5 static int addTriggerIndex(Package pkg, char *file, char *script, char *prog)
7 struct TriggerFileEntry *new;
8 struct TriggerFileEntry *list = pkg->triggerFiles;
9 struct TriggerFileEntry *last = NULL;
18 index = last->index + 1;
21 new = malloc(sizeof(*new));
23 new->fileName = (file) ? strdup(file) : NULL;
24 new->script = (*script) ? strdup(script) : NULL;
25 new->prog = strdup(prog);
32 pkg->triggerFiles = new;
38 /* these have to be global because of stupid compilers */
42 static struct poptOption optionsTable[] = {
43 { NULL, 'p', POPT_ARG_STRING, &prog, 'p', NULL, NULL},
44 { NULL, 'n', POPT_ARG_STRING, &name, 'n', NULL, NULL},
45 { NULL, 'f', POPT_ARG_STRING, &file, 'f', NULL, NULL},
46 { 0, 0, 0, 0, 0, NULL, NULL}
49 /* %trigger is a strange combination of %pre and Requires: behavior */
50 /* We can handle it by parsing the args before "--" in parseScript. */
51 /* We then pass the remaining arguments to parseRCPOT, along with */
52 /* an index we just determined. */
54 int parseScript(Spec spec, int parsePart)
56 /* There are a few options to scripts: */
60 /* -p "<sh> <args>..." */
64 char **progArgv = NULL;
66 char *partname = NULL;
70 int flag = PART_SUBNAME;
80 poptContext optCon = NULL;
89 progtag = RPMTAG_PREINPROG;
94 progtag = RPMTAG_POSTINPROG;
99 progtag = RPMTAG_PREUNPROG;
104 progtag = RPMTAG_POSTUNPROG;
105 partname = "%postun";
107 case PART_VERIFYSCRIPT:
108 tag = RPMTAG_VERIFYSCRIPT;
109 progtag = RPMTAG_VERIFYSCRIPTPROG;
110 partname = "%verifyscript";
113 tag = RPMTAG_TRIGGERSCRIPTS;
114 reqtag = RPMTAG_TRIGGERIN;
115 progtag = RPMTAG_TRIGGERSCRIPTPROG;
116 partname = "%triggerin";
119 tag = RPMTAG_TRIGGERSCRIPTS;
120 reqtag = RPMTAG_TRIGGERUN;
121 progtag = RPMTAG_TRIGGERSCRIPTPROG;
122 partname = "%triggerun";
124 case PART_TRIGGERPOSTUN:
125 tag = RPMTAG_TRIGGERSCRIPTS;
126 reqtag = RPMTAG_TRIGGERPOSTUN;
127 progtag = RPMTAG_TRIGGERSCRIPTPROG;
128 partname = "%triggerpostun";
132 if (tag == RPMTAG_TRIGGERSCRIPTS) {
133 /* break line into two */
134 p = strstr(spec->line, "--");
136 rpmError(RPMERR_BADSPEC, _("line %d: triggers must have --: %s"),
137 spec->lineNum, spec->line);
138 return RPMERR_BADSPEC;
142 strcpy(reqargs, p + 2);
145 if ((rc = poptParseArgvString(spec->line, &argc, &argv))) {
146 rpmError(RPMERR_BADSPEC, _("line %d: Error parsing %s: %s"),
147 spec->lineNum, partname, poptStrerror(rc));
148 return RPMERR_BADSPEC;
151 optCon = poptGetContext(NULL, argc, argv, optionsTable, 0);
152 while ((arg = poptGetNextOpt(optCon)) > 0) {
154 if (prog[0] != '/') {
155 rpmError(RPMERR_BADSPEC,
156 _("line %d: script program must begin "
157 "with \'/\': %s"), spec->lineNum, prog);
159 poptFreeContext(optCon);
160 return RPMERR_BADSPEC;
162 } else if (arg == 'n') {
168 rpmError(RPMERR_BADSPEC, _("line %d: Bad option %s: %s"),
170 poptBadOption(optCon, POPT_BADOPTION_NOALIAS),
173 poptFreeContext(optCon);
174 return RPMERR_BADSPEC;
177 if (poptPeekArg(optCon)) {
179 name = poptGetArg(optCon);
181 if (poptPeekArg(optCon)) {
182 rpmError(RPMERR_BADSPEC, _("line %d: Too many names: %s"),
186 poptFreeContext(optCon);
187 return RPMERR_BADSPEC;
191 if (lookupPackage(spec, name, flag, &pkg)) {
192 rpmError(RPMERR_BADSPEC, _("line %d: Package does not exist: %s"),
193 spec->lineNum, spec->line);
195 poptFreeContext(optCon);
196 return RPMERR_BADSPEC;
199 if (tag != RPMTAG_TRIGGERSCRIPTS) {
200 if (headerIsEntry(pkg->header, progtag)) {
201 rpmError(RPMERR_BADSPEC, _("line %d: Second %s"),
202 spec->lineNum, partname);
204 poptFreeContext(optCon);
205 return RPMERR_BADSPEC;
209 if ((rc = poptParseArgvString(prog, &progArgc, &progArgv))) {
210 rpmError(RPMERR_BADSPEC, _("line %d: Error parsing %s: %s"),
211 spec->lineNum, partname, poptStrerror(rc));
213 poptFreeContext(optCon);
214 return RPMERR_BADSPEC;
218 if ((rc = readLine(spec, STRIP_NOTHING)) > 0) {
219 nextPart = PART_NONE;
224 while (! (nextPart = isPart(spec->line))) {
225 appendStringBuf(sb, spec->line);
226 if ((rc = readLine(spec, STRIP_NOTHING)) > 0) {
227 nextPart = PART_NONE;
235 stripTrailingBlanksStringBuf(sb);
236 p = getStringBuf(sb);
238 addReqProv(spec, pkg->header, RPMSENSE_PREREQ, prog, NULL, 0);
240 /* Trigger script insertion is always delayed in order to */
241 /* get the index right. */
242 if (tag == RPMTAG_TRIGGERSCRIPTS) {
243 /* Add file/index/prog triple to the trigger file list */
244 index = addTriggerIndex(pkg, file, p, prog);
246 /* Generate the trigger tags */
247 if ((rc = parseRCPOT(spec, pkg, reqargs, reqtag, index))) {
251 poptFreeContext(optCon);
255 headerAddEntry(pkg->header, progtag, RPM_STRING_TYPE, prog, 1);
257 headerAddEntry(pkg->header, tag, RPM_STRING_TYPE, p, 1);
262 pkg->preInFile = strdup(file);
265 pkg->postInFile = strdup(file);
268 pkg->preUnFile = strdup(file);
271 pkg->postUnFile = strdup(file);
273 case PART_VERIFYSCRIPT:
274 pkg->verifyFile = strdup(file);
283 poptFreeContext(optCon);