rpm  4.5
parsePrep.c
Go to the documentation of this file.
1 
6 #include "system.h"
7 
8 #include <rpmio_internal.h>
9 #include <rpmbuild.h>
10 #include "debug.h"
11 
12 /*@access StringBuf @*/ /* compared with NULL */
13 
14 /* These have to be global to make up for stupid compilers */
15 /*@unchecked@*/
17 /*@unchecked@*/
18  static int createDir, quietly;
19 /*@unchecked@*/ /*@observer@*/ /*@null@*/
20  static const char * dirName = NULL;
21 /*@unchecked@*/ /*@observer@*/
22  static struct poptOption optionsTable[] = {
23  { NULL, 'a', POPT_ARG_STRING, NULL, 'a', NULL, NULL},
24  { NULL, 'b', POPT_ARG_STRING, NULL, 'b', NULL, NULL},
25  { NULL, 'c', 0, &createDir, 0, NULL, NULL},
26  { NULL, 'D', 0, &leaveDirs, 0, NULL, NULL},
27  { NULL, 'n', POPT_ARG_STRING, &dirName, 0, NULL, NULL},
28  { NULL, 'T', 0, &skipDefaultAction, 0, NULL, NULL},
29  { NULL, 'q', 0, &quietly, 0, NULL, NULL},
30  { 0, 0, 0, 0, 0, NULL, NULL}
31  };
32 
38 static int checkOwners(const char * urlfn)
39  /*@globals h_errno, fileSystem, internalState @*/
40  /*@modifies fileSystem, internalState @*/
41 {
42  struct stat sb;
43 
44  if (Lstat(urlfn, &sb)) {
45  rpmError(RPMERR_BADSPEC, _("Bad source: %s: %s\n"),
46  urlfn, strerror(errno));
47  return RPMERR_BADSPEC;
48  }
49  if (!getUname(sb.st_uid) || !getGname(sb.st_gid)) {
50  rpmError(RPMERR_BADSPEC, _("Bad owner/group: %s\n"), urlfn);
51  return RPMERR_BADSPEC;
52  }
53 
54  return 0;
55 }
56 
68 /*@-boundswrite@*/
69 /*@observer@*/
70 static char *doPatch(Spec spec, int c, int strip, const char *db,
71  int reverse, int removeEmpties, int fuzz)
72  /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
73  /*@modifies rpmGlobalMacroContext, fileSystem, internalState @*/
74 {
75  const char *fn, *Lurlfn;
76  static char buf[BUFSIZ];
77  char args[BUFSIZ], *t = args;
78  struct Source *sp;
80  int urltype;
81 
82  *t = '\0';
83  if (db) {
84 #if HAVE_OLDPATCH_21 == 0
85  t = stpcpy(t, "-b ");
86 #endif
87  t = stpcpy( stpcpy(t, "--suffix "), db);
88  }
89  if (fuzz) {
90  t = stpcpy(t, " -F ");
91  sprintf(t, "%10.10d", fuzz);
92  t += strlen(t);
93  }
94  if (reverse)
95  t = stpcpy(t, " -R");
96  if (removeEmpties)
97  t = stpcpy(t, " -E");
98 
99  for (sp = spec->sources; sp != NULL; sp = sp->next) {
100  if ((sp->flags & RPMFILE_PATCH) && (sp->num == c))
101  break;
102  }
103  if (sp == NULL) {
104  rpmError(RPMERR_BADSPEC, _("No patch number %d\n"), c);
105  return NULL;
106  }
107 
108  Lurlfn = rpmGenPath(NULL, "%{_patchdir}/", sp->source);
109 
110  /* XXX On non-build parse's, file cannot be stat'd or read */
111  if (!spec->force && (isCompressed(Lurlfn, &compressed) || checkOwners(Lurlfn))) {
112  Lurlfn = _free(Lurlfn);
113  return NULL;
114  }
115 
116  fn = NULL;
117  urltype = urlPath(Lurlfn, &fn);
118  switch (urltype) {
119  case URL_IS_HTTPS: /* XXX WRONG WRONG WRONG */
120  case URL_IS_HTTP: /* XXX WRONG WRONG WRONG */
121  case URL_IS_FTP: /* XXX WRONG WRONG WRONG */
122  case URL_IS_HKP: /* XXX WRONG WRONG WRONG */
123  case URL_IS_PATH:
124  case URL_IS_UNKNOWN:
125  break;
126  case URL_IS_DASH:
127  Lurlfn = _free(Lurlfn);
128  return NULL;
129  /*@notreached@*/ break;
130  }
131 
132  if (compressed) {
133  const char *zipper;
134 
135  switch (compressed) {
136  default:
137  case COMPRESSED_NOT: /* XXX can't happen */
138  case COMPRESSED_OTHER:
139  case COMPRESSED_ZIP: /* XXX wrong */
140  zipper = "%{__gzip}";
141  break;
142  case COMPRESSED_BZIP2:
143  zipper = "%{__bzip2}";
144  break;
145  case COMPRESSED_LZOP:
146  zipper = "%{__lzop}";
147  break;
148  case COMPRESSED_LZMA:
149  zipper = "%{__lzma}";
150  break;
151  }
152  zipper = rpmGetPath(zipper, NULL);
153 
154  sprintf(buf,
155  "echo \"Patch #%d (%s):\"\n"
156  "%s -d < '%s' | patch -p%d %s -s\n"
157  "STATUS=$?\n"
158  "if [ $STATUS -ne 0 ]; then\n"
159  " exit $STATUS\n"
160  "fi",
161  c, /*@-unrecog@*/ (const char *) basename(fn), /*@=unrecog@*/
162  zipper,
163  fn, strip, args);
164  zipper = _free(zipper);
165  } else {
166  sprintf(buf,
167  "echo \"Patch #%d (%s):\"\n"
168  "patch -p%d %s -s < '%s'", c, (const char *) basename(fn),
169  strip, args, fn);
170  }
171 
172  Lurlfn = _free(Lurlfn);
173  return buf;
174 }
175 /*@=boundswrite@*/
176 
184 /*@-boundswrite@*/
185 /*@observer@*/
186 static const char *doUntar(Spec spec, int c, int quietly)
187  /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
188  /*@modifies rpmGlobalMacroContext, fileSystem, internalState @*/
189 {
190  const char *fn, *Lurlfn;
191  static char buf[BUFSIZ];
192  char *taropts;
193  char *t = NULL;
194  struct Source *sp;
195  rpmCompressedMagic compressed = COMPRESSED_NOT;
196  int urltype;
197 
198  for (sp = spec->sources; sp != NULL; sp = sp->next) {
199  if ((sp->flags & RPMFILE_SOURCE) && (sp->num == c)) {
200  break;
201  }
202  }
203  if (sp == NULL) {
204  rpmError(RPMERR_BADSPEC, _("No source number %d\n"), c);
205  return NULL;
206  }
207 
208  /*@-internalglobs@*/ /* FIX: shrug */
209  taropts = ((rpmIsVerbose() && !quietly) ? "-xvvf" : "-xf");
210  /*@=internalglobs@*/
211 
212  Lurlfn = rpmGenPath(NULL, "%{_sourcedir}/", sp->source);
213 
214  /* XXX On non-build parse's, file cannot be stat'd or read */
215  if (!spec->force && (isCompressed(Lurlfn, &compressed) || checkOwners(Lurlfn))) {
216  Lurlfn = _free(Lurlfn);
217  return NULL;
218  }
219 
220  fn = NULL;
221  urltype = urlPath(Lurlfn, &fn);
222  switch (urltype) {
223  case URL_IS_HTTPS: /* XXX WRONG WRONG WRONG */
224  case URL_IS_HTTP: /* XXX WRONG WRONG WRONG */
225  case URL_IS_FTP: /* XXX WRONG WRONG WRONG */
226  case URL_IS_HKP: /* XXX WRONG WRONG WRONG */
227  case URL_IS_PATH:
228  case URL_IS_UNKNOWN:
229  break;
230  case URL_IS_DASH:
231  Lurlfn = _free(Lurlfn);
232  return NULL;
233  /*@notreached@*/ break;
234  }
235 
236  if (compressed != COMPRESSED_NOT) {
237  const char *zipper;
238  int needtar = 1;
239 
240  switch (compressed) {
241  case COMPRESSED_NOT: /* XXX can't happen */
242  case COMPRESSED_OTHER:
243  t = "%{__gzip} -dc";
244  break;
245  case COMPRESSED_BZIP2:
246  t = "%{__bzip2} -dc";
247  break;
248  case COMPRESSED_LZOP:
249  t = "%{__lzop} -dc";
250  break;
251  case COMPRESSED_LZMA:
252  t = "%{__lzma} -dc";
253  break;
254  case COMPRESSED_ZIP:
255  if (rpmIsVerbose() && !quietly)
256  t = "%{__unzip}";
257  else
258  t = "%{__unzip} -qq";
259  needtar = 0;
260  break;
261  }
262  zipper = rpmGetPath(t, NULL);
263  buf[0] = '\0';
264  t = stpcpy(buf, zipper);
265  zipper = _free(zipper);
266  *t++ = ' ';
267  *t++ = '\'';
268  t = stpcpy(t, fn);
269  *t++ = '\'';
270  if (needtar)
271  t = stpcpy( stpcpy( stpcpy(t, " | tar "), taropts), " -");
272  t = stpcpy(t,
273  "\n"
274  "STATUS=$?\n"
275  "if [ $STATUS -ne 0 ]; then\n"
276  " exit $STATUS\n"
277  "fi");
278  } else {
279  buf[0] = '\0';
280  t = stpcpy( stpcpy(buf, "tar "), taropts);
281  *t++ = ' ';
282  t = stpcpy(t, fn);
283  }
284 
285  Lurlfn = _free(Lurlfn);
286  return buf;
287 }
288 /*@=boundswrite@*/
289 
297 static int doSetupMacro(Spec spec, char *line)
298  /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
299  /*@modifies spec->buildSubdir, spec->macros, spec->prep,
300  rpmGlobalMacroContext, fileSystem, internalState @*/
301 {
302  char buf[BUFSIZ];
303  StringBuf before;
304  StringBuf after;
305  poptContext optCon;
306  int argc;
307  const char ** argv;
308  int arg;
309  const char * optArg;
310  int rc;
311  int num;
312 
313  /*@-mods@*/
315  createDir = quietly = 0;
316  dirName = NULL;
317  /*@=mods@*/
318 
319  if ((rc = poptParseArgvString(line, &argc, &argv))) {
320  rpmError(RPMERR_BADSPEC, _("Error parsing %%setup: %s\n"),
321  poptStrerror(rc));
322  return RPMERR_BADSPEC;
323  }
324 
325  before = newStringBuf();
326  after = newStringBuf();
327 
328  optCon = poptGetContext(NULL, argc, argv, optionsTable, 0);
329  while ((arg = poptGetNextOpt(optCon)) > 0) {
330  optArg = poptGetOptArg(optCon);
331 
332  /* We only parse -a and -b here */
333 
334  if (parseNum(optArg, &num)) {
335  rpmError(RPMERR_BADSPEC, _("line %d: Bad arg to %%setup: %s\n"),
336  spec->lineNum, (optArg ? optArg : "???"));
337  before = freeStringBuf(before);
338  after = freeStringBuf(after);
339  optCon = poptFreeContext(optCon);
340  argv = _free(argv);
341  return RPMERR_BADSPEC;
342  }
343 
344  { const char *chptr = doUntar(spec, num, quietly);
345  if (chptr == NULL)
346  return RPMERR_BADSPEC;
347 
348  appendLineStringBuf((arg == 'a' ? after : before), chptr);
349  }
350  }
351 
352  if (arg < -1) {
353  rpmError(RPMERR_BADSPEC, _("line %d: Bad %%setup option %s: %s\n"),
354  spec->lineNum,
355  poptBadOption(optCon, POPT_BADOPTION_NOALIAS),
356  poptStrerror(arg));
357  before = freeStringBuf(before);
358  after = freeStringBuf(after);
359  optCon = poptFreeContext(optCon);
360  argv = _free(argv);
361  return RPMERR_BADSPEC;
362  }
363 
364  if (dirName) {
365  spec->buildSubdir = xstrdup(dirName);
366  } else {
367  const char *name, *version;
368  (void) headerNVR(spec->packages->header, &name, &version, NULL);
369  sprintf(buf, "%s-%s", name, version);
370  spec->buildSubdir = xstrdup(buf);
371  }
372  addMacro(spec->macros, "buildsubdir", NULL, spec->buildSubdir, RMIL_SPEC);
373 
374  optCon = poptFreeContext(optCon);
375  argv = _free(argv);
376 
377  /* cd to the build dir */
378  { const char * buildDirURL = rpmGenPath(spec->rootURL, "%{_builddir}", "");
379  const char *buildDir;
380 
381  (void) urlPath(buildDirURL, &buildDir);
382  sprintf(buf, "cd '%s'", buildDir);
383  appendLineStringBuf(spec->prep, buf);
384  buildDirURL = _free(buildDirURL);
385  }
386 
387  /* delete any old sources */
388  if (!leaveDirs) {
389  sprintf(buf, "rm -rf '%s'", spec->buildSubdir);
390  appendLineStringBuf(spec->prep, buf);
391  }
392 
393  /* if necessary, create and cd into the proper dir */
394  if (createDir) {
395  sprintf(buf, MKDIR_P " '%s'\ncd '%s'",
396  spec->buildSubdir, spec->buildSubdir);
397  appendLineStringBuf(spec->prep, buf);
398  }
399 
400  /* do the default action */
401  if (!createDir && !skipDefaultAction) {
402  const char *chptr = doUntar(spec, 0, quietly);
403  if (!chptr)
404  return RPMERR_BADSPEC;
405  appendLineStringBuf(spec->prep, chptr);
406  }
407 
408  appendStringBuf(spec->prep, getStringBuf(before));
409  before = freeStringBuf(before);
410 
411  if (!createDir) {
412  sprintf(buf, "cd '%s'", spec->buildSubdir);
413  appendLineStringBuf(spec->prep, buf);
414  }
415 
416  if (createDir && !skipDefaultAction) {
417  const char * chptr = doUntar(spec, 0, quietly);
418  if (chptr == NULL)
419  return RPMERR_BADSPEC;
420  appendLineStringBuf(spec->prep, chptr);
421  }
422 
423  appendStringBuf(spec->prep, getStringBuf(after));
424  after = freeStringBuf(after);
425 
426  /* XXX FIXME: owner & group fixes were conditioned on !geteuid() */
427  /* Fix the owner, group, and permissions of the setup build tree */
428  { /*@observer@*/ static const char *fixmacs[] =
429  { "%{_fixowner}", "%{_fixgroup}", "%{_fixperms}", NULL };
430  const char ** fm;
431 
432  for (fm = fixmacs; *fm; fm++) {
433  const char *fix;
434 /*@-boundsread@*/
435  fix = rpmExpand(*fm, " .", NULL);
436  if (fix && *fix != '%')
437  appendLineStringBuf(spec->prep, fix);
438  fix = _free(fix);
439 /*@=boundsread@*/
440  }
441  }
442 
443  return 0;
444 }
445 
452 /*@-boundswrite@*/
453 static int doPatchMacro(Spec spec, char *line)
454  /*@globals rpmGlobalMacroContext, h_errno,
455  fileSystem, internalState @*/
456  /*@modifies spec->prep, rpmGlobalMacroContext,
457  fileSystem, internalState @*/
458 {
459  char *opt_b;
460  int opt_P, opt_p, opt_R, opt_E, opt_F;
461  char *s;
462  char buf[BUFSIZ], *bp;
463  int patch_nums[1024]; /* XXX - we can only handle 1024 patches! */
464  int patch_index, x;
465 
466  memset(patch_nums, 0, sizeof(patch_nums));
467  opt_P = opt_p = opt_R = opt_E = opt_F = 0;
468  opt_b = NULL;
469  patch_index = 0;
470 
471  if (! strchr(" \t\n", line[6])) {
472  /* %patchN */
473  sprintf(buf, "%%patch -P %s", line + 6);
474  } else {
475  strcpy(buf, line);
476  }
477 
478  /*@-internalglobs@*/ /* FIX: strtok has state */
479  for (bp = buf; (s = strtok(bp, " \t\n")) != NULL;) {
480  if (bp) { /* remove 1st token (%patch) */
481  bp = NULL;
482  continue;
483  }
484  if (!strcmp(s, "-P")) {
485  opt_P = 1;
486  } else if (!strcmp(s, "-R")) {
487  opt_R = 1;
488  } else if (!strcmp(s, "-E")) {
489  opt_E = 1;
490  } else if (!strcmp(s, "-b")) {
491  /* orig suffix */
492  opt_b = strtok(NULL, " \t\n");
493  if (! opt_b) {
495  _("line %d: Need arg to %%patch -b: %s\n"),
496  spec->lineNum, spec->line);
497  return RPMERR_BADSPEC;
498  }
499  } else if (!strcmp(s, "-z")) {
500  /* orig suffix */
501  opt_b = strtok(NULL, " \t\n");
502  if (! opt_b) {
504  _("line %d: Need arg to %%patch -z: %s\n"),
505  spec->lineNum, spec->line);
506  return RPMERR_BADSPEC;
507  }
508  } else if (!strcmp(s, "-F")) {
509  /* fuzz factor */
510  const char * fnum = (!strchr(" \t\n", s[2])
511  ? s+2 : strtok(NULL, " \t\n"));
512  char * end = NULL;
513 
514  opt_F = (fnum ? strtol(fnum, &end, 10) : 0);
515  if (! opt_F || *end) {
517  _("line %d: Bad arg to %%patch -F: %s\n"),
518  spec->lineNum, spec->line);
519  return RPMERR_BADSPEC;
520  }
521  } else if (!strncmp(s, "-p", sizeof("-p")-1)) {
522  /* unfortunately, we must support -pX */
523  if (! strchr(" \t\n", s[2])) {
524  s = s + 2;
525  } else {
526  s = strtok(NULL, " \t\n");
527  if (s == NULL) {
529  _("line %d: Need arg to %%patch -p: %s\n"),
530  spec->lineNum, spec->line);
531  return RPMERR_BADSPEC;
532  }
533  }
534  if (parseNum(s, &opt_p)) {
536  _("line %d: Bad arg to %%patch -p: %s\n"),
537  spec->lineNum, spec->line);
538  return RPMERR_BADSPEC;
539  }
540  } else {
541  /* Must be a patch num */
542  if (patch_index == 1024) {
543  rpmError(RPMERR_BADSPEC, _("Too many patches!\n"));
544  return RPMERR_BADSPEC;
545  }
546  if (parseNum(s, &(patch_nums[patch_index]))) {
547  rpmError(RPMERR_BADSPEC, _("line %d: Bad arg to %%patch: %s\n"),
548  spec->lineNum, spec->line);
549  return RPMERR_BADSPEC;
550  }
551  patch_index++;
552  }
553  }
554  /*@=internalglobs@*/
555 
556  /* All args processed */
557 
558  if (! opt_P) {
559  s = doPatch(spec, 0, opt_p, opt_b, opt_R, opt_E, opt_F);
560  if (s == NULL)
561  return RPMERR_BADSPEC;
562  appendLineStringBuf(spec->prep, s);
563  }
564 
565  for (x = 0; x < patch_index; x++) {
566  s = doPatch(spec, patch_nums[x], opt_p, opt_b, opt_R, opt_E, opt_F);
567  if (s == NULL)
568  return RPMERR_BADSPEC;
569  appendLineStringBuf(spec->prep, s);
570  }
571 
572  return 0;
573 }
574 /*@=boundswrite@*/
575 
579 static int prepFetch(Spec spec)
580  /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
581  /*@modifies rpmGlobalMacroContext, fileSystem, internalState @*/
582 {
583  const char *Lmacro, *Lurlfn = NULL;
584  const char *Rmacro, *Rurlfn = NULL;
585  struct Source *sp;
586  struct stat st;
587  rpmRC rpmrc;
588  int ec, rc;
589 
590  /* XXX insure that %{_sourcedir} exists */
591  rpmrc = RPMRC_OK;
592  Lurlfn = rpmGenPath(NULL, "%{?_sourcedir}", NULL);
593  if (Lurlfn != NULL && *Lurlfn != '\0')
594  rpmrc = rpmMkdirPath(Lurlfn, "_sourcedir");
595  Lurlfn = _free(Lurlfn);
596  if (rpmrc != RPMRC_OK)
597  return -1;
598 
599  /* XXX insure that %{_patchdir} exists */
600  rpmrc = RPMRC_OK;
601  Lurlfn = rpmGenPath(NULL, "%{?_patchdir}", NULL);
602  if (Lurlfn != NULL && *Lurlfn != '\0')
603  rpmrc = rpmMkdirPath(Lurlfn, "_patchdir");
604  Lurlfn = _free(Lurlfn);
605  if (rpmrc != RPMRC_OK)
606  return -1;
607 
608  /* XXX insure that %{_icondir} exists */
609  rpmrc = RPMRC_OK;
610  Lurlfn = rpmGenPath(NULL, "%{?_icondir}", NULL);
611  if (Lurlfn != NULL && *Lurlfn != '\0')
612  rpmrc = rpmMkdirPath(Lurlfn, "_icondir");
613  Lurlfn = _free(Lurlfn);
614  if (rpmrc != RPMRC_OK)
615  return -1;
616 
617 /*@-branchstate@*/
618  ec = 0;
619  for (sp = spec->sources; sp != NULL; sp = sp->next) {
620 
621  if (sp->flags & RPMFILE_SOURCE) {
622  Rmacro = "%{_Rsourcedir}/";
623  Lmacro = "%{_sourcedir}/";
624  } else
625  if (sp->flags & RPMFILE_PATCH) {
626  Rmacro = "%{_Rpatchdir}/";
627  Lmacro = "%{_patchdir}/";
628  } else
629  if (sp->flags & RPMFILE_ICON) {
630  Rmacro = "%{_Ricondir}/";
631  Lmacro = "%{_icondir}/";
632  } else
633  continue;
634 
635  Lurlfn = rpmGenPath(NULL, Lmacro, sp->source);
636  rc = Lstat(Lurlfn, &st);
637  if (rc == 0)
638  goto bottom;
639  if (errno != ENOENT) {
640  ec++;
641  rpmError(RPMERR_BADFILENAME, _("Missing %s%d %s: %s\n"),
642  ((sp->flags & RPMFILE_SOURCE) ? "Source" : "Patch"),
643  sp->num, sp->source, strerror(ENOENT));
644  goto bottom;
645  }
646 
647  Rurlfn = rpmGenPath(NULL, Rmacro, sp->source);
648  if (Rurlfn == NULL || *Rurlfn == '%' || !strcmp(Lurlfn, Rurlfn)) {
649  rpmError(RPMERR_BADFILENAME, _("file %s missing: %s\n"),
650  Lurlfn, strerror(errno));
651  ec++;
652  goto bottom;
653  }
654 
655  rc = urlGetFile(Rurlfn, Lurlfn);
656  if (rc != 0) {
657  rpmError(RPMERR_BADFILENAME, _("Fetching %s failed: %s\n"),
658  Rurlfn, ftpStrerror(rc));
659  ec++;
660  goto bottom;
661  }
662 
663 bottom:
664  Lurlfn = _free(Lurlfn);
665  Rurlfn = _free(Rurlfn);
666  }
667 /*@=branchstate@*/
668 
669  return ec;
670 }
671 
672 int parsePrep(Spec spec, int verify)
673 {
674  int nextPart, res, rc;
675  StringBuf sb;
676  char **lines, **saveLines;
677 
678  if (spec->prep != NULL) {
679  rpmError(RPMERR_BADSPEC, _("line %d: second %%prep\n"), spec->lineNum);
680  return RPMERR_BADSPEC;
681  }
682 
683  spec->prep = newStringBuf();
684 
685  /* There are no options to %prep */
686  if ((rc = readLine(spec, STRIP_NOTHING)) > 0)
687  return PART_NONE;
688  if (rc)
689  return rc;
690 
691  /* Check to make sure that all sources/patches are present. */
692  if (verify) {
693  rc = prepFetch(spec);
694  if (rc)
695  return RPMERR_BADSPEC;
696  }
697 
698  sb = newStringBuf();
699 
700  while (! (nextPart = isPart(spec->line))) {
701  /* Need to expand the macros inline. That way we */
702  /* can give good line number information on error. */
703  appendStringBuf(sb, spec->line);
704  if ((rc = readLine(spec, STRIP_NOTHING)) > 0) {
705  nextPart = PART_NONE;
706  break;
707  }
708  if (rc)
709  return rc;
710  }
711 
712  saveLines = splitString(getStringBuf(sb), strlen(getStringBuf(sb)), '\n');
713  /*@-usereleased@*/
714  for (lines = saveLines; *lines; lines++) {
715  res = 0;
716 /*@-boundsread@*/
717  if (! strncmp(*lines, "%setup", sizeof("%setup")-1)) {
718  res = doSetupMacro(spec, *lines);
719  } else if (! strncmp(*lines, "%patch", sizeof("%patch")-1)) {
720  res = doPatchMacro(spec, *lines);
721  } else {
722  appendLineStringBuf(spec->prep, *lines);
723  }
724 /*@=boundsread@*/
725  if (res && !spec->force) {
726  freeSplitString(saveLines);
727  sb = freeStringBuf(sb);
728  return res;
729  }
730  }
731  /*@=usereleased@*/
732 
733  freeSplitString(saveLines);
734  sb = freeStringBuf(sb);
735 
736  return nextPart;
737 }