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