blob: 24b972db0c1aa46811b03bd2eddaa9fe59a18a1e [file] [log] [blame]
Uwe Hermann7eb845e2008-11-02 17:01:06 +00001/*
2 * This file is part of the bayou project.
3 *
4 * Copyright (C) 2008 Advanced Micro Devices, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
Paul Menzela46a7122013-02-23 18:37:27 +010017 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Uwe Hermann7eb845e2008-11-02 17:01:06 +000018 */
19
20#include <stdlib.h>
21#include <string.h>
22#include <unistd.h>
23#include <fcntl.h>
24#include <libgen.h>
25#include "liblar.h"
26#include "pbuilder.h"
27
28void do_lzma_compress(char *in, int in_len, char *out, int *out_len);
29
30int add_bpt_to_lar(struct LAR *lar, struct config *config)
31{
32 char *buffer;
33 int ret, i, len = sizeof(struct bpt_config);
34 struct bpt_config *cfg;
35 struct LARAttr attr;
36 char *ptr;
37
38 for (i = 0; i < config->n_entries; i++) {
39 len += sizeof(struct bpt_pentry);
40
41 if (config->entries[i]->type != BPT_TYPE_CHAIN)
42 len += ((strlen(config->entries[i]->larname)
43 + 15) & ~0x0F);
44 }
45
46 buffer = calloc(len, 1);
47
48 if (buffer == NULL)
49 return -1;
50
51 cfg = (struct bpt_config *)buffer;
52
53 cfg->id = BPT_ID;
54 cfg->timeout = config->timeout;
55 cfg->entries = config->n_entries;
56
57 ptr = buffer + sizeof(struct bpt_config);
58
59 for (i = 0; i < config->n_entries; i++) {
60 int nlen = 0;
61 struct bpt_pentry *pentry = (struct bpt_pentry *)ptr;
62
63 pentry->index = config->entries[i]->index;
64 pentry->parent = config->entries[i]->parent;
65 pentry->type = config->entries[i]->type;
66 pentry->flags = config->entries[i]->flags;
67
68 strncpy((char *)pentry->title,
69 (char *)config->entries[i]->title,
70 sizeof(pentry->title));
71
72 if (config->entries[i]->type != BPT_TYPE_CHAIN) {
73 nlen = strlen(config->entries[i]->larname);
74 nlen = (nlen + 15) & ~0x0F;
75
76 strcpy((char *)(ptr + sizeof(struct bpt_pentry)),
77 config->entries[i]->larname);
78
79 pentry->nlen = nlen;
80 }
81
82 ptr += sizeof(struct bpt_pentry);
83
84 if (config->entries[i]->type != BPT_TYPE_CHAIN)
85 ptr += nlen;
86 }
87
88 LAR_SetAttrs(&attr, "bayou_payload_table", ALGO_NONE);
89
90 ret = LAR_AppendBuffer(lar, (unsigned char *)buffer, len, &attr);
91 free(buffer);
92 return ret;
93}
94
95struct lfile {
96 char *file;
97 char *larname;
98};
99
100int n_lfiles;
101
102int create_lar_from_config(const char *input, const char *output)
103{
104 struct config config;
105 FILE *stream;
106 struct LAR *lar;
107 struct LARAttr attr;
108 int i, j, ret = -1;
109 struct lfile *lfiles;
110
111 stream = fopen(input, "r");
112
113 if (stream == NULL) {
114 warn("E: Couldn't open %s for reading\n", input);
115 return -1;
116 }
117
118 memset(&config, 0, sizeof(config));
119
120 parseconfig(stream, &config);
121 fclose(stream);
122
123 lar = LAR_Create(output);
124
125 if (lar == NULL) {
126 warn("E: Couldn't create a new lar file\n");
127 return -1;
128 }
129
130 LAR_SetCompressionFuncs(lar, ALGO_LZMA, do_lzma_compress, NULL);
131
132 lfiles = calloc(sizeof(struct lfile), config.n_entries);
133
134 if (lfiles == NULL) {
135 warn("E: Couldn't allocate memory: %m\n");
136 return -1;
137 }
138
139 for (i = 0; i < config.n_entries; i++) {
140 /* Master chain entries don't have files associated with them. */
141 if (config.entries[i]->type == BPT_TYPE_CHAIN)
142 continue;
143
144 if (access(config.entries[i]->file, R_OK)) {
145 warn("E: Could not find file %s\n",
146 config.entries[i]->file);
147
148 goto err;
149 }
150
151 if (config.entries[i]->larname == NULL) {
152 config.entries[i]->larname =
153 strdup(basename(config.entries[i]->file));
154
155 if (config.entries[i]->larname == NULL) {
156 warn("E: Could not allocate memory for the default name\n");
157 goto err;
158 }
159 }
160
161 /*
162 * Add the file to the list of files to add to the LAR - skip
163 * any duplicates, but be on the lookout for the same LAR name
164 * attached to a different file.
165 */
166 for (j = 0; j < n_lfiles; j++) {
167 if (!strcmp(lfiles[j].larname,
168 config.entries[i]->larname)) {
169 if (strcmp(lfiles[j].file,
170 config.entries[i]->file)) {
171 warn("E: LAR name '%s' has already been used\n", config.entries[i]->larname);
172 goto err;
173 }
174 break;
175 }
176 }
177
178 if (j == n_lfiles) {
179 lfiles[n_lfiles].file = config.entries[i]->file;
180 lfiles[n_lfiles++].larname = config.entries[i]->larname;
181 }
182 }
183
184 /* Add all the files to the LAR. */
185 for (i = 0; i < n_lfiles; i++) {
186 LAR_SetAttrs(&attr, lfiles[i].larname, ALGO_LZMA);
187
188 if (LAR_AppendFile(lar, lfiles[i].file, &attr)) {
189 warn("E: Could not add %s to the LAR\n",
190 lfiles[i].file);
191 goto err;
192 }
193 }
194
195 ret = add_bpt_to_lar(lar, &config);
196
197err:
198 LAR_Close(lar);
199 return ret;
200}