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