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