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