00001
00006 #include "system.h"
00007
00008 #include "rpmbuild.h"
00009 #include "buildio.h"
00010 #include "debug.h"
00011
00012
00013 extern int specedit;
00014
00015
00016 extern struct MacroContext_s rpmGlobalMacroContext;
00017
00018
00019 #define SKIPWHITE(_x) {while(*(_x) && (xisspace(*_x) || *(_x) == ',')) (_x)++;}
00020 #define SKIPNONWHITE(_x){while(*(_x) &&!(xisspace(*_x) || *(_x) == ',')) (_x)++;}
00021
00022
00023
00027 static inline
00028 struct TriggerFileEntry * freeTriggerFiles( struct TriggerFileEntry * p)
00029 {
00030 struct TriggerFileEntry *o, *q = p;
00031
00032 while (q != NULL) {
00033 o = q;
00034 q = q->next;
00035 o->fileName = _free(o->fileName);
00036 o->script = _free(o->script);
00037 o->prog = _free(o->prog);
00038 o = _free(o);
00039 }
00040 return NULL;
00041 }
00042
00048 static inline
00049 struct Source * freeSources( struct Source * s)
00050 {
00051 struct Source *r, *t = s;
00052
00053 while (t != NULL) {
00054 r = t;
00055 t = t->next;
00056 r->fullSource = _free(r->fullSource);
00057 r = _free(r);
00058 }
00059 return NULL;
00060 }
00061
00062 int lookupPackage(Spec spec, const char *name, int flag, Package *pkg)
00063 {
00064 const char *pname;
00065 const char *fullName;
00066 Package p;
00067
00068
00069 if (name == NULL) {
00070 if (pkg)
00071 *pkg = spec->packages;
00072 return 0;
00073 }
00074
00075
00076 { char *n;
00077 if (flag == PART_SUBNAME) {
00078 (void) headerNVR(spec->packages->header, &pname, NULL, NULL);
00079 fullName = n = alloca(strlen(pname) + 1 + strlen(name) + 1);
00080 while (*pname != '\0') *n++ = *pname++;
00081 *n++ = '-';
00082 } else {
00083 fullName = n = alloca(strlen(name)+1);
00084 }
00085
00086 strcpy(n, name);
00087
00088 }
00089
00090
00091 for (p = spec->packages; p != NULL; p = p->next) {
00092 (void) headerNVR(p->header, &pname, NULL, NULL);
00093 if (pname && (! strcmp(fullName, pname))) {
00094 break;
00095 }
00096 }
00097
00098 if (pkg)
00099 *pkg = p;
00100 return ((p == NULL) ? 1 : 0);
00101 }
00102
00103 Package newPackage(Spec spec)
00104 {
00105 Package p;
00106 Package pp;
00107
00108 p = xmalloc(sizeof(*p));
00109
00110 p->header = headerNew();
00111 p->icon = NULL;
00112
00113 p->autoProv = 1;
00114 p->autoReq = 1;
00115
00116 #if 0
00117 p->reqProv = NULL;
00118 p->triggers = NULL;
00119 p->triggerScripts = NULL;
00120 #endif
00121
00122 p->triggerFiles = NULL;
00123
00124 p->fileFile = NULL;
00125 p->fileList = NULL;
00126
00127 p->cpioList = NULL;
00128
00129 p->preInFile = NULL;
00130 p->postInFile = NULL;
00131 p->preUnFile = NULL;
00132 p->postUnFile = NULL;
00133 p->verifyFile = NULL;
00134
00135 p->specialDoc = NULL;
00136
00137 if (spec->packages == NULL) {
00138 spec->packages = p;
00139 } else {
00140
00141 for (pp = spec->packages; pp->next != NULL; pp = pp->next)
00142 {};
00143 pp->next = p;
00144 }
00145 p->next = NULL;
00146
00147 return p;
00148 }
00149
00150 Package freePackage(Package p)
00151 {
00152 if (p == NULL) return NULL;
00153
00154 p->preInFile = _free(p->preInFile);
00155 p->postInFile = _free(p->postInFile);
00156 p->preUnFile = _free(p->preUnFile);
00157 p->postUnFile = _free(p->postUnFile);
00158 p->verifyFile = _free(p->verifyFile);
00159
00160 p->header = headerFree(p->header);
00161 p->fileList = freeStringBuf(p->fileList);
00162 p->fileFile = _free(p->fileFile);
00163 if (p->cpioList) {
00164 TFI_t fi = p->cpioList;
00165 p->cpioList = NULL;
00166 freeFi(fi);
00167 fi = _free(fi);
00168 }
00169
00170 p->specialDoc = freeStringBuf(p->specialDoc);
00171 p->icon = freeSources(p->icon);
00172 p->triggerFiles = freeTriggerFiles(p->triggerFiles);
00173
00174 p = _free(p);
00175 return NULL;
00176 }
00177
00178 Package freePackages(Package packages)
00179 {
00180 Package p;
00181
00182 while ((p = packages) != NULL) {
00183 packages = p->next;
00184 p->next = NULL;
00185 p = freePackage(p);
00186 }
00187 return NULL;
00188 }
00189
00192 static inline struct Source *findSource(Spec spec, int num, int flag)
00193 {
00194 struct Source *p;
00195
00196 for (p = spec->sources; p != NULL; p = p->next)
00197 if ((num == p->num) && (p->flags & flag)) return p;
00198
00199 return NULL;
00200 }
00201
00202 int parseNoSource(Spec spec, const char * field, int tag)
00203 {
00204 const char *f, *fe;
00205 const char *name;
00206 int num, flag;
00207
00208 if (tag == RPMTAG_NOSOURCE) {
00209 flag = RPMBUILD_ISSOURCE;
00210 name = "source";
00211 } else {
00212 flag = RPMBUILD_ISPATCH;
00213 name = "patch";
00214 }
00215
00216 fe = field;
00217 for (f = fe; *f != '\0'; f = fe) {
00218 struct Source *p;
00219
00220 SKIPWHITE(f);
00221 if (*f == '\0')
00222 break;
00223 fe = f;
00224 SKIPNONWHITE(fe);
00225 if (*fe != '\0') fe++;
00226
00227 if (parseNum(f, &num)) {
00228 rpmError(RPMERR_BADSPEC, _("line %d: Bad number: %s\n"),
00229 spec->lineNum, f);
00230 return RPMERR_BADSPEC;
00231 }
00232
00233 if (! (p = findSource(spec, num, flag))) {
00234 rpmError(RPMERR_BADSPEC, _("line %d: Bad no%s number: %d\n"),
00235 spec->lineNum, name, num);
00236 return RPMERR_BADSPEC;
00237 }
00238
00239 p->flags |= RPMBUILD_ISNO;
00240
00241 }
00242
00243 return 0;
00244 }
00245
00246 int addSource(Spec spec, Package pkg, const char *field, int tag)
00247 {
00248 struct Source *p;
00249 int flag = 0;
00250 char *name = NULL;
00251 char *nump;
00252 const char *fieldp = NULL;
00253 char buf[BUFSIZ];
00254 int num = 0;
00255
00256 buf[0] = '\0';
00257 switch (tag) {
00258 case RPMTAG_SOURCE:
00259 flag = RPMBUILD_ISSOURCE;
00260 name = "source";
00261 fieldp = spec->line + 6;
00262 break;
00263 case RPMTAG_PATCH:
00264 flag = RPMBUILD_ISPATCH;
00265 name = "patch";
00266 fieldp = spec->line + 5;
00267 break;
00268 case RPMTAG_ICON:
00269 flag = RPMBUILD_ISICON;
00270 fieldp = NULL;
00271 break;
00272 }
00273
00274
00275 if (tag != RPMTAG_ICON) {
00276
00277
00278
00279
00280
00281 nump = buf;
00282 while ((*fieldp != ':') && (*fieldp != ' ') && (*fieldp != '\t')) {
00283 *nump++ = *fieldp++;
00284 }
00285 *nump = '\0';
00286
00287 nump = buf;
00288 SKIPSPACE(nump);
00289 if (nump == NULL || *nump == '\0') {
00290 num = 0;
00291 } else {
00292 if (parseNum(buf, &num)) {
00293 rpmError(RPMERR_BADSPEC, _("line %d: Bad %s number: %s\n"),
00294 spec->lineNum, name, spec->line);
00295 return RPMERR_BADSPEC;
00296 }
00297 }
00298 }
00299
00300
00301 p = xmalloc(sizeof(struct Source));
00302 p->num = num;
00303 p->fullSource = xstrdup(field);
00304 p->flags = flag;
00305 p->source = strrchr(p->fullSource, '/');
00306 if (p->source) {
00307 p->source++;
00308 } else {
00309 p->source = p->fullSource;
00310 }
00311
00312 if (tag != RPMTAG_ICON) {
00313 p->next = spec->sources;
00314 spec->sources = p;
00315 } else {
00316 p->next = pkg->icon;
00317 pkg->icon = p;
00318 }
00319
00320 spec->numSources++;
00321
00322 if (tag != RPMTAG_ICON) {
00323
00324 const char *body = rpmGetPath("%{_sourcedir}/", p->source, NULL);
00325
00326
00327 sprintf(buf, "%s%d",
00328 (flag & RPMBUILD_ISPATCH) ? "PATCH" : "SOURCE", num);
00329 addMacro(spec->macros, buf, NULL, body, RMIL_SPEC);
00330 sprintf(buf, "%sURL%d",
00331 (flag & RPMBUILD_ISPATCH) ? "PATCH" : "SOURCE", num);
00332 addMacro(spec->macros, buf, NULL, p->fullSource, RMIL_SPEC);
00333 body = _free(body);
00334 }
00335
00336 return 0;
00337 }
00338
00341 static inline speclines newSl(void)
00342 {
00343 speclines sl = NULL;
00344 if (specedit) {
00345 sl = xmalloc(sizeof(*sl));
00346 sl->sl_lines = NULL;
00347 sl->sl_nalloc = 0;
00348 sl->sl_nlines = 0;
00349 }
00350 return sl;
00351 }
00352
00355 static inline speclines freeSl( speclines sl)
00356 {
00357 int i;
00358 if (sl == NULL) return NULL;
00359 for (i = 0; i < sl->sl_nlines; i++)
00360
00361 sl->sl_lines[i] = _free(sl->sl_lines[i]);
00362
00363 sl->sl_lines = _free(sl->sl_lines);
00364 return _free(sl);
00365 }
00366
00369 static inline spectags newSt(void)
00370 {
00371 spectags st = NULL;
00372 if (specedit) {
00373 st = xmalloc(sizeof(*st));
00374 st->st_t = NULL;
00375 st->st_nalloc = 0;
00376 st->st_ntags = 0;
00377 }
00378 return st;
00379 }
00380
00383 static inline spectags freeSt( spectags st)
00384 {
00385 int i;
00386 if (st == NULL) return NULL;
00387 for (i = 0; i < st->st_ntags; i++) {
00388 spectag t = st->st_t + i;
00389 t->t_lang = _free(t->t_lang);
00390 t->t_msgid = _free(t->t_msgid);
00391 }
00392 st->st_t = _free(st->st_t);
00393 return _free(st);
00394 }
00395
00396 Spec newSpec(void)
00397 {
00398 Spec spec = xcalloc(1, sizeof(*spec));
00399
00400 spec->specFile = NULL;
00401 spec->sourceRpmName = NULL;
00402
00403 spec->sl = newSl();
00404 spec->st = newSt();
00405
00406 spec->fileStack = NULL;
00407 spec->lbuf[0] = '\0';
00408 spec->line = spec->lbuf;
00409 spec->nextline = NULL;
00410 spec->nextpeekc = '\0';
00411 spec->lineNum = 0;
00412 spec->readStack = xcalloc(1, sizeof(*spec->readStack));
00413 spec->readStack->next = NULL;
00414 spec->readStack->reading = 1;
00415
00416 spec->rootURL = NULL;
00417 spec->prep = NULL;
00418 spec->build = NULL;
00419 spec->install = NULL;
00420 spec->clean = NULL;
00421
00422 spec->sources = NULL;
00423 spec->packages = NULL;
00424 spec->noSource = 0;
00425 spec->numSources = 0;
00426
00427 spec->sourceHeader = NULL;
00428
00429 spec->sourceCpioList = NULL;
00430
00431 spec->gotBuildRootURL = 0;
00432 spec->buildRootURL = NULL;
00433 spec->buildSubdir = NULL;
00434
00435 spec->passPhrase = NULL;
00436 spec->timeCheck = 0;
00437 spec->cookie = NULL;
00438
00439 spec->buildRestrictions = headerNew();
00440 spec->BANames = NULL;
00441 spec->BACount = 0;
00442 spec->recursing = 0;
00443 spec->BASpecs = NULL;
00444
00445 spec->force = 0;
00446 spec->anyarch = 0;
00447
00448 spec->macros = &rpmGlobalMacroContext;
00449
00450 return spec;
00451 }
00452
00453 Spec freeSpec(Spec spec)
00454 {
00455 struct ReadLevelEntry *rl;
00456
00457 if (spec == NULL) return NULL;
00458
00459 spec->sl = freeSl(spec->sl);
00460 spec->st = freeSt(spec->st);
00461
00462 spec->prep = freeStringBuf(spec->prep);
00463 spec->build = freeStringBuf(spec->build);
00464 spec->install = freeStringBuf(spec->install);
00465 spec->clean = freeStringBuf(spec->clean);
00466
00467 spec->buildRootURL = _free(spec->buildRootURL);
00468 spec->buildSubdir = _free(spec->buildSubdir);
00469 spec->rootURL = _free(spec->rootURL);
00470 spec->specFile = _free(spec->specFile);
00471 spec->sourceRpmName = _free(spec->sourceRpmName);
00472
00473 #ifdef DEAD
00474 { struct OpenFileInfo *ofi;
00475 while (spec->fileStack) {
00476 ofi = spec->fileStack;
00477 spec->fileStack = ofi->next;
00478 ofi->next = NULL;
00479 ofi->fileName = _free(ofi->fileName);
00480 ofi = _free(ofi);
00481 }
00482 }
00483 #else
00484 closeSpec(spec);
00485 #endif
00486
00487 while (spec->readStack) {
00488 rl = spec->readStack;
00489
00490 spec->readStack = rl->next;
00491
00492 rl->next = NULL;
00493 rl = _free(rl);
00494 }
00495
00496 spec->sourceHeader = headerFree(spec->sourceHeader);
00497
00498 if (spec->sourceCpioList) {
00499 TFI_t fi = spec->sourceCpioList;
00500 spec->sourceCpioList = NULL;
00501 freeFi(fi);
00502 fi = _free(fi);
00503 }
00504
00505 spec->buildRestrictions = headerFree(spec->buildRestrictions);
00506
00507 if (!spec->recursing) {
00508 if (spec->BASpecs != NULL)
00509 while (spec->BACount--) {
00510
00511 spec->BASpecs[spec->BACount] =
00512 freeSpec(spec->BASpecs[spec->BACount]);
00513
00514 }
00515
00516 spec->BASpecs = _free(spec->BASpecs);
00517
00518 }
00519 spec->BANames = _free(spec->BANames);
00520
00521 spec->passPhrase = _free(spec->passPhrase);
00522 spec->cookie = _free(spec->cookie);
00523
00524 spec->sources = freeSources(spec->sources);
00525 spec->packages = freePackages(spec->packages);
00526
00527 spec = _free(spec);
00528
00529 return spec;
00530 }
00531
00532 struct OpenFileInfo * newOpenFileInfo(void)
00533 {
00534 struct OpenFileInfo *ofi;
00535
00536 ofi = xmalloc(sizeof(struct OpenFileInfo));
00537 ofi->fd = NULL;
00538 ofi->fileName = NULL;
00539 ofi->lineNum = 0;
00540 ofi->readBuf[0] = '\0';
00541 ofi->readPtr = NULL;
00542 ofi->next = NULL;
00543
00544 return ofi;
00545 }