rpm 5.2.1

- Main Page
- Related Pages
- Modules
- Data Structures
- Files

- File List
- Globals

parsePrep.c
Go to the documentation of this file.
1
6 #include "system.h"
7
8 #include <rpmio.h>
9 #include <rpmiotypes.h>
10 #include <argv.h>
11 #include <rpmcb.h>
12 #include <rpmurl.h>
13 #ifdef NOTYET
14 #include <rpmmg.h>
15 #endif
16
17 #include <rpmbuild.h>
18
19 #include "misc.h" /* XXX rpmMkdirPath */
20 #include "debug.h"
21
22 /* These have to be global to make up for stupid compilers */
23 /*@unchecked@*/
24 static int leaveDirs, skipDefaultAction;
25 /*@unchecked@*/
26 static int createDir, quietly;
27 /*@unchecked@*/ /*@observer@*/ /*@null@*/
28 static const char * dirName = NULL;
29 /*@unchecked@*/ /*@observer@*/
30 static struct poptOption optionsTable[] = {
31 { NULL, 'a', POPT_ARG_STRING, NULL, 'a', NULL, NULL},
32 { NULL, 'b', POPT_ARG_STRING, NULL, 'b', NULL, NULL},
33 { NULL, 'c', 0, &createDir, 0, NULL, NULL},
34 { NULL, 'D', 0, &leaveDirs, 0, NULL, NULL},
35 { NULL, 'n', POPT_ARG_STRING, &dirName, 0, NULL, NULL},
36 { NULL, 'T', 0, &skipDefaultAction, 0, NULL, NULL},
37 { NULL, 'q', 0, &quietly, 0, NULL, NULL},
38 { 0, 0, 0, 0, 0, NULL, NULL}
39 };
40
46 static rpmRC checkOwners(const char * urlfn)
47 /*@globals h_errno, fileSystem, internalState @*/
48 /*@modifies fileSystem, internalState @*/
49 {
50 struct stat sb;
51
52 if (Lstat(urlfn, &sb)) {
53 rpmlog(RPMLOG_ERR, _("Bad source: %s: %s\n"),
54 urlfn, strerror(errno));
55 return RPMRC_FAIL;
56 }
57 if (!getUname(sb.st_uid) || !getGname(sb.st_gid)) {
58 rpmlog(RPMLOG_ERR, _("Bad owner/group: %s\n"), urlfn);
59 return RPMRC_FAIL;
60 }
61
62 return RPMRC_OK;
63 }
64
65 #ifndef DYING
66
78 /*@observer@*/
79 static char *doPatch(Spec spec, rpmuint32_t c, int strip, const char *db,
80 int reverse, int removeEmpties, int fuzz, const char *subdir)
81 /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
82 /*@modifies rpmGlobalMacroContext, fileSystem, internalState @*/
83 {
84 const char *fn, *Lurlfn;
85 static char buf[BUFSIZ];
86 char args[BUFSIZ], *t = args;
87 struct Source *sp;
88 rpmCompressedMagic compressed = COMPRESSED_NOT;
89 int urltype;
90 const char *patch, *flags;
91
92 *t = '\0';
93 if (db)
94 t = stpcpy( stpcpy(t, "-b --suffix "), db);
95 #if defined(RPM_VENDOR_OPENPKG) /* always-backup-on-patching */
96 /* always create backup files in OpenPKG */
97 else
98 t = stpcpy(t, "-b --suffix .orig ");
99 #endif
100 if (subdir)
101 t = stpcpy( stpcpy(t, "-d "), subdir);
102 if (fuzz >= 0) {
103 t = stpcpy(t, "-F ");
104 sprintf(t, "%10.10d", fuzz);
105 t += strlen(t);
106 }
107 if (reverse)
108 t = stpcpy(t, " -R");
109 if (removeEmpties)
110 t = stpcpy(t, " -E");
111
112 for (sp = spec->sources; sp != NULL; sp = sp->next) {
113 if ((sp->flags & RPMFILE_PATCH) && (sp->num == c))
114 break;
115 }
116 if (sp == NULL) {
117 rpmlog(RPMLOG_ERR, _("No patch number %d\n"), c);
118 return NULL;
119 }
120
121 Lurlfn = rpmGenPath(NULL, "%{_patchdir}/", sp->source);
122
123 /* XXX On non-build parse's, file cannot be stat'd or read */
124 if (!spec->force && (isCompressed(Lurlfn, &compressed) || checkOwners(Lurlfn))) {
125 Lurlfn = _free(Lurlfn);
126 return NULL;
127 }
128
129 fn = NULL;
130 urltype = urlPath(Lurlfn, &fn);
131 switch (urltype) {
132 case URL_IS_HTTPS: /* XXX WRONG WRONG WRONG */
133 case URL_IS_HTTP: /* XXX WRONG WRONG WRONG */
134 case URL_IS_FTP: /* XXX WRONG WRONG WRONG */
135 case URL_IS_HKP: /* XXX WRONG WRONG WRONG */
136 case URL_IS_PATH:
137 case URL_IS_UNKNOWN:
138 break;
139 case URL_IS_DASH:
140 Lurlfn = _free(Lurlfn);
141 return NULL;
142 /*@notreached@*/ break;
143 }
144
145 patch = rpmGetPath("%{__patch}", NULL);
146 if (strcmp(patch, "%{__patch}") == 0)
147 patch = xstrdup("patch");
148
149 flags = rpmExpand("%{?_default_patch_flags}%{!?_default_patch_flags:-s}", NULL);
150
151 if (compressed) {
152 const char *zipper;
153
154 switch (compressed) {
155 default:
156 case COMPRESSED_NOT: /* XXX can't happen */
157 case COMPRESSED_OTHER:
158 case COMPRESSED_ZIP: /* XXX wrong */
159 zipper = "%{__gzip}";
160 break;
161 case COMPRESSED_BZIP2:
162 zipper = "%{__bzip2}";
163 break;
164 case COMPRESSED_LZOP:
165 zipper = "%{__lzop}";
166 break;
167 case COMPRESSED_LZMA:
168 zipper = "%{__lzma}";
169 break;
170 case COMPRESSED_XZ:
171 zipper = "%{__xz}";
172 break;
173 }
174 zipper = rpmGetPath(zipper, NULL);
175
176 sprintf(buf,
177 "echo \"Patch #%d (%s):\"\n"
178 "%s -d < '%s' | %s -p%d %s %s\n"
179 "STATUS=$?\n"
180 "if [ $STATUS -ne 0 ]; then\n"
181 " exit $STATUS\n"
182 "fi",
183 c,
184 /*@-moduncon@*/
185 (const char *) basename((char *)fn),
186 /*@=moduncon@*/
187 zipper,
188 fn, patch, strip, args, flags);
189 zipper = _free(zipper);
190 } else {
191 sprintf(buf,
192 "echo \"Patch #%d (%s):\"\n"
193 "%s -p%d %s %s < '%s'", c,
194 /*@-moduncon@*/
195 (const char *) basename((char *)fn),
196 /*@=moduncon@*/
197 patch, strip, args, flags, fn);
198 }
199
200 patch = _free(patch);
201 flags = _free(flags);
202 Lurlfn = _free(Lurlfn);
203 return buf;
204 }
205 #endif
206
214 /*@observer@*/
215 static const char *doUntar(Spec spec, rpmuint32_t c, int quietly)
216 /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
217 /*@modifies rpmGlobalMacroContext, fileSystem, internalState @*/
218 {
219 const char *fn, *Lurlfn;
220 static char buf[BUFSIZ];
221 char *taropts;
222 char *t = NULL;
223 struct Source *sp;
224 rpmCompressedMagic compressed = COMPRESSED_NOT;
225 int urltype;
226 const char *tar;
227
228 for (sp = spec->sources; sp != NULL; sp = sp->next) {
229 if ((sp->flags & RPMFILE_SOURCE) && (sp->num == c)) {
230 break;
231 }
232 }
233 if (sp == NULL) {
234 rpmlog(RPMLOG_ERR, _("No source number %d\n"), c);
235 return NULL;
236 }
237
238 /*@-internalglobs@*/ /* FIX: shrug */
239 taropts = ((rpmIsVerbose() && !quietly) ? "-xvvf" : "-xf");
240 /*@=internalglobs@*/
241
242 #if defined(RPM_VENDOR_OPENPKG) /* splitted-source-directory */
243 Lurlfn = rpmGenPath(NULL, getSourceDir(sp->flags, sp->source), sp->source);
244 #else
245 Lurlfn = rpmGenPath(NULL, getSourceDir(sp->flags), sp->source);
246 #endif
247
248 /* XXX On non-build parse's, file cannot be stat'd or read */
249 if (!spec->force && (isCompressed(Lurlfn, &compressed) || checkOwners(Lurlfn))) {
250 Lurlfn = _free(Lurlfn);
251 return NULL;
252 }
253
254 fn = NULL;
255 urltype = urlPath(Lurlfn, &fn);
256 switch (urltype) {
257 case URL_IS_HTTPS: /* XXX WRONG WRONG WRONG */
258 case URL_IS_HTTP: /* XXX WRONG WRONG WRONG */
259 case URL_IS_FTP: /* XXX WRONG WRONG WRONG */
260 case URL_IS_HKP: /* XXX WRONG WRONG WRONG */
261 case URL_IS_PATH:
262 case URL_IS_UNKNOWN:
263 break;
264 case URL_IS_DASH:
265 Lurlfn = _free(Lurlfn);
266 return NULL;
267 /*@notreached@*/ break;
268 }
269 #ifdef NOTYET
270 { rpmmg mg;
271
272 _rpmmg_debug = 1;
273 mg = rpmmgNew(NULL, 0);
274 t = (char *) rpmmgFile(mg, fn);
275 mg = rpmmgFree(mg);
276 fprintf(stderr, "==> %s: %s\n", fn, t);
277 t = _free(t);
278 _rpmmg_debug = 0;
279 }
280 #endif
281
282 tar = rpmGetPath("%{__tar}", NULL);
283 if (strcmp(tar, "%{__tar}") == 0)
284 tar = xstrdup("tar");
285
286 #if defined(RPM_VENDOR_ARK) /* use-gnu-tar-compression-detection */
287 /* We leave compression handling for all tar based files up to GNU tar */
288 if (compressed == COMPRESSED_ZIP)
289 #else
290 if (compressed != COMPRESSED_NOT)
291 #endif
292 {
293 const char *zipper;
294 int needtar = 1;
295
296 switch (compressed) {
297 case COMPRESSED_NOT: /* XXX can't happen */
298 case COMPRESSED_OTHER:
299 t = "%{__gzip} -dc";
300 break;
301 case COMPRESSED_BZIP2:
302 t = "%{__bzip2} -dc";
303 break;
304 case COMPRESSED_LZOP:
305 t = "%{__lzop} -dc";
306 break;
307 case COMPRESSED_LZMA:
308 t = "%{__lzma} -dc";
309 break;
310 case COMPRESSED_XZ:
311 t = "%{__xz} -dc";
312 break;
313 case COMPRESSED_ZIP:
314 #if defined(RPM_VENDOR_OPENPKG) /* use-bsdtar-for-zip-files */
315 t = "%{__bsdtar} -x -f";
316 #else
317 if (rpmIsVerbose() && !quietly)
318 t = "%{__unzip}";
319 else
320 t = "%{__unzip} -qq";
321 #endif
322 needtar = 0;
323 break;
324 }
325 zipper = rpmGetPath(t, NULL);
326 buf[0] = '\0';
327 t = stpcpy(buf, zipper);
328 zipper = _free(zipper);
329 *t++ = ' ';
330 *t++ = '\'';
331 t = stpcpy(t, fn);
332 *t++ = '\'';
333 if (needtar) {
334 t = stpcpy(t, " | ");
335 t = stpcpy(t, tar);
336 t = stpcpy(t, " ");
337 t = stpcpy(t, taropts);
338 t = stpcpy(t, " -");
339 }
340 t = stpcpy(t,
341 "\n"
342 "STATUS=$?\n"
343 "if [ $STATUS -ne 0 ]; then\n"
344 " exit $STATUS\n"
345 "fi");
346 } else {
347 buf[0] = '\0';
348 t = stpcpy(buf, tar);
349 t = stpcpy(t, " ");
350 t = stpcpy(t, taropts);
351 *t++ = ' ';
352 t = stpcpy(t, fn);
353 }
354
355 tar = _free(tar);
356 Lurlfn = _free(Lurlfn);
357 return buf;
358 }
359
367 static int doSetupMacro(Spec spec, const char * line)
368 /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
369 /*@modifies spec->buildSubdir, spec->macros, spec->prep,
370 spec->packages->header,
371 rpmGlobalMacroContext, fileSystem, internalState @*/
372 {
373 char buf[BUFSIZ];
374 rpmiob before;
375 rpmiob after;
376 poptContext optCon;
377 int argc;
378 const char ** argv;
379 int arg;
380 const char * optArg;
381 int rc;
382 rpmuint32_t num;
383
384 /*@-mods@*/
385 leaveDirs = skipDefaultAction = 0;
386 createDir = quietly = 0;
387 dirName = NULL;
388 /*@=mods@*/
389
390 if ((rc = poptParseArgvString(line, &argc, &argv))) {
391 rpmlog(RPMLOG_ERR, _("Error parsing %%setup: %s\n"),
392 poptStrerror(rc));
393 return RPMRC_FAIL;
394 }
395
396 before = rpmiobNew(0);
397 after = rpmiobNew(0);
398
399 optCon = poptGetContext(NULL, argc, argv, optionsTable, 0);
400 while ((arg = poptGetNextOpt(optCon)) > 0) {
401 optArg = poptGetOptArg(optCon);
402
403 /* We only parse -a and -b here */
404
405 if (parseNum(optArg, &num)) {
406 rpmlog(RPMLOG_ERR, _("line %d: Bad arg to %%setup: %s\n"),
407 spec->lineNum, (optArg ? optArg : "???"));
408 before = rpmiobFree(before);
409 after = rpmiobFree(after);
410 optCon = poptFreeContext(optCon);
411 argv = _free(argv);
412 return RPMRC_FAIL;
413 }
414
415 { const char *chptr = doUntar(spec, num, quietly);
416 if (chptr == NULL)
417 return RPMRC_FAIL;
418
419 (void) rpmiobAppend((arg == 'a' ? after : before), chptr, 1);
420 }
421 }
422
423 if (arg < -1) {
424 rpmlog(RPMLOG_ERR, _("line %d: Bad %%setup option %s: %s\n"),
425 spec->lineNum,
426 poptBadOption(optCon, POPT_BADOPTION_NOALIAS),
427 poptStrerror(arg));
428 before = rpmiobFree(before);
429 after = rpmiobFree(after);
430 optCon = poptFreeContext(optCon);
431 argv = _free(argv);
432 return RPMRC_FAIL;
433 }
434
435 if (dirName) {
436 spec->buildSubdir = xstrdup(dirName);
437 } else {
438 const char *N, *V;
439 (void) headerNEVRA(spec->packages->header, &N, NULL, &V, NULL, NULL);
440 (void) snprintf(buf, sizeof(buf), "%s-%s", N, V);
441 buf[sizeof(buf)-1] = '\0';
442 N = _free(N);
443 V = _free(V);
444 spec->buildSubdir = xstrdup(buf);
445 }
446 addMacro(spec->macros, "buildsubdir", NULL, spec->buildSubdir, RMIL_SPEC);
447
448 optCon = poptFreeContext(optCon);
449 argv = _free(argv);
450
451 /* cd to the build dir */
452 { const char * buildDirURL = rpmGenPath(spec->rootURL, "%{_builddir}", "");
453 const char *buildDir;
454
455 (void) urlPath(buildDirURL, &buildDir);
456 rc = rpmioMkpath(buildDir, 0755, -1, -1);
457 sprintf(buf, "cd '%s'", buildDir);
458 spec->prep = rpmiobAppend(spec->prep, buf, 1);
459 buildDirURL = _free(buildDirURL);
460 }
461
462 /* delete any old sources */
463 if (!leaveDirs) {
464 sprintf(buf, "rm -rf '%s'", spec->buildSubdir);
465 spec->prep = rpmiobAppend(spec->prep, buf, 1);
466 }
467
468 /* if necessary, create and cd into the proper dir */
469 if (createDir) {
470 char *mkdir_p;
471 mkdir_p = rpmExpand("%{?__mkdir_p}%{!?__mkdir_p:mkdir -p}", NULL);
472 if (!mkdir_p)
473 mkdir_p = xstrdup("mkdir -p");
474 sprintf(buf, "%s '%s'\ncd '%s'",
475 mkdir_p, spec->buildSubdir, spec->buildSubdir);
476 mkdir_p = _free(mkdir_p);
477 spec->prep = rpmiobAppend(spec->prep, buf, 1);
478 }
479
480 /* do the default action */
481 if (!createDir && !skipDefaultAction) {
482 const char *chptr = doUntar(spec, 0, quietly);
483 if (!chptr)
484 return RPMRC_FAIL;
485 spec->prep = rpmiobAppend(spec->prep, chptr, 1);
486 }
487
488 spec->prep = rpmiobAppend(spec->prep, rpmiobStr(before), 0);
489 before = rpmiobFree(before);
490
491 if (!createDir) {
492 sprintf(buf, "cd '%s'", spec->buildSubdir);
493 spec->prep = rpmiobAppend(spec->prep, buf, 1);
494 }
495
496 if (createDir && !skipDefaultAction) {
497 const char * chptr = doUntar(spec, 0, quietly);
498 if (chptr == NULL)
499 return RPMRC_FAIL;
500 spec->prep = rpmiobAppend(spec->prep, chptr, 1);
501 }
502
503 spec->prep = rpmiobAppend(spec->prep, rpmiobStr(after), 0);
504 after = rpmiobFree(after);
505
506 /* XXX FIXME: owner & group fixes were conditioned on !geteuid() */
507 /* Fix the owner, group, and permissions of the setup build tree */
508 { /*@observer@*/ static const char *fixmacs[] =
509 { "%{_fixowner}", "%{_fixgroup}", "%{_fixperms}", NULL };
510 const char ** fm;
511
512 for (fm = fixmacs; *fm; fm++) {
513 const char *fix;
514 fix = rpmExpand(*fm, " .", NULL);
515 if (fix && *fix != '%')
516 spec->prep = rpmiobAppend(spec->prep, fix, 1);
517 fix = _free(fix);
518 }
519 }
520
521 return 0;
522 }
523
524 #ifndef DYING
525
531 static rpmRC doPatchMacro(Spec spec, const char * line)
532 /*@globals rpmGlobalMacroContext, h_errno,
533 fileSystem, internalState @*/
534 /*@modifies spec->prep, rpmGlobalMacroContext,
535 fileSystem, internalState @*/
536 {
537 char *s;
538 char *opt_b;
539 char *opt_d;
540 rpmuint32_t opt_P, opt_p, opt_R, opt_E, opt_F;
541 char buf[BUFSIZ], *bp;
542 rpmuint32_t patch_nums[1024]; /* XXX - we can only handle 1024 patches! */
543 int patch_index, x;
544
545 memset(patch_nums, 0, sizeof(patch_nums));
546 opt_P = opt_p = opt_R = opt_E = 0;
547 opt_F = rpmExpandNumeric("%{?_default_patch_fuzz}%{!?_default_patch_fuzz:-1}");
548 opt_b = NULL;
549 opt_d = NULL;
550 patch_index = 0;
551
552 if (! strchr(" \t\n", line[6])) {
553 /* %patchN */
554 sprintf(buf, "%%patch -P %s", line + 6);
555 } else {
556 strcpy(buf, line);
557 }
558
559 /*@-internalglobs@*/ /* FIX: strtok has state */
560 for (bp = buf; (s = strtok(bp, " \t\n")) != NULL;) {
561 if (bp) { /* remove 1st token (%patch) */
562 bp = NULL;
563 continue;
564 }
565 if (!strcmp(s, "-P")) {
566 opt_P = 1;
567 } else if (!strcmp(s, "-R")) {
568 opt_R = 1;
569 } else if (!strcmp(s, "-E")) {
570 opt_E = 1;
571 } else if (!strcmp(s, "-b")) {
572 /* orig suffix */
573 opt_b = strtok(NULL, " \t\n");
574 if (! opt_b) {
575 rpmlog(RPMLOG_ERR,
576 _("line %d: Need arg to %%patch -b: %s\n"),
577 spec->lineNum, spec->line);
578 return RPMRC_FAIL;
579 }
580 } else if (!strcmp(s, "-z")) {
581 /* orig suffix */
582 opt_b = strtok(NULL, " \t\n");
583 if (! opt_b) {
584 rpmlog(RPMLOG_ERR,
585 _("line %d: Need arg to %%patch -z: %s\n"),
586 spec->lineNum, spec->line);
587 return RPMRC_FAIL;
588 }
589 } else if (!strcmp(s, "-F")) {
590 /* fuzz factor */
591 const char * fnum = (!strchr(" \t\n", s[2])
592 ? s+2 : strtok(NULL, " \t\n"));
593 char * end = NULL;
594
595 opt_F = (fnum ? strtol(fnum, &end, 10) : 0);
596 if (! opt_F || *end) {
597 rpmlog(RPMLOG_ERR,
598 _("line %d: Bad arg to %%patch -F: %s\n"),
599 spec->lineNum, spec->line);
600 return RPMRC_FAIL;
601 }
602 } else if (!strcmp(s, "-d")) {
603 /* subdirectory */
604 opt_d = strtok(NULL, " \t\n");
605 if (! opt_d) {
606 rpmlog(RPMLOG_ERR,
607 _("line %d: Need arg to %%patch -d: %s\n"),
608 spec->lineNum, spec->line);
609 return RPMRC_FAIL;
610 }
611 } else if (!strncmp(s, "-p", sizeof("-p")-1)) {
612 /* unfortunately, we must support -pX */
613 if (! strchr(" \t\n", s[2])) {
614 s = s + 2;
615 } else {
616 s = strtok(NULL, " \t\n");
617 if (s == NULL) {
618 rpmlog(RPMLOG_ERR,
619 _("line %d: Need arg to %%patch -p: %s\n"),
620 spec->lineNum, spec->line);
621 return RPMRC_FAIL;
622 }
623 }
624 if (parseNum(s, &opt_p)) {
625 rpmlog(RPMLOG_ERR,
626 _("line %d: Bad arg to %%patch -p: %s\n"),
627 spec->lineNum, spec->line);
628 return RPMRC_FAIL;
629 }
630 } else {
631 /* Must be a patch num */
632 if (patch_index == 1024) {
633 rpmlog(RPMLOG_ERR, _("Too many patches!\n"));
634 return RPMRC_FAIL;
635 }
636 if (parseNum(s, &(patch_nums[patch_index]))) {
637 rpmlog(RPMLOG_ERR, _("line %d: Bad arg to %%patch: %s\n"),
638 spec->lineNum, spec->line);
639 return RPMRC_FAIL;
640 }
641 patch_index++;
642 }
643 }
644 /*@=internalglobs@*/
645
646 /* All args processed */
647
648 if (! opt_P) {
649 s = doPatch(spec, 0, opt_p, opt_b, opt_R, opt_E, opt_F, opt_d);
650 if (s == NULL)
651 return RPMRC_FAIL;
652 spec->prep = rpmiobAppend(spec->prep, s, 1);
653 }
654
655 for (x = 0; x < patch_index; x++) {
656 s = doPatch(spec, patch_nums[x], opt_p, opt_b, opt_R, opt_E, opt_F, opt_d);
657 if (s == NULL)
658 return RPMRC_FAIL;
659 spec->prep = rpmiobAppend(spec->prep, s, 1);
660 }
661
662 return RPMRC_OK;
663 }
664 #endif
665
666 static void prepFetchVerbose(/*@unused@*/ struct Source *sp,
667 /*@unused@*/ struct stat *st)
668 /*@globals internalState @*/
669 /*@modifies internalState @*/
670 {
671 char *buf;
672 size_t buf_len;
673 int xx;
674 int i;
675
676 if (!(rpmIsVerbose() && !quietly && (rpmBTArgs.buildAmount & RPMBUILD_FETCHSOURCE)))
677 return;
678 buf_len = 2*80;
679 if ((buf = (char *)malloc(buf_len)) == NULL)
680 return;
681 xx = snprintf(buf, buf_len, "%s%d:", (sp->flags & RPMFILE_SOURCE) ? "Source" : "Patch", sp->num);
682 for (i = (int)strlen(buf); i <= 11; i++)
683 buf[i] = ' ';
684 xx = snprintf(buf+i, buf_len-i, "%-52.52s", sp->source);
685 i = (int)strlen(buf);
686 if (st != NULL)
687 xx = snprintf(buf+i, buf_len-i, " %9lu Bytes\n", (unsigned long)st->st_size);
688 else
689 xx = snprintf(buf+i, buf_len-i, " ...MISSING\n");
690 rpmlog(RPMLOG_NOTICE, "%s", buf);
691 buf = _free(buf);
692 return;
693 }
694
698 static int prepFetch(Spec spec)
699 /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
700 /*@modifies rpmGlobalMacroContext, fileSystem, internalState @*/
701 {
702 #if defined(RPM_VENDOR_OPENPKG) /* splitted-source-directory */
703 const char *Smacro;
704 #endif
705 const char *Lmacro, *Lurlfn = NULL;
706 const char *Rmacro, *Rurlfn = NULL;
707 struct Source *sp;
708 struct stat st;
709 rpmRC rpmrc;
710 int ec, rc;
711 char *cp;
712
713 /* XXX insure that %{_sourcedir} exists */
714 rpmrc = RPMRC_OK;
715 Lurlfn = rpmGenPath(NULL, "%{?_sourcedir}", NULL);
716 if (Lurlfn != NULL && *Lurlfn != '\0')
717 rpmrc = rpmMkdirPath(Lurlfn, "_sourcedir");
718 Lurlfn = _free(Lurlfn);
719 if (rpmrc != RPMRC_OK)
720 return -1;
721
722 /* XXX insure that %{_patchdir} exists */
723 rpmrc = RPMRC_OK;
724 Lurlfn = rpmGenPath(NULL, "%{?_patchdir}", NULL);
725 if (Lurlfn != NULL && *Lurlfn != '\0')
726 rpmrc = rpmMkdirPath(Lurlfn, "_patchdir");
727 Lurlfn = _free(Lurlfn);
728 if (rpmrc != RPMRC_OK)
729 return -1;
730
731 /* XXX insure that %{_icondir} exists */
732 rpmrc = RPMRC_OK;
733 Lurlfn = rpmGenPath(NULL, "%{?_icondir}", NULL);
734 if (Lurlfn != NULL && *Lurlfn != '\0')
735 rpmrc = rpmMkdirPath(Lurlfn, "_icondir");
736 Lurlfn = _free(Lurlfn);
737 if (rpmrc != RPMRC_OK)
738 return -1;
739
740 if (rpmIsVerbose() && !quietly && (rpmBTArgs.buildAmount & RPMBUILD_FETCHSOURCE))
741 rpmlog(RPMLOG_NOTICE, "Checking source and patch file(s):\n");
742
743 ec = 0;
744 for (sp = spec->sources; sp != NULL; sp = sp->next) {
745
746 #if defined(RPM_VENDOR_OPENPKG) /* splitted-source-directory */
747 Smacro = "%{?_specdir}/";
748 #endif
749 #if defined(RPM_VENDOR_OPENPKG) /* splitted-source-directory */
750 if (! (Lmacro = getSourceDir(sp->flags, sp->source)))
751 #else
752 if (! (Lmacro = getSourceDir(sp->flags)))
753 #endif
754 continue;
755 if (sp->flags & RPMFILE_SOURCE) {
756 Rmacro = "%{?_Rsourcedir}/";
757 } else
758 if (sp->flags & RPMFILE_PATCH) {
759 Rmacro = "%{?_Rpatchdir}/";
760 } else
761 if (sp->flags & RPMFILE_ICON) {
762 Rmacro = "%{?_Ricondir}/";
763 } else
764 continue;
765
766 #if defined(RPM_VENDOR_OPENPKG) /* splitted-source-directory */
767 /* support splitted source directories, i.e., source files which
768 are alternatively placed into the .spec directory and picked
769 up from there, too. */
770 Lurlfn = rpmGenPath(NULL, Smacro, sp->source);
771 rc = Lstat(Lurlfn, &st);
772 if (rc == 0) {
773 prepFetchVerbose(sp, &st);
774 goto bottom;
775 }
776 #endif
777 Lurlfn = rpmGenPath(NULL, Lmacro, sp->source);
778 rc = Lstat(Lurlfn, &st);
779 if (rc == 0) {
780 /*@-noeffect@*/
781 prepFetchVerbose(sp, &st);
782 /*@=noeffect@*/
783 goto bottom;
784 }
785 /*@-noeffect@*/
786 prepFetchVerbose(sp, NULL);
787 /*@=noeffect@*/
788 if (errno != ENOENT) {
789 ec++;
790 rpmlog(RPMLOG_ERR, _("Missing %s%d %s: %s\n"),
791 ((sp->flags & RPMFILE_SOURCE) ? "Source" : "Patch"),
792 sp->num, sp->source, strerror(ENOENT));
793 goto bottom;
794 }
795
796 /* try to fetch via macro-controlled remote locations */
797 cp = rpmExpand(Rmacro, NULL);
798 if (cp != NULL && strcmp(cp, "/") != 0) {
799 cp = _free(cp);
800 Rurlfn = rpmGenPath(NULL, Rmacro, sp->source);
801 if (!(Rurlfn == NULL || Rurlfn[0] == '\0' || !strcmp(Rurlfn, "/") || !strcmp(Lurlfn, Rurlfn))) {
802 rpmlog(RPMLOG_NOTICE, _("Fetching(%s%d): %s\n"),
803 (sp->flags & RPMFILE_SOURCE) ? "Source" : "Patch", sp->num, Rurlfn);
804 rc = urlGetFile(Rurlfn, Lurlfn);
805 if (rc == 0)
806 goto bottom;
807 else {
808 rpmlog(RPMLOG_ERR, _("Fetching %s%d failed: %s\n"),
809 (sp->flags & RPMFILE_SOURCE) ? "Source" : "Patch", sp->num, ftpStrerror(rc));
810 ec++;
811 }
812 }
813 }
814 cp = _free(cp);
815
816 /* try to fetch from original location */
817 rpmlog(RPMLOG_NOTICE, _("Fetching(%s%d): %s\n"),
818 (sp->flags & RPMFILE_SOURCE) ? "Source" : "Patch", sp->num, sp->fullSource);
819 rc = urlGetFile(sp->fullSource, Lurlfn);
820 if (rc == 0)
821 goto bottom;
822 else {
823 rpmlog(RPMLOG_ERR, _("Fetching %s%d failed: %s\n"),
824 (sp->flags & RPMFILE_SOURCE) ? "Source" : "Patch", sp->num, ftpStrerror(rc));
825 ec++;
826 }
827
828 rpmlog(RPMLOG_ERR, _("Missing %s%d: %s: %s\n"),
829 ((sp->flags & RPMFILE_SOURCE) ? "Source" : "Patch"),
830 sp->num, sp->source, strerror(ENOENT));
831 ec++;
832
833 bottom:
834 Lurlfn = _free(Lurlfn);
835 Rurlfn = _free(Rurlfn);
836 }
837
838 return ec;
839 }
840
841 int parsePrep(Spec spec, int verify)
842 {
843 rpmParseState nextPart;
844 int res, rc;
845 rpmiob iob;
846 ARGV_t saveLines = NULL;
847 ARGV_t lines;
848 const char * cp;
849 int xx;
850
851 if (spec->prep != NULL) {
852 rpmlog(RPMLOG_ERR, _("line %d: second %%prep\n"), spec->lineNum);
853 return RPMRC_FAIL;
854 }
855
856 spec->prep = rpmiobNew(0);
857
858 /* There are no options to %prep */
859 if ((rc = readLine(spec, STRIP_NOTHING)) > 0)
860 return PART_NONE;
861 if (rc)
862 return rc;
863
864 /* Check to make sure that all sources/patches are present. */
865 if (verify) {
866 rc = prepFetch(spec);
867 if (rc)
868 return RPMRC_FAIL;
869 }
870
871 iob = rpmiobNew(0);
872
873 while ((nextPart = isPart(spec)) == PART_NONE) {
874 /* Need to expand the macros inline. That way we */
875 /* can give good line number information on error. */
876 iob = rpmiobAppend(iob, spec->line, 0);
877 if ((rc = readLine(spec, STRIP_NOTHING)) > 0) {
878 nextPart = PART_NONE;
879 break;
880 }
881 if (rc)
882 return rc;
883 }
884
885 xx = argvSplit(&saveLines, rpmiobStr(iob), "\n");
886
887 /*@-usereleased@*/
888 for (lines = saveLines; *lines; lines++) {
889 res = 0;
890 for (cp = *lines; *cp == ' ' || *cp == '\t'; cp++)
891 {};
892 if (!strncmp(cp, "%setup", sizeof("%setup")-1)) {
893 res = doSetupMacro(spec, cp);
894 #ifndef DYING
895 } else if (! strncmp(cp, "%patch", sizeof("%patch")-1)) {
896 res = doPatchMacro(spec, cp);
897 #endif
898 } else {
899 spec->prep = rpmiobAppend(spec->prep, *lines, 1);
900 }
901 if (res && !spec->force) {
902 saveLines = argvFree(saveLines);
903 iob = rpmiobFree(iob);
904 return res;
905 }
906 }
907 /*@=usereleased@*/
908
909 saveLines = argvFree(saveLines);
910 iob = rpmiobFree(iob);
911
912 return nextPart;
913 }