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
00047 static const char *name = NULL;
00048 static const char *prog = NULL;
00049 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
00058
00059
00060
00061
00062 int parseScript(Spec spec, int parsePart)
00063 {
00064
00065
00066
00067
00068
00069
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
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
00252
00253 if (tag == RPMTAG_TRIGGERSCRIPTS) {
00254
00255 index = addTriggerIndex(pkg, file, p, progArgv[0]);
00256
00257
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 }