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
00020 static inline void freeTriggerFiles( struct TriggerFileEntry *p)
00021 {
00022 struct TriggerFileEntry *o, *q = p;
00023
00024 while (q != NULL) {
00025 o = q;
00026 q = q->next;
00027 FREE(o->fileName);
00028 FREE(o->script);
00029 FREE(o->prog);
00030 free(o);
00031 }
00032 }
00033
00036 static inline void freeCpioList( struct cpioFileMapping *cpioList, int cpioCount)
00037 {
00038 struct cpioFileMapping *p = cpioList;
00039
00040 while (cpioCount--) {
00041 rpmMessage(RPMMESS_DEBUG, _("archive = %s, fs = %s\n"),
00042 p->archivePath, p->fsPath);
00043 FREE(p->archivePath);
00044 FREE(p->fsPath);
00045 p++;
00046 }
00047 FREE(cpioList);
00048 }
00049
00052 static inline void freeSources( struct Source *s)
00053 {
00054 struct Source *r, *t = s;
00055
00056 while (t != NULL) {
00057 r = t;
00058 t = t->next;
00059 FREE(r->fullSource);
00060 free(r);
00061 }
00062 }
00063
00064 int lookupPackage(Spec spec, const char *name, int flag, Package *pkg)
00065 {
00066 const char *pname;
00067 const char *fullName;
00068 Package p;
00069
00070
00071 if (name == NULL) {
00072 if (pkg)
00073 *pkg = spec->packages;
00074 return 0;
00075 }
00076
00077
00078 { char *n;
00079 if (flag == PART_SUBNAME) {
00080 headerNVR(spec->packages->header, &pname, NULL, NULL);
00081 fullName = n = alloca(strlen(pname) + 1 + strlen(name) + 1);
00082 while (*pname) *n++ = *pname++;
00083 *n++ = '-';
00084 } else {
00085 fullName = n = alloca(strlen(name)+1);
00086 }
00087 strcpy(n, name);
00088 }
00089
00090
00091 for (p = spec->packages; p != NULL; p = p->next) {
00092 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 p->cpioCount = 0;
00129
00130 p->preInFile = NULL;
00131 p->postInFile = NULL;
00132 p->preUnFile = NULL;
00133 p->postUnFile = NULL;
00134 p->verifyFile = NULL;
00135
00136 p->specialDoc = NULL;
00137
00138 if (spec->packages == NULL) {
00139 spec->packages = p;
00140 } else {
00141
00142 for (pp = spec->packages; pp->next != NULL; pp = pp->next)
00143 ;
00144 pp->next = p;
00145 }
00146 p->next = NULL;
00147
00148 return p;
00149 }
00150
00151 void freePackage( Package p)
00152 {
00153 if (p == NULL)
00154 return;
00155
00156 FREE(p->preInFile);
00157 FREE(p->postInFile);
00158 FREE(p->preUnFile);
00159 FREE(p->postUnFile);
00160 FREE(p->verifyFile);
00161
00162 headerFree(p->header);
00163 freeStringBuf(p->fileList);
00164 FREE(p->fileFile);
00165 freeCpioList(p->cpioList, p->cpioCount);
00166
00167 freeStringBuf(p->specialDoc);
00168
00169 freeSources(p->icon);
00170
00171 freeTriggerFiles(p->triggerFiles);
00172
00173 free(p);
00174 }
00175
00176 void freePackages(Spec spec)
00177 {
00178 Package p;
00179
00180 while ((p = spec->packages) != NULL) {
00181 spec->packages = p->next;
00182 p->next = NULL;
00183 freePackage(p);
00184 }
00185 }
00186
00189 static inline struct Source *findSource(Spec spec, int num, int flag)
00190 {
00191 struct Source *p;
00192
00193 for (p = spec->sources; p != NULL; p = p->next) {
00194 if ((num == p->num) && (p->flags & flag)) {
00195 return p;
00196 }
00197 }
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; 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) 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 switch (tag) {
00257 case RPMTAG_SOURCE:
00258 flag = RPMBUILD_ISSOURCE;
00259 name = "source";
00260 fieldp = spec->line + 6;
00261 break;
00262 case RPMTAG_PATCH:
00263 flag = RPMBUILD_ISPATCH;
00264 name = "patch";
00265 fieldp = spec->line + 5;
00266 break;
00267 case RPMTAG_ICON:
00268 flag = RPMBUILD_ISICON;
00269 fieldp = NULL;
00270 break;
00271 }
00272
00273
00274 if (tag != RPMTAG_ICON) {
00275
00276
00277
00278
00279
00280 nump = buf;
00281 while ((*fieldp != ':') && (*fieldp != ' ') && (*fieldp != '\t')) {
00282 *nump++ = *fieldp++;
00283 }
00284 *nump = '\0';
00285
00286 nump = buf;
00287 SKIPSPACE(nump);
00288 if (! *nump) {
00289 num = 0;
00290 } else {
00291 if (parseNum(buf, &num)) {
00292 rpmError(RPMERR_BADSPEC, _("line %d: Bad %s number: %s\n"),
00293 spec->lineNum, name, spec->line);
00294 return RPMERR_BADSPEC;
00295 }
00296 }
00297 }
00298
00299
00300 p = xmalloc(sizeof(struct Source));
00301 p->num = num;
00302 p->fullSource = xstrdup(field);
00303 p->source = strrchr(p->fullSource, '/');
00304 p->flags = flag;
00305 if (p->source) {
00306 p->source++;
00307 } else {
00308 p->source = p->fullSource;
00309 }
00310
00311 if (tag != RPMTAG_ICON) {
00312 p->next = spec->sources;
00313 spec->sources = p;
00314 } else {
00315 p->next = pkg->icon;
00316 pkg->icon = p;
00317 }
00318
00319 spec->numSources++;
00320
00321 if (tag != RPMTAG_ICON) {
00322 const char *body = rpmGetPath("%{_sourcedir}/", p->source, NULL);
00323
00324 sprintf(buf, "%s%d",
00325 (flag & RPMBUILD_ISPATCH) ? "PATCH" : "SOURCE", num);
00326 addMacro(spec->macros, buf, NULL, body, RMIL_SPEC);
00327 sprintf(buf, "%sURL%d",
00328 (flag & RPMBUILD_ISPATCH) ? "PATCH" : "SOURCE", num);
00329 addMacro(spec->macros, buf, NULL, p->fullSource, RMIL_SPEC);
00330 free((void *)body);
00331 }
00332
00333 return 0;
00334 }
00335
00338 static inline struct speclines * newSl(void)
00339 {
00340 struct speclines *sl = NULL;
00341 if (specedit) {
00342 sl = xmalloc(sizeof(struct speclines));
00343 sl->sl_lines = NULL;
00344 sl->sl_nalloc = 0;
00345 sl->sl_nlines = 0;
00346 }
00347 return sl;
00348 }
00349
00352 static inline void freeSl(struct speclines *sl)
00353 {
00354 int i;
00355 if (sl == NULL)
00356 return;
00357 for (i = 0; i < sl->sl_nlines; i++)
00358 FREE(sl->sl_lines[i]);
00359 FREE(sl->sl_lines);
00360 free(sl);
00361 }
00362
00365 static inline struct spectags * newSt(void)
00366 {
00367 struct spectags *st = NULL;
00368 if (specedit) {
00369 st = xmalloc(sizeof(struct spectags));
00370 st->st_t = NULL;
00371 st->st_nalloc = 0;
00372 st->st_ntags = 0;
00373 }
00374 return st;
00375 }
00376
00379 static inline void freeSt(struct spectags *st)
00380 {
00381 int i;
00382 if (st == NULL)
00383 return;
00384 for (i = 0; i < st->st_ntags; i++) {
00385 struct spectag *t = st->st_t + i;
00386 FREE(t->t_lang);
00387 FREE(t->t_msgid);
00388 }
00389 FREE(st->st_t);
00390 free(st);
00391 }
00392
00393 Spec newSpec(void)
00394 {
00395 Spec spec;
00396
00397 spec = (Spec)xmalloc(sizeof *spec);
00398
00399 spec->specFile = NULL;
00400 spec->sourceRpmName = NULL;
00401
00402 spec->sl = newSl();
00403 spec->st = newSt();
00404
00405 spec->fileStack = NULL;
00406 spec->lbuf[0] = '\0';
00407 spec->line = spec->lbuf;
00408 spec->nextline = NULL;
00409 spec->nextpeekc = '\0';
00410 spec->lineNum = 0;
00411 spec->readStack = xmalloc(sizeof(struct ReadLevelEntry));
00412 spec->readStack->next = NULL;
00413 spec->readStack->reading = 1;
00414
00415 spec->rootURL = NULL;
00416 spec->prep = NULL;
00417 spec->build = NULL;
00418 spec->install = NULL;
00419 spec->clean = NULL;
00420
00421 spec->sources = NULL;
00422 spec->packages = NULL;
00423 spec->noSource = 0;
00424 spec->numSources = 0;
00425
00426 spec->sourceHeader = NULL;
00427
00428 spec->sourceCpioCount = 0;
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->buildArchitectures = NULL;
00441 spec->buildArchitectureCount = 0;
00442 spec->inBuildArchitectures = 0;
00443 spec->buildArchitectureSpecs = NULL;
00444
00445 spec->force = 0;
00446 spec->anyarch = 0;
00447
00448 spec->macros = &rpmGlobalMacroContext;
00449
00450 return spec;
00451 }
00452
00453 void freeSpec( Spec spec)
00454 {
00455 struct OpenFileInfo *ofi;
00456 struct ReadLevelEntry *rl;
00457
00458 freeSl(spec->sl); spec->sl = NULL;
00459 freeSt(spec->st); spec->st = NULL;
00460
00461 freeStringBuf(spec->prep); spec->prep = NULL;
00462 freeStringBuf(spec->build); spec->build = NULL;
00463 freeStringBuf(spec->install); spec->install = NULL;
00464 freeStringBuf(spec->clean); spec->clean = NULL;
00465
00466 FREE(spec->buildRootURL);
00467 FREE(spec->buildSubdir);
00468 FREE(spec->rootURL);
00469 FREE(spec->specFile);
00470 FREE(spec->sourceRpmName);
00471
00472 while (spec->fileStack) {
00473 ofi = spec->fileStack;
00474 spec->fileStack = spec->fileStack->next;
00475 ofi->next = NULL;
00476 FREE(ofi->fileName);
00477 free(ofi);
00478 }
00479
00480 while (spec->readStack) {
00481 rl = spec->readStack;
00482 spec->readStack = spec->readStack->next;
00483 rl->next = NULL;
00484 free(rl);
00485 }
00486
00487 if (spec->sourceHeader != NULL) {
00488 headerFree(spec->sourceHeader);
00489 spec->sourceHeader = NULL;
00490 }
00491
00492 freeCpioList(spec->sourceCpioList, spec->sourceCpioCount);
00493 spec->sourceCpioList = NULL;
00494
00495 headerFree(spec->buildRestrictions);
00496 spec->buildRestrictions = NULL;
00497
00498 if (!spec->inBuildArchitectures) {
00499 while (spec->buildArchitectureCount--) {
00500 freeSpec(
00501 spec->buildArchitectureSpecs[spec->buildArchitectureCount]);
00502 }
00503 FREE(spec->buildArchitectureSpecs);
00504 }
00505 FREE(spec->buildArchitectures);
00506
00507 FREE(spec->passPhrase);
00508 FREE(spec->cookie);
00509
00510 freeSources(spec->sources); spec->sources = NULL;
00511 freePackages(spec);
00512 closeSpec(spec);
00513
00514 free(spec);
00515 }
00516
00517 struct OpenFileInfo * newOpenFileInfo(void)
00518 {
00519 struct OpenFileInfo *ofi;
00520
00521 ofi = xmalloc(sizeof(struct OpenFileInfo));
00522 ofi->fd = NULL;
00523 ofi->fileName = NULL;
00524 ofi->lineNum = 0;
00525 ofi->readBuf[0] = '\0';
00526 ofi->readPtr = NULL;
00527 ofi->next = NULL;
00528
00529 return ofi;
00530 }