home *** CD-ROM | disk | FTP | other *** search
/ Chip 1998 February / CHIP_2_98.iso / misc / src / rpm / build / build.c next >
C/C++ Source or Header  |  1997-09-17  |  17KB  |  736 lines

  1. /* RPM - Copyright (C) 1995 Red Hat Software
  2.  * 
  3.  * build.c - routines for preparing and building the sources
  4.  */
  5.  
  6. #include "miscfn.h"
  7.  
  8. #include <stdlib.h>
  9. #include <stdio.h>
  10. #include <sys/time.h>
  11. #include <sys/resource.h>
  12. #include <sys/stat.h>
  13. #include <sys/wait.h>
  14. #include <unistd.h>
  15. #include <fcntl.h>
  16. #include <string.h>
  17. #include <limits.h>
  18.  
  19. #include "build.h"
  20. #include "files.h"
  21. #include "header.h"
  22. #include "spec.h"
  23. #include "specP.h"
  24. #include "rpmlib.h"
  25. #include "messages.h"
  26. #include "stringbuf.h"
  27. #include "misc.h"
  28. #include "pack.h"
  29. #include "popt.h"
  30.  
  31. #include "names.h"
  32.  
  33. struct Script {
  34.     char *name;
  35.     FILE *file;
  36. };
  37.  
  38. struct Script *openScript(Spec spec, int builddir, char *name);
  39. void writeScript(struct Script *script, char *s);
  40. int execScript(struct Script *script);
  41. void freeScript(struct Script *script, int test);
  42. int execPart(Spec s, char *sb, char *name, int builddir, int test);
  43. static int doSetupMacro(Spec spec, StringBuf sb, char *line);
  44. static int doPatchMacro(Spec spec, StringBuf sb, char *line);
  45. static char *do_untar(Spec spec, int c, int quietly);
  46. static char *do_patch(Spec spec, int c, int strip, char *dashb,
  47.               int reverse, int removeEmpties);
  48. int isCompressed(char *file);
  49. static void doSweep(Spec s);
  50. static int doRmSource(Spec s);
  51.  
  52. char build_subdir[1024];
  53.  
  54. struct Script *openScript(Spec spec, int builddir, char *name)
  55. {
  56.     struct Script *script = malloc(sizeof(struct Script));
  57.     struct PackageRec *main_package = spec->packages;
  58.     char *s, * arch, * os;
  59.     int fd;
  60.     int_32 foo;
  61.  
  62.     rpmGetArchInfo(&arch, NULL);
  63.     rpmGetOsInfo(&os, NULL);
  64.  
  65.     if (! main_package) {
  66.     rpmError(RPMERR_INTERNAL, "Empty main package");
  67.     exit(RPMERR_INTERNAL);
  68.     }
  69.     
  70.     if (makeTempFile(NULL, &script->name, &fd))
  71.     exit(1);
  72.     script->file = fdopen(fd, "w");
  73.  
  74.     /* Prepare the script */
  75.     fprintf(script->file,
  76.         "# Script generated by rpm\n\n");
  77.  
  78.     fprintf(script->file, "RPM_SOURCE_DIR=\"%s\"\n", rpmGetVar(RPMVAR_SOURCEDIR));
  79.     fprintf(script->file, "RPM_BUILD_DIR=\"%s\"\n", rpmGetVar(RPMVAR_BUILDDIR));
  80.     fprintf(script->file, "RPM_DOC_DIR=\"%s\"\n", rpmGetVar(RPMVAR_DEFAULTDOCDIR));
  81.     fprintf(script->file, "RPM_OPT_FLAGS=\"%s\"\n", rpmGetVar(RPMVAR_OPTFLAGS));
  82.     fprintf(script->file, "RPM_ARCH=\"%s\"\n", arch);
  83.     fprintf(script->file, "RPM_OS=\"%s\"\n", os);
  84.     if (rpmGetVar(RPMVAR_ROOT)) {
  85.     fprintf(script->file, "RPM_ROOT_DIR=\"%s\"\n", rpmGetVar(RPMVAR_ROOT));
  86.     } else {
  87.     fprintf(script->file, "RPM_ROOT_DIR=\"\"\n");
  88.     }
  89.     if (rpmGetVar(RPMVAR_BUILDROOT)) {
  90.     fprintf(script->file, "RPM_BUILD_ROOT=\"%s\"\n",
  91.         rpmGetVar(RPMVAR_BUILDROOT));
  92.     } else {
  93.     fprintf(script->file, "RPM_BUILD_ROOT=\"\"\n");
  94.     }
  95.  
  96.     fprintf(script->file, "RPM_PACKAGE_NAME=\"%s\"\n", spec->name);
  97.     headerGetEntry(main_package->header, RPMTAG_VERSION, &foo, (void **)&s, &foo);
  98.     fprintf(script->file, "RPM_PACKAGE_VERSION=\"%s\"\n", s);
  99.     headerGetEntry(main_package->header, RPMTAG_RELEASE, &foo, (void **)&s, &foo);
  100.     fprintf(script->file, "RPM_PACKAGE_RELEASE=\"%s\"\n", s);
  101.  
  102.     if (rpmIsVerbose()) {
  103.     fprintf(script->file, "set -x\n\n");
  104.     } else {
  105.     fprintf(script->file, "exec > /dev/null\n\n");
  106.     }
  107.  
  108.     /* Set the umask to a known value */
  109.     fprintf(script->file, "umask 022\n");
  110.  
  111.     fprintf(script->file, "\necho Executing: %s\n", name);
  112.     fprintf(script->file, "cd %s\n\n", rpmGetVar(RPMVAR_BUILDDIR));
  113.     if (builddir) {
  114.     /* Need to cd to the actual build directory. */
  115.     /* Note that this means we have to parse the */
  116.     /* %prep section even if we aren't using it. */
  117.     fprintf(script->file, "cd %s\n\n", build_subdir);
  118.     }
  119.  
  120.     return script;
  121. }
  122.  
  123. void writeScript(struct Script *script, char *s)
  124. {
  125.     fprintf(script->file, "%s", s);
  126. }
  127.  
  128. int execScript(struct Script *script)
  129. {
  130.     int pid;
  131.     int status;
  132.     
  133.     writeScript(script, "\nexit 0;\n");
  134.     fclose(script->file);
  135.     script->file = NULL;
  136.     chmod(script->name, 0600);
  137.  
  138.     if (!(pid = fork())) {
  139.     execl("/bin/sh", "/bin/sh", "-e", script->name, script->name, NULL);
  140.     rpmError(RPMERR_SCRIPT, "Exec failed");
  141.     _exit(RPMERR_SCRIPT);
  142.     }
  143.     wait(&status);
  144.     if (! WIFEXITED(status) || WEXITSTATUS(status)) {
  145.     rpmError(RPMERR_SCRIPT, "Bad exit status");
  146.     exit(RPMERR_SCRIPT);
  147.     }
  148.     return 0;
  149. }
  150.  
  151. void freeScript(struct Script *script, int test)
  152. {
  153.     if (script->file)
  154.     fclose(script->file);
  155.     if (! test)
  156.     unlink(script->name);
  157.     free(script->name);
  158.     free(script);
  159. }
  160.  
  161. int execPart(Spec s, char *sb, char *name, int builddir, int test)
  162. {
  163.     struct Script *script;
  164.  
  165.     rpmMessage(RPMMESS_DEBUG, "RUNNING: %s\n", name);
  166.     script = openScript(s, builddir, name);
  167.     writeScript(script, sb);
  168.     if (!test) {
  169.     execScript(script);
  170.     }
  171.     freeScript(script, test);
  172.     return 0;
  173. }
  174.  
  175. static void doSweep(Spec s)
  176. {
  177.     char buf[1024];
  178.  
  179.     if (strcmp(build_subdir, ".")) {
  180.         struct Script *script;
  181.         script = openScript(s, 0, "sweep");
  182.         sprintf(buf, "rm -rf %s\n", build_subdir);
  183.         writeScript(script, buf);
  184.         execScript(script);
  185.         freeScript(script, 0);
  186.     }
  187. }
  188.  
  189. static int doRmSource(Spec s)
  190. {
  191.     char filename[1024];
  192.     struct sources *source;
  193.     struct PackageRec *package;
  194.  
  195.     /* spec file */
  196.     sprintf(filename, "%s%s", rpmGetVar(RPMVAR_SPECDIR),
  197.         strrchr(s->specfile, '/'));
  198.     unlink(filename);
  199.  
  200.     /* sources and patches */
  201.     source = s->sources;
  202.     while (source) {
  203.     sprintf(filename, "%s/%s", rpmGetVar(RPMVAR_SOURCEDIR), source->source);
  204.     unlink(filename);
  205.     source = source->next;
  206.     }
  207.  
  208.     /* icons */
  209.     package = s->packages;
  210.     while (package) {
  211.     if (package->icon) {
  212.         sprintf(filename, "%s/%s", rpmGetVar(RPMVAR_SOURCEDIR),
  213.             package->icon);
  214.         unlink(filename);
  215.     }
  216.     package = package->next;
  217.     }
  218.     
  219.     return 0;
  220. }
  221.  
  222. static int doSetupMacro(Spec spec, StringBuf sb, char *line)
  223. {
  224.     char *version;
  225.     int leaveDirs = 0, skipDefaultAction = 0;
  226.     int createDir = 0, quietly = 0;
  227.     char * dirName = NULL;
  228.     char buf[1024];
  229.     StringBuf before;
  230.     StringBuf after;
  231.     poptContext optCon;
  232.     int argc;
  233.     char ** argv;
  234.     int arg;
  235.     char * optArg;
  236.     char * chptr;
  237.     int rc;
  238.     int num;
  239.     struct poptOption optionsTable[] = {
  240.         { NULL, 'a', POPT_ARG_STRING, NULL, 'a' },
  241.         { NULL, 'b', POPT_ARG_STRING, NULL, 'b' },
  242.         { NULL, 'c', 0, &createDir, 0 },
  243.         { NULL, 'D', 0, &leaveDirs, 0 },
  244.         { NULL, 'n', POPT_ARG_STRING, &dirName, 0 },
  245.         { NULL, 'T', 0, &skipDefaultAction, 0 },
  246.         { NULL, 'q', 0, &quietly, 0 },
  247.     };
  248.  
  249.     if ((rc = poptParseArgvString(line, &argc, &argv))) {
  250.     rpmError(RPMERR_BADSPEC, "Error parsing %%setup: %s",
  251.             poptStrerror(rc));
  252.     return RPMERR_BADSPEC;
  253.     }
  254.  
  255.     before = newStringBuf();
  256.     after = newStringBuf();
  257.  
  258.     optCon = poptGetContext(NULL, argc, argv, optionsTable, 0);
  259.     while ((arg = poptGetNextOpt(optCon)) > 0) {
  260.     optArg = poptGetOptArg(optCon);
  261.  
  262.     /* We only parse -a and -b here */
  263.  
  264.     num = strtoul(optArg, &chptr, 10);
  265.     if ((*chptr) || (chptr == optArg) || (num == ULONG_MAX)) {
  266.         rpmError(RPMERR_BADSPEC, "Bad arg to %%setup %c: %s", num, optArg);
  267.         free(argv);
  268.         freeStringBuf(before);
  269.         freeStringBuf(after);
  270.         poptFreeContext(optCon);
  271.         return(RPMERR_BADSPEC);
  272.     }
  273.  
  274.     chptr = do_untar(spec, num, quietly);
  275.     if (!chptr) return 1;
  276.  
  277.     if (arg == 'a')
  278.         appendLineStringBuf(after, chptr);
  279.     else
  280.         appendLineStringBuf(before, chptr);
  281.     }
  282.  
  283.     if (arg < -1) {
  284.     rpmError(RPMERR_BADSPEC, "Bad %%setup option %s: %s",
  285.         poptBadOption(optCon, POPT_BADOPTION_NOALIAS), 
  286.         poptStrerror(arg));
  287.     free(argv);
  288.     freeStringBuf(before);
  289.     freeStringBuf(after);
  290.     poptFreeContext(optCon);
  291.     return(RPMERR_BADSPEC);
  292.     }
  293.  
  294.     if (dirName) {
  295.     strcpy(build_subdir, dirName);
  296.     } else {
  297.     strcpy(build_subdir, spec->name);
  298.     strcat(build_subdir, "-");
  299.     /* We should already have a version field */
  300.     headerGetEntry(spec->packages->header, RPMTAG_VERSION, NULL,
  301.          (void *) &version, NULL);
  302.     strcat(build_subdir, version);
  303.     }
  304.     
  305.     free(argv);
  306.     poptFreeContext(optCon);
  307.  
  308.     /* cd to the build dir */
  309.     sprintf(buf, "cd %s", rpmGetVar(RPMVAR_BUILDDIR));
  310.     appendLineStringBuf(sb, buf);
  311.     
  312.     /* delete any old sources */
  313.     if (!leaveDirs) {
  314.     sprintf(buf, "rm -rf %s", build_subdir);
  315.     appendLineStringBuf(sb, buf);
  316.     }
  317.  
  318.     /* if necessary, create and cd into the proper dir */
  319.     if (createDir) {
  320.     sprintf(buf, "mkdir -p %s\ncd %s", build_subdir, build_subdir);
  321.     appendLineStringBuf(sb, buf);
  322.     }
  323.  
  324.     /* do the default action */
  325.     if (!createDir && !skipDefaultAction) {
  326.     chptr = do_untar(spec, 0, quietly);
  327.     if (!chptr) return 1;
  328.     appendLineStringBuf(sb, chptr);
  329.     }
  330.  
  331.     appendStringBuf(sb, getStringBuf(before));
  332.     freeStringBuf(before);
  333.  
  334.     if (!createDir) {
  335.     sprintf(buf, "cd %s", build_subdir);
  336.     appendLineStringBuf(sb, buf);
  337.     }
  338.  
  339.     if (createDir && !skipDefaultAction) {
  340.     chptr = do_untar(spec, 0, quietly);
  341.     if (!chptr) return 1;
  342.     appendLineStringBuf(sb, chptr);
  343.     }
  344.     
  345.     appendStringBuf(sb, getStringBuf(after));
  346.     freeStringBuf(after);
  347.  
  348.     /* clean up permissions etc */
  349.     if (!geteuid()) {
  350.     appendLineStringBuf(sb, "chown -R root .");
  351.     appendLineStringBuf(sb, "chgrp -R root .");
  352.     }
  353.  
  354.     if (rpmGetVar(RPMVAR_FIXPERMS)) {
  355.     appendStringBuf(sb, "chmod -R ");
  356.     appendStringBuf(sb, rpmGetVar(RPMVAR_FIXPERMS));
  357.     appendLineStringBuf(sb, " .");
  358.     }
  359.     
  360.     return 0;
  361. }
  362.  
  363. int isCompressed(char *file)
  364. {
  365.     int fd;
  366.     unsigned char magic[4];
  367.  
  368.     fd = open(file, O_RDONLY);
  369.     read(fd, magic, 4);
  370.     close(fd);
  371.  
  372.     if (((magic[0] == 0037) && (magic[1] == 0213)) ||  /* gzip */
  373.     ((magic[0] == 0037) && (magic[1] == 0236)) ||  /* old gzip */
  374.     ((magic[0] == 0037) && (magic[1] == 0036)) ||  /* pack */
  375.     ((magic[0] == 0037) && (magic[1] == 0240)) ||  /* SCO lzh */
  376.     ((magic[0] == 0037) && (magic[1] == 0235)) ||  /* compress */
  377.     ((magic[0] == 0120) && (magic[1] == 0113) &&
  378.      (magic[2] == 0003) && (magic[3] == 0004))     /* pkzip */
  379.     ) {
  380.     return 1;
  381.     }
  382.  
  383.     return 0;
  384. }
  385.  
  386. static char *do_untar(Spec spec, int c, int quietly)
  387. {
  388.     static char buf[1024];
  389.     char file[1024];
  390.     char *s, *taropts;
  391.     struct sources *sp;
  392.  
  393.     s = NULL;
  394.     sp = spec->sources;
  395.     while (sp) {
  396.     if ((sp->ispatch == 0) && (sp->num == c)) {
  397.         s = sp->source;
  398.         break;
  399.     }
  400.     sp = sp->next;
  401.     }
  402.     if (! s) {
  403.     rpmError(RPMERR_BADSPEC, "No source number %d", c);
  404.     return NULL;
  405.     }
  406.  
  407.     sprintf(file, "%s/%s", rpmGetVar(RPMVAR_SOURCEDIR), s);
  408.     taropts = (rpmIsVerbose() && !quietly ? "-xvvf" : "-xf");
  409.     
  410.     if (isCompressed(file)) {
  411.     sprintf(buf,
  412.         "%s -dc %s | tar %s -\n"
  413.         "if [ $? -ne 0 ]; then\n"
  414.         "  exit $?\n"
  415.         "fi",
  416.         rpmGetVar(RPMVAR_GZIPBIN), file, taropts);
  417.     } else {
  418.     sprintf(buf, "tar %s %s", taropts, file);
  419.     }
  420.  
  421.     return buf;
  422. }
  423.  
  424. static char *do_patch(Spec spec, int c, int strip, char *db,
  425.               int reverse, int removeEmpties)
  426. {
  427.     static char buf[1024];
  428.     char file[1024];
  429.     char args[1024];
  430.     char *s;
  431.     struct sources *sp;
  432.  
  433.     s = NULL;
  434.     sp = spec->sources;
  435.     while (sp) {
  436.     if ((sp->ispatch == 1) && (sp->num == c)) {
  437.         s = sp->source;
  438.         break;
  439.     }
  440.     sp = sp->next;
  441.     }
  442.     if (! s) {
  443.     rpmError(RPMERR_BADSPEC, "No patch number %d", c);
  444.     return NULL;
  445.     }
  446.  
  447.     sprintf(file, "%s/%s", rpmGetVar(RPMVAR_SOURCEDIR), s);
  448.  
  449.     args[0] = '\0';
  450.     if (db) {
  451.     strcat(args, "-b ");
  452.     strcat(args, db);
  453.     }
  454.     if (reverse) {
  455.     strcat(args, " -R");
  456.     }
  457.     if (removeEmpties) {
  458.     strcat(args, " -E");
  459.     }
  460.  
  461.     if (isCompressed(file)) {
  462.     sprintf(buf,
  463.         "echo \"Patch #%d:\"\n"
  464.         "%s -dc %s | patch -p%d %s -s\n"
  465.         "if [ $? -ne 0 ]; then\n"
  466.         "  exit $?\n"
  467.         "fi",
  468.         c, rpmGetVar(RPMVAR_GZIPBIN), file, strip, args);
  469.     } else {
  470.     sprintf(buf,
  471.         "echo \"Patch #%d:\"\n"
  472.         "patch -p%d %s -s < %s", c, strip, args, file);
  473.     }
  474.  
  475.     return buf;
  476. }
  477.  
  478. static int doPatchMacro(Spec spec, StringBuf sb, char *line)
  479. {
  480.     char *opt_b;
  481.     int opt_P, opt_p, opt_R, opt_E;
  482.     char *s, *s1;
  483.     char buf[1024];
  484.     int patch_nums[1024];  /* XXX - we can only handle 1024 patches! */
  485.     int patch_index, x;
  486.  
  487.     opt_P = opt_p = opt_R = opt_E = 0;
  488.     opt_b = NULL;
  489.     patch_index = 0;
  490.  
  491.     if (! strchr(" \t\n", line[6])) {
  492.     /* %patchN */
  493.     sprintf(buf, "%%patch -P %s", line + 6);
  494.     } else {
  495.     strcpy(buf, line);
  496.     }
  497.     
  498.     strtok(buf, " \t\n");  /* remove %patch */
  499.     while ((s = strtok(NULL, " \t\n"))) {
  500.     if (!strcmp(s, "-P")) {
  501.         opt_P = 1;
  502.     } else if (!strcmp(s, "-R")) {
  503.         opt_R = 1;
  504.     } else if (!strcmp(s, "-E")) {
  505.         opt_E = 1;
  506.     } else if (!strcmp(s, "-b")) {
  507.         /* orig suffix */
  508.         opt_b = strtok(NULL, " \t\n");
  509.         if (! opt_b) {
  510.         rpmError(RPMERR_BADSPEC, "Need arg to %%patch -b");
  511.         return(RPMERR_BADSPEC);
  512.         }
  513.     } else if (!strncmp(s, "-p", 2)) {
  514.         /* unfortunately, we must support -pX */
  515.         if (! strchr(" \t\n", s[2])) {
  516.         s = s + 2;
  517.         } else {
  518.         s = strtok(NULL, " \t\n");
  519.         if (! s) {
  520.             rpmError(RPMERR_BADSPEC, "Need arg to %%patch -p");
  521.             return(RPMERR_BADSPEC);
  522.         }
  523.         }
  524.         s1 = NULL;
  525.         opt_p = strtoul(s, &s1, 10);
  526.         if ((*s1) || (s1 == s) || (opt_p == ULONG_MAX)) {
  527.         rpmError(RPMERR_BADSPEC, "Bad arg to %%patch -p: %s", s);
  528.         return(RPMERR_BADSPEC);
  529.         }
  530.     } else {
  531.         /* Must be a patch num */
  532.         if (patch_index == 1024) {
  533.         rpmError(RPMERR_BADSPEC, "Too many patches!");
  534.         return(RPMERR_BADSPEC);
  535.         }
  536.         s1 = NULL;
  537.         patch_nums[patch_index] = strtoul(s, &s1, 10);
  538.         if ((*s1) || (s1 == s) || (patch_nums[patch_index] == ULONG_MAX)) {
  539.         rpmError(RPMERR_BADSPEC, "Bad arg to %%patch: %s", s);
  540.         return(RPMERR_BADSPEC);
  541.         }
  542.         patch_index++;
  543.     }
  544.     }
  545.  
  546.     /* All args processed */
  547.  
  548.     if (! opt_P) {
  549.     s = do_patch(spec, 0, opt_p, opt_b, opt_R, opt_E);
  550.     if (! s) {
  551.         return 1;
  552.     }
  553.     appendLineStringBuf(sb, s);
  554.     }
  555.  
  556.     x = 0;
  557.     while (x < patch_index) {
  558.     s = do_patch(spec, patch_nums[x], opt_p, opt_b, opt_R, opt_E);
  559.     if (! s) {
  560.         return 1;
  561.     }
  562.     appendLineStringBuf(sb, s);
  563.     x++;
  564.     }
  565.     
  566.     return 0;
  567. }
  568.  
  569. static int checkSources(Spec s)
  570. {
  571.     struct sources *source;
  572.     struct PackageRec *package;
  573.     char buf[1024];
  574.  
  575.     /* Check that we can access all the sources */
  576.     source = s->sources;
  577.     while (source) {
  578.     sprintf(buf, "%s/%s", rpmGetVar(RPMVAR_SOURCEDIR), source->source);
  579.     if (access(buf, R_OK)) {
  580.         rpmError(RPMERR_BADSPEC, "missing source or patch: %s", buf);
  581.         return RPMERR_BADSPEC;
  582.     }
  583.     source = source->next;
  584.     }
  585.  
  586.     /* ... and icons */
  587.     package = s->packages;
  588.     while (package) {
  589.     if (package->icon) {
  590.         sprintf(buf, "%s/%s", rpmGetVar(RPMVAR_SOURCEDIR), package->icon);
  591.         if (access(buf, R_OK)) {
  592.         rpmError(RPMERR_BADSPEC, "missing icon: %s", buf);
  593.         return RPMERR_BADSPEC;
  594.         }
  595.     }
  596.     package = package->next;
  597.     }
  598.     
  599.     return 0;
  600. }
  601.  
  602. int execPrep(Spec s, int really_exec, int test)
  603. {
  604.     char **lines, **lines1, *p;
  605.     StringBuf out;
  606.     int res;
  607.  
  608.     if (checkSources(s)) {
  609.     return 1;
  610.     }
  611.     out = newStringBuf();
  612.     
  613.     p = getStringBuf(s->prep);
  614.     lines = splitString(p, strlen(p), '\n');
  615.     lines1 = lines;
  616.     while (*lines) {
  617.     if (! strncmp(*lines, "%setup", 6)) {
  618.         if (doSetupMacro(s, out, *lines)) {
  619.         return 1;
  620.         }
  621.     } else if (! strncmp(*lines, "%patch", 6)) {
  622.         if (doPatchMacro(s, out, *lines)) {
  623.         return 1;
  624.         }
  625.     } else {
  626.         appendLineStringBuf(out, *lines);
  627.     }
  628.     lines++;
  629.     }
  630.  
  631.     freeSplitString(lines1);
  632.     res = 0;
  633.     if (really_exec) {
  634.     res = execPart(s, getStringBuf(out), "%prep", 0, test);
  635.     }
  636.     freeStringBuf(out);
  637.     return res;
  638. }
  639.  
  640. int execBuild(Spec s, int test)
  641. {
  642.     return execPart(s, getStringBuf(s->build), "%build", 1, test);
  643. }
  644.  
  645. int execInstall(Spec s, int test)
  646. {
  647.     int res;
  648.  
  649.     if ((res = execPart(s, getStringBuf(s->install), "%install", 1, test))) {
  650.     return res;
  651.     }
  652.     if ((res = finish_filelists(s))) {
  653.     return res;
  654.     }
  655.     return execPart(s, getStringBuf(s->doc), "special doc", 1, test);
  656. }
  657.  
  658. int execClean(Spec s)
  659. {
  660.     return execPart(s, getStringBuf(s->clean), "%clean", 1, 0);
  661. }
  662.  
  663. int verifyList(Spec s)
  664. {
  665.     int res;
  666.  
  667.     if ((res = finish_filelists(s))) {
  668.     return res;
  669.     }
  670.     return packageBinaries(s, NULL, PACK_NOPACKAGE);
  671. }
  672.  
  673. int doBuild(Spec s, int flags, char *passPhrase)
  674. {
  675.     int test;
  676.  
  677.     test = flags & RPMBUILD_TEST;
  678.  
  679.     strcpy(build_subdir, ".");
  680.  
  681.     if (s->buildArch) {
  682.     rpmSetMachine(s->buildArch, NULL);
  683.     }
  684.  
  685.     /* We always need to parse the %prep section */
  686.     if (execPrep(s, (flags & RPMBUILD_PREP), test)) {
  687.     return 1;
  688.     }
  689.  
  690.     if (flags & RPMBUILD_LIST)
  691.     return verifyList(s);
  692.  
  693.     if (flags & RPMBUILD_BUILD) {
  694.     if (execBuild(s, test)) {
  695.         return 1;
  696.     }
  697.     }
  698.  
  699.     if (flags & RPMBUILD_INSTALL) {
  700.     if (execInstall(s, test)) {
  701.         return 1;
  702.     }
  703.     }
  704.  
  705.     if (test) {
  706.     return 0;
  707.     }
  708.     
  709.     markBuildTime();
  710.     
  711.     if (flags & RPMBUILD_BINARY) {
  712.     if (packageBinaries(s, passPhrase, PACK_PACKAGE)) {
  713.         return 1;
  714.     }
  715.     if (execClean(s)) {
  716.         return 1;
  717.     }
  718.     }
  719.  
  720.     if (flags & RPMBUILD_SOURCE) {
  721.     if (packageSource(s, passPhrase)) {
  722.         return 1;
  723.     }
  724.     }
  725.  
  726.     if (flags & RPMBUILD_SWEEP) {
  727.     doSweep(s);
  728.     }
  729.  
  730.     if (flags & RPMBUILD_RMSOURCE) {
  731.     doRmSource(s);
  732.     }
  733.  
  734.     return 0;
  735. }
  736.