Main Page   Modules   Compound List   File List   Compound Members   File Members   Related Pages  

build/parseScript.c

Go to the documentation of this file.
00001 
00006 #include "system.h"
00007 
00008 #include "rpmbuild.h"
00009 #include "debug.h"
00010 
00013 static int addTriggerIndex(Package pkg, const char *file, const char *script, const char *prog)
00014 {
00015     struct TriggerFileEntry *new;
00016     struct TriggerFileEntry *list = pkg->triggerFiles;
00017     struct TriggerFileEntry *last = NULL;
00018     int index = 0;
00019 
00020     while (list) {
00021         last = list;
00022         list = list->next;
00023     }
00024 
00025     if (last) {
00026         index = last->index + 1;
00027     }
00028 
00029     new = xmalloc(sizeof(*new));
00030 
00031     new->fileName = (file) ? xstrdup(file) : NULL;
00032     new->script = (*script) ? xstrdup(script) : NULL;
00033     new->prog = xstrdup(prog);
00034     new->index = index;
00035     new->next = NULL;
00036 
00037     if (last) {
00038         last->next = new;
00039     } else {
00040         pkg->triggerFiles = new;
00041     }
00042 
00043     return index;
00044 }
00045 
00046 /* these have to be global because of stupid compilers */
00047     /*@observer@*/ /*@null@*/ static const char *name = NULL;
00048     /*@observer@*/ /*@null@*/ static const char *prog = NULL;
00049     /*@observer@*/ /*@null@*/ static const char *file = NULL;
00050     static struct poptOption optionsTable[] = {
00051         { NULL, 'p', POPT_ARG_STRING, &prog, 'p',       NULL, NULL},
00052         { NULL, 'n', POPT_ARG_STRING, &name, 'n',       NULL, NULL},
00053         { NULL, 'f', POPT_ARG_STRING, &file, 'f',       NULL, NULL},
00054         { 0, 0, 0, 0, 0,        NULL, NULL}
00055     };
00056 
00057 /* %trigger is a strange combination of %pre and Requires: behavior */
00058 /* We can handle it by parsing the args before "--" in parseScript. */
00059 /* We then pass the remaining arguments to parseRCPOT, along with   */
00060 /* an index we just determined.                                     */
00061 
00062 int parseScript(Spec spec, int parsePart)
00063 {
00064     /* There are a few options to scripts: */
00065     /*  <pkg>                              */
00066     /*  -n <pkg>                           */
00067     /*  -p <sh>                            */
00068     /*  -p "<sh> <args>..."                */
00069     /*  -f <file>                          */
00070 
00071     char *p;
00072     const char **progArgv = NULL;
00073     int progArgc;
00074     char *partname = NULL;
00075     int reqtag = 0;
00076     int tag = 0;
00077     int tagflags = 0;
00078     int progtag = 0;
00079     int flag = PART_SUBNAME;
00080     Package pkg;
00081     StringBuf sb = NULL;
00082     int nextPart;
00083     int index;
00084     char reqargs[BUFSIZ];
00085 
00086     int rc, argc;
00087     int arg;
00088     const char **argv = NULL;
00089     poptContext optCon = NULL;
00090     
00091     name = NULL;
00092     prog = "/bin/sh";
00093     file = NULL;
00094     
00095     switch (parsePart) {
00096       case PART_PRE:
00097         tag = RPMTAG_PREIN;
00098         tagflags = RPMSENSE_SCRIPT_PRE;
00099         progtag = RPMTAG_PREINPROG;
00100         partname = "%pre";
00101         break;
00102       case PART_POST:
00103         tag = RPMTAG_POSTIN;
00104         tagflags = RPMSENSE_SCRIPT_POST;
00105         progtag = RPMTAG_POSTINPROG;
00106         partname = "%post";
00107         break;
00108       case PART_PREUN:
00109         tag = RPMTAG_PREUN;
00110         tagflags = RPMSENSE_SCRIPT_PREUN;
00111         progtag = RPMTAG_PREUNPROG;
00112         partname = "%preun";
00113         break;
00114       case PART_POSTUN:
00115         tag = RPMTAG_POSTUN;
00116         tagflags = RPMSENSE_SCRIPT_POSTUN;
00117         progtag = RPMTAG_POSTUNPROG;
00118         partname = "%postun";
00119         break;
00120       case PART_VERIFYSCRIPT:
00121         tag = RPMTAG_VERIFYSCRIPT;
00122         tagflags = RPMSENSE_SCRIPT_VERIFY;
00123         progtag = RPMTAG_VERIFYSCRIPTPROG;
00124         partname = "%verifyscript";
00125         break;
00126       case PART_TRIGGERIN:
00127         tag = RPMTAG_TRIGGERSCRIPTS;
00128         tagflags = 0;
00129         reqtag = RPMTAG_TRIGGERIN;
00130         progtag = RPMTAG_TRIGGERSCRIPTPROG;
00131         partname = "%triggerin";
00132         break;
00133       case PART_TRIGGERUN:
00134         tag = RPMTAG_TRIGGERSCRIPTS;
00135         tagflags = 0;
00136         reqtag = RPMTAG_TRIGGERUN;
00137         progtag = RPMTAG_TRIGGERSCRIPTPROG;
00138         partname = "%triggerun";
00139         break;
00140       case PART_TRIGGERPOSTUN:
00141         tag = RPMTAG_TRIGGERSCRIPTS;
00142         tagflags = 0;
00143         reqtag = RPMTAG_TRIGGERPOSTUN;
00144         progtag = RPMTAG_TRIGGERSCRIPTPROG;
00145         partname = "%triggerpostun";
00146         break;
00147     }
00148 
00149     if (tag == RPMTAG_TRIGGERSCRIPTS) {
00150         /* break line into two */
00151         p = strstr(spec->line, "--");
00152         if (!p) {
00153             rpmError(RPMERR_BADSPEC, _("line %d: triggers must have --: %s\n"),
00154                      spec->lineNum, spec->line);
00155             return RPMERR_BADSPEC;
00156         }
00157 
00158         *p = '\0';
00159         strcpy(reqargs, p + 2);
00160     }
00161     
00162     if ((rc = poptParseArgvString(spec->line, &argc, &argv))) {
00163         rpmError(RPMERR_BADSPEC, _("line %d: Error parsing %s: %s\n"),
00164                  spec->lineNum, partname, poptStrerror(rc));
00165         return RPMERR_BADSPEC;
00166     }
00167     
00168     optCon = poptGetContext(NULL, argc, argv, optionsTable, 0);
00169     while ((arg = poptGetNextOpt(optCon)) > 0) {
00170         switch (arg) {
00171         case 'p':
00172             if (prog[0] != '/') {
00173                 rpmError(RPMERR_BADSPEC,
00174                          _("line %d: script program must begin "
00175                          "with \'/\': %s\n"), spec->lineNum, prog);
00176                 rc = RPMERR_BADSPEC;
00177                 goto exit;
00178             }
00179             break;
00180         case 'n':
00181             flag = PART_NAME;
00182             break;
00183         }
00184     }
00185     
00186     if (arg < -1) {
00187         rpmError(RPMERR_BADSPEC, _("line %d: Bad option %s: %s\n"),
00188                  spec->lineNum,
00189                  poptBadOption(optCon, POPT_BADOPTION_NOALIAS), 
00190                  spec->line);
00191         rc = RPMERR_BADSPEC;
00192         goto exit;
00193     }
00194 
00195     if (poptPeekArg(optCon)) {
00196         if (name == NULL)
00197             name = poptGetArg(optCon);
00198         if (poptPeekArg(optCon)) {
00199             rpmError(RPMERR_BADSPEC, _("line %d: Too many names: %s\n"),
00200                      spec->lineNum,
00201                      spec->line);
00202             rc = RPMERR_BADSPEC;
00203             goto exit;
00204         }
00205     }
00206     
00207     if (lookupPackage(spec, name, flag, &pkg)) {
00208         rpmError(RPMERR_BADSPEC, _("line %d: Package does not exist: %s\n"),
00209                  spec->lineNum, spec->line);
00210         rc = RPMERR_BADSPEC;
00211         goto exit;
00212     }
00213 
00214     if (tag != RPMTAG_TRIGGERSCRIPTS) {
00215         if (headerIsEntry(pkg->header, progtag)) {
00216             rpmError(RPMERR_BADSPEC, _("line %d: Second %s\n"),
00217                      spec->lineNum, partname);
00218             rc = RPMERR_BADSPEC;
00219             goto exit;
00220         }
00221     }
00222 
00223     if ((rc = poptParseArgvString(prog, &progArgc, &progArgv))) {
00224         rpmError(RPMERR_BADSPEC, _("line %d: Error parsing %s: %s\n"),
00225                  spec->lineNum, partname, poptStrerror(rc));
00226         rc = RPMERR_BADSPEC;
00227         goto exit;
00228     }
00229 
00230     sb = newStringBuf();
00231     if ((rc = readLine(spec, STRIP_NOTHING)) > 0) {
00232         nextPart = PART_NONE;
00233     } else {
00234         if (rc)
00235             goto exit;
00236         while (! (nextPart = isPart(spec->line))) {
00237             appendStringBuf(sb, spec->line);
00238             if ((rc = readLine(spec, STRIP_NOTHING)) > 0) {
00239                 nextPart = PART_NONE;
00240                 break;
00241             }
00242             if (rc)
00243                 goto exit;
00244         }
00245     }
00246     stripTrailingBlanksStringBuf(sb);
00247     p = getStringBuf(sb);
00248 
00249     addReqProv(spec, pkg->header, (tagflags | RPMSENSE_INTERP), progArgv[0], NULL, 0);
00250 
00251     /* Trigger script insertion is always delayed in order to */
00252     /* get the index right.                                   */
00253     if (tag == RPMTAG_TRIGGERSCRIPTS) {
00254         /* Add file/index/prog triple to the trigger file list */
00255         index = addTriggerIndex(pkg, file, p, progArgv[0]);
00256 
00257         /* Generate the trigger tags */
00258         if ((rc = parseRCPOT(spec, pkg, reqargs, reqtag, index, tagflags)))
00259             goto exit;
00260     } else {
00261         if (progArgc == 1)
00262             headerAddEntry(pkg->header, progtag, RPM_STRING_TYPE,
00263                         *progArgv, progArgc);
00264         else
00265             headerAddEntry(pkg->header, progtag, RPM_STRING_ARRAY_TYPE,
00266                         progArgv, progArgc);
00267 
00268         if (*p)
00269             headerAddEntry(pkg->header, tag, RPM_STRING_TYPE, p, 1);
00270 
00271         if (file) {
00272             switch (parsePart) {
00273               case PART_PRE:
00274                 pkg->preInFile = xstrdup(file);
00275                 break;
00276               case PART_POST:
00277                 pkg->postInFile = xstrdup(file);
00278                 break;
00279               case PART_PREUN:
00280                 pkg->preUnFile = xstrdup(file);
00281                 break;
00282               case PART_POSTUN:
00283                 pkg->postUnFile = xstrdup(file);
00284                 break;
00285               case PART_VERIFYSCRIPT:
00286                 pkg->verifyFile = xstrdup(file);
00287                 break;
00288             }
00289         }
00290     }
00291     rc = nextPart;
00292     
00293 exit:
00294     if (sb)
00295         freeStringBuf(sb);
00296     if (progArgv) {
00297         FREE(progArgv);
00298     }
00299     if (argv) {
00300         FREE(argv);
00301     }
00302     if (optCon)
00303         poptFreeContext(optCon);
00304     
00305     return rc;
00306 }

Generated at Mon May 21 08:53:38 2001 for rpm by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001