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