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