/[gentoo-projects]/portage-utils/qglsa.c
Gentoo

Contents of /portage-utils/qglsa.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.14 - (show annotations) (download) (as text)
Sun Oct 28 04:16:19 2012 UTC (2 years, 1 month ago) by vapier
Branch: MAIN
Changes since 1.13: +3 -3 lines
File MIME type: text/x-csrc
kill off more spurious/useless parens

1 /*
2 * Copyright 2005-2010 Gentoo Foundation
3 * Distributed under the terms of the GNU General Public License v2
4 * $Header: /var/cvsroot/gentoo-projects/portage-utils/qglsa.c,v 1.13 2011/02/21 01:33:47 vapier Exp $
5 *
6 * Copyright 2005-2010 Ned Ludd - <solar@gentoo.org>
7 * Copyright 2005-2010 Mike Frysinger - <vapier@gentoo.org>
8 */
9
10 #ifdef APPLET_qglsa
11
12 #define QGLSA_DB "/var/cache/edb/glsa"
13
14 #define QGLSA_FLAGS "ldtpfi" COMMON_FLAGS
15 static struct option const qglsa_long_opts[] = {
16 {"list", no_argument, NULL, 'l'},
17 {"dump", no_argument, NULL, 'd'},
18 {"test", no_argument, NULL, 't'},
19 {"pretend", no_argument, NULL, 'p'},
20 {"fix", no_argument, NULL, 'f'},
21 {"inject", no_argument, NULL, 'i'},
22 COMMON_LONG_OPTS
23 };
24 static const char * const qglsa_opts_help[] = {
25 "List GLSAs",
26 "Dump info about GLSAs",
27 "Test if system is affected by GLSAs",
28 "Do everything but actually emerge the package",
29 "Auto-apply GLSAs to the system",
30 "Mark specified GLSAs as fixed",
31 COMMON_OPTS_HELP
32 };
33 static const char qglsa_rcsid[] = "$Id: qglsa.c,v 1.13 2011/02/21 01:33:47 vapier Exp $";
34 #define qglsa_usage(ret) usage(ret, QGLSA_FLAGS, qglsa_long_opts, qglsa_opts_help, lookup_applet_idx("qglsa"))
35
36 static char *qglsa_load_list(void);
37 static char *qglsa_load_list(void)
38 {
39 char *ret;
40 struct stat st;
41
42 if (stat(QGLSA_DB, &st))
43 return NULL;
44
45 ret = xmalloc(st.st_size+1);
46
47 if (!eat_file(QGLSA_DB, ret, st.st_size)) {
48 free(ret);
49 return NULL;
50 }
51
52 return ret;
53 }
54 static void qglsa_append_to_list(const char *glsa);
55 static void qglsa_append_to_list(const char *glsa)
56 {
57 FILE *f;
58 if ((f = fopen(QGLSA_DB, "a")) != NULL) {
59 fprintf(f, "%s\n", glsa);
60 fclose(f);
61 }
62 }
63
64 static void qglsa_decode_entities(char *xml_buf, size_t len);
65 static void qglsa_decode_entities(char *xml_buf, size_t len)
66 {
67 const char const *encoded[] = { "&lt;", "&gt;", "&quot;", "&amp;"};
68 const char const *decoded[] = { "<", ">", "\"", "&"};
69 int i;
70 char *p, *q;
71
72 /* most things dont have entities so let's just bail real quick */
73 if (strchr(xml_buf, '&') == NULL)
74 return;
75
76 for (i=0; i < ARRAY_SIZE(encoded); ++i) {
77 /* for now, we assume that strlen(decoded) is always 1 ... if
78 * this changes, we have to update the 'p++' accordingly */
79 while ((p = strstr(xml_buf, encoded[i])) != NULL) {
80 strcpy(p, decoded[i]);
81 q = p++ + strlen(encoded[i]);
82 memmove(p, q, len-(q-xml_buf)+1);
83 }
84 }
85 }
86
87 static char *qglsa_get_xml_tag_attribute(const char *xml_buf, const char *tag, const char *attribute)
88 {
89 static char tmp_buf[BUFSIZE];
90 char *start, *end, *start_attr, *end_attr;
91
92 /* find the start of this tag */
93 sprintf(tmp_buf, "<%s ", tag);
94 if ((start = strstr(xml_buf, tmp_buf)) == NULL)
95 return NULL;
96
97 /* find the end of this tag */
98 start += strlen(tmp_buf) - 1;
99 if ((end = strchr(start, '>')) == NULL)
100 return NULL;
101
102 /* find the attribute in this tag */
103 sprintf(tmp_buf, " %s=", attribute);
104 if ((start_attr = strstr(start, tmp_buf)) == NULL)
105 return NULL;
106
107 /* get the value */
108 start_attr += strlen(tmp_buf);
109 if (*start_attr == '"') {
110 end_attr = strchr(++start_attr, '"');
111 } else {
112 end_attr = strchr(start_attr, ' ');
113 }
114 assert(end_attr - start_attr < sizeof(tmp_buf));
115 memcpy(tmp_buf, start_attr, end_attr-start_attr);
116 tmp_buf[end_attr-start_attr] = '\0';
117
118 qglsa_decode_entities(tmp_buf, end-start);
119 return tmp_buf;
120 }
121 static char *qglsa_get_xml_tag(const char *xml_buf, const char *tag)
122 {
123 static char tmp_buf[BUFSIZE];
124 char *start, *end;
125
126 sprintf(tmp_buf, "<%s>", tag);
127 if ((start = strstr(xml_buf, tmp_buf)) == NULL) {
128 sprintf(tmp_buf, "<%s ", tag);
129 if ((start = strstr(xml_buf, tmp_buf)) == NULL)
130 return NULL;
131 }
132 start += strlen(tmp_buf);
133 sprintf(tmp_buf, "</%s>", tag);
134 if ((end = strstr(start, tmp_buf)) == NULL)
135 return NULL;
136 assert(end - start < sizeof(tmp_buf));
137 memcpy(tmp_buf, start, end - start);
138 tmp_buf[end - start] = '\0';
139
140 qglsa_decode_entities(tmp_buf, end-start);
141 return tmp_buf;
142 }
143
144 /*
145 static const char * const qglsa_opts_glsa[] = {
146 "le", "lt", "eq", "gt", "ge", "rge", "rle", "rgt", "rlt", NULL
147 };
148 static const char * const qglsa_opts_portage[] = {
149 "<=", "<", "=", ">", ">=", ">=~", "<=~", " >~", " <~", NULL
150 };
151
152 static void qglsa_act_list(char *glsa)
153 {
154
155 }
156 */
157 int qglsa_main(int argc, char **argv)
158 {
159 enum { GLSA_FUNKYTOWN, GLSA_LIST, GLSA_DUMP, GLSA_TEST, GLSA_FIX, GLSA_INJECT };
160 int i;
161 DIR *dir;
162 struct dirent *dentry;
163 struct stat st;
164 char buf[BUFSIZE*4];
165 char *s, *p, *glsa_fixed_list;
166 int action = GLSA_FUNKYTOWN;
167 int all_glsas = 0;
168
169 DBG("argc=%d argv[0]=%s argv[1]=%s",
170 argc, argv[0], argc > 1 ? argv[1] : "NULL?");
171
172 while ((i = GETOPT_LONG(QGLSA, qglsa, "")) != -1) {
173 #define set_action(a) { if (action == 0) action = a; else err("cannot specify more than one action at a time"); }
174 switch (i) {
175 case 'l': set_action(GLSA_LIST); break;
176 case 'd': set_action(GLSA_DUMP); break;
177 case 't': set_action(GLSA_TEST); break;
178 case 'p': pretend = 1; break;
179 case 'f': set_action(GLSA_FIX); break;
180 case 'i': set_action(GLSA_INJECT); break;
181 COMMON_GETOPTS_CASES(qglsa)
182 }
183 }
184 if (action == GLSA_FUNKYTOWN)
185 qglsa_usage(EXIT_FAILURE);
186 if (action != GLSA_LIST && optind == argc)
187 err("specified action requires a list, either 'all', 'new', or GLSA numbers");
188
189 glsa_fixed_list = NULL;
190 for (i = optind; i < argc; ++i) {
191 if (!strcmp(argv[i], "all")) {
192 all_glsas = 1;
193 if (optind+1 != argc)
194 err("You may only use class names by themselves");
195 } else if (!strcmp(argv[i], "new")) {
196 all_glsas = 0;
197 if (optind+1 != argc)
198 err("You may only use class names by themselves");
199 }
200 }
201 glsa_fixed_list = qglsa_load_list();
202
203 xchdir(portdir);
204 xchdir("./metadata/glsa");
205
206 switch (action) {
207 /*case GLSA_FIX:*/
208 case GLSA_INJECT:
209 for (i = optind; i < argc; ++i) {
210 snprintf(buf, sizeof(buf), "glsa-%s.xml", argv[i]);
211 if (stat(buf, &st)) {
212 warn("Skipping invalid GLSA '%s'", argv[i]);
213 continue;
214 }
215 if (glsa_fixed_list) {
216 if (strstr(glsa_fixed_list, argv[i])) {
217 warn("Skipping already installed GLSA %s", argv[i]);
218 continue;
219 }
220 }
221 if (action == GLSA_FIX) {
222 printf("Fixing GLSA %s%s%s\n", GREEN, argv[i], NORM);
223 continue;
224 } else if (action == GLSA_INJECT)
225 printf("Injecting GLSA %s%s%s\n", GREEN, argv[i], NORM);
226 qglsa_append_to_list(argv[i]);
227 }
228 break;
229
230 default:
231 if ((dir = opendir(".")) == NULL)
232 return EXIT_FAILURE;
233
234 while ((dentry = readdir(dir)) != NULL) {
235 /* validate this file as a proper glsa */
236 char glsa_id[20];
237 if (strncmp(dentry->d_name, "glsa-", 5))
238 continue;
239 strcpy(glsa_id, dentry->d_name + 5);
240 if ((s = strchr(glsa_id, '.')) == NULL || memcmp(s, ".xml\0", 5))
241 continue;
242 *s = '\0';
243
244 /* see if we want to skip glsa's already fixed */
245 if (!all_glsas && glsa_fixed_list) {
246 if (strstr(glsa_fixed_list, glsa_id))
247 continue;
248 }
249
250 /* load the glsa into memory */
251 if (eat_file(dentry->d_name, buf, sizeof(buf)) == 0)
252 errp("could not eat %s", dentry->d_name);
253
254 /* now lets figure out what to do with this memory */
255 switch (action) {
256 case GLSA_LIST:
257 s = qglsa_get_xml_tag(buf, "title");
258 printf("%s%s%s: %s", GREEN, glsa_id, NORM, s);
259 if (verbose) {
260 int num_shown = 0;
261 p = qglsa_get_xml_tag(buf, "affected");
262 if (p) {
263 printf(" (");
264 while (p++) {
265 s = qglsa_get_xml_tag_attribute(p, "package", "name");
266 if (s) {
267 if (verbose < 2 && ++num_shown > 3) {
268 printf(" ...");
269 break;
270 }
271 printf(" %s", s);
272 } else
273 break;
274 p = strstr(p, "</package>");
275 }
276 printf(" )");
277 }
278 }
279 printf("\n");
280 break;
281 case GLSA_DUMP:
282 s = qglsa_get_xml_tag(buf, "title");
283 printf("%s%s%s: %s\n", GREEN, glsa_id, NORM, s);
284 s = qglsa_get_xml_tag(buf, "bug");
285 printf(" %sRef%s: http://bugs.gentoo.org/%s\n", BLUE, NORM, s);
286 s = qglsa_get_xml_tag(buf, "access");
287 printf(" %saccess%s: %s\n", BLUE, NORM, s);
288 s = qglsa_get_xml_tag(buf, "synopsis");
289 printf(" %ssynopsis%s:\n%s\n", BLUE, NORM, s);
290 s = qglsa_get_xml_tag(buf, "affected");
291 printf(" %saffected%s:\n%s\n", BLUE, NORM, s);
292 if (verbose) {
293 s = qglsa_get_xml_tag(buf, "description");
294 printf(" %sdescription%s:\n%s\n", BLUE, NORM, s);
295 s = qglsa_get_xml_tag(buf, "workaround");
296 printf(" %sworkaround%s:\n%s\n", BLUE, NORM, s);
297 }
298 break;
299 }
300 }
301 closedir(dir);
302 }
303
304 free(glsa_fixed_list);
305
306 return EXIT_SUCCESS;
307 }
308
309 #else
310 DEFINE_APPLET_STUB(qglsa)
311 #endif

  ViewVC Help
Powered by ViewVC 1.1.20