00001
00006 #include "system.h"
00007
00008 #include "buildio.h"
00009 #include "rpmds.h"
00010 #include "rpmfi.h"
00011 #include "rpmts.h"
00012
00013 #include "debug.h"
00014
00015
00016 extern int specedit;
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
00024
00029 static inline
00030 struct TriggerFileEntry * freeTriggerFiles( struct TriggerFileEntry * p)
00031
00032 {
00033 struct TriggerFileEntry *o, *q = p;
00034
00035 while (q != NULL) {
00036 o = q;
00037 q = q->next;
00038 o->fileName = _free(o->fileName);
00039 o->script = _free(o->script);
00040 o->prog = _free(o->prog);
00041 o = _free(o);
00042 }
00043 return NULL;
00044 }
00045
00051 static inline
00052 struct Source * freeSources( struct Source * s)
00053
00054 {
00055 struct Source *r, *t = s;
00056
00057 while (t != NULL) {
00058 r = t;
00059 t = t->next;
00060 r->fullSource = _free(r->fullSource);
00061 r = _free(r);
00062 }
00063 return NULL;
00064 }
00065
00066
00067 int lookupPackage(Spec spec, const char *name, int flag, Package *pkg)
00068 {
00069 const char *pname;
00070 const char *fullName;
00071 Package p;
00072
00073
00074 if (name == NULL) {
00075 if (pkg)
00076 *pkg = spec->packages;
00077 return 0;
00078 }
00079
00080
00081 { char *n;
00082 if (flag == PART_SUBNAME) {
00083 (void) headerNVR(spec->packages->header, &pname, NULL, NULL);
00084 fullName = n = alloca(strlen(pname) + 1 + strlen(name) + 1);
00085 while (*pname != '\0') *n++ = *pname++;
00086 *n++ = '-';
00087 } else {
00088 fullName = n = alloca(strlen(name)+1);
00089 }
00090
00091 strcpy(n, name);
00092
00093 }
00094
00095
00096 for (p = spec->packages; p != NULL; p = p->next) {
00097 (void) headerNVR(p->header, &pname, NULL, NULL);
00098 if (pname && (! strcmp(fullName, pname))) {
00099 break;
00100 }
00101 }
00102
00103 if (pkg)
00104 *pkg = p;
00105 return ((p == NULL) ? 1 : 0);
00106 }
00107
00108
00109 Package newPackage(Spec spec)
00110 {
00111 Package p;
00112 Package pp;
00113
00114 p = xcalloc(1, sizeof(*p));
00115
00116 p->header = headerNew();
00117 p->ds = NULL;
00118 p->icon = NULL;
00119
00120 p->autoProv = 1;
00121 p->autoReq = 1;
00122
00123 #if 0
00124 p->reqProv = NULL;
00125 p->triggers = NULL;
00126 p->triggerScripts = NULL;
00127 #endif
00128
00129 p->triggerFiles = NULL;
00130
00131 p->fileFile = NULL;
00132 p->fileList = NULL;
00133
00134 p->cpioList = NULL;
00135
00136 p->preInFile = NULL;
00137 p->postInFile = NULL;
00138 p->preUnFile = NULL;
00139 p->postUnFile = NULL;
00140 p->verifyFile = NULL;
00141
00142 p->specialDoc = NULL;
00143
00144 if (spec->packages == NULL) {
00145 spec->packages = p;
00146 } else {
00147
00148 for (pp = spec->packages; pp->next != NULL; pp = pp->next)
00149 {};
00150 pp->next = p;
00151 }
00152 p->next = NULL;
00153
00154 return p;
00155 }
00156
00157 Package freePackage(Package pkg)
00158 {
00159 if (pkg == NULL) return NULL;
00160
00161 pkg->preInFile = _free(pkg->preInFile);
00162 pkg->postInFile = _free(pkg->postInFile);
00163 pkg->preUnFile = _free(pkg->preUnFile);
00164 pkg->postUnFile = _free(pkg->postUnFile);
00165 pkg->verifyFile = _free(pkg->verifyFile);
00166
00167 pkg->header = headerFree(pkg->header);
00168 pkg->ds = rpmdsFree(pkg->ds);
00169 pkg->fileList = freeStringBuf(pkg->fileList);
00170 pkg->fileFile = _free(pkg->fileFile);
00171 if (pkg->cpioList) {
00172 rpmfi fi = pkg->cpioList;
00173 pkg->cpioList = NULL;
00174 fi = rpmfiFree(fi);
00175 }
00176
00177 pkg->specialDoc = freeStringBuf(pkg->specialDoc);
00178 pkg->icon = freeSources(pkg->icon);
00179 pkg->triggerFiles = freeTriggerFiles(pkg->triggerFiles);
00180
00181 pkg = _free(pkg);
00182 return NULL;
00183 }
00184
00185 Package freePackages(Package packages)
00186 {
00187 Package p;
00188
00189 while ((p = packages) != NULL) {
00190 packages = p->next;
00191 p->next = NULL;
00192 p = freePackage(p);
00193 }
00194 return NULL;
00195 }
00196
00199 static inline struct Source *findSource(Spec spec, int num, int flag)
00200
00201 {
00202 struct Source *p;
00203
00204 for (p = spec->sources; p != NULL; p = p->next)
00205 if ((num == p->num) && (p->flags & flag)) return p;
00206
00207 return NULL;
00208 }
00209
00210
00211 int parseNoSource(Spec spec, const char * field, int tag)
00212 {
00213 const char *f, *fe;
00214 const char *name;
00215 int num, flag;
00216
00217 if (tag == RPMTAG_NOSOURCE) {
00218 flag = RPMBUILD_ISSOURCE;
00219 name = "source";
00220 } else {
00221 flag = RPMBUILD_ISPATCH;
00222 name = "patch";
00223 }
00224
00225 fe = field;
00226 for (f = fe; *f != '\0'; f = fe) {
00227 struct Source *p;
00228
00229 SKIPWHITE(f);
00230 if (*f == '\0')
00231 break;
00232 fe = f;
00233 SKIPNONWHITE(fe);
00234 if (*fe != '\0') fe++;
00235
00236 if (parseNum(f, &num)) {
00237 rpmError(RPMERR_BADSPEC, _("line %d: Bad number: %s\n"),
00238 spec->lineNum, f);
00239 return RPMERR_BADSPEC;
00240 }
00241
00242 if (! (p = findSource(spec, num, flag))) {
00243 rpmError(RPMERR_BADSPEC, _("line %d: Bad no%s number: %d\n"),
00244 spec->lineNum, name, num);
00245 return RPMERR_BADSPEC;
00246 }
00247
00248 p->flags |= RPMBUILD_ISNO;
00249
00250 }
00251
00252 return 0;
00253 }
00254
00255
00256
00257 int addSource(Spec spec, Package pkg, const char *field, int tag)
00258 {
00259 struct Source *p;
00260 int flag = 0;
00261 char *name = NULL;
00262 char *nump;
00263 const char *fieldp = NULL;
00264 char buf[BUFSIZ];
00265 int num = 0;
00266
00267 buf[0] = '\0';
00268
00269 switch (tag) {
00270 case RPMTAG_SOURCE:
00271 flag = RPMBUILD_ISSOURCE;
00272 name = "source";
00273 fieldp = spec->line + 6;
00274 break;
00275 case RPMTAG_PATCH:
00276 flag = RPMBUILD_ISPATCH;
00277 name = "patch";
00278 fieldp = spec->line + 5;
00279 break;
00280 case RPMTAG_ICON:
00281 flag = RPMBUILD_ISICON;
00282 fieldp = NULL;
00283 break;
00284 }
00285
00286
00287
00288 if (tag != RPMTAG_ICON) {
00289
00290
00291
00292
00293
00294 nump = buf;
00295 while ((*fieldp != ':') && (*fieldp != ' ') && (*fieldp != '\t')) {
00296 *nump++ = *fieldp++;
00297 }
00298 *nump = '\0';
00299
00300 nump = buf;
00301 SKIPSPACE(nump);
00302 if (nump == NULL || *nump == '\0') {
00303 num = 0;
00304 } else {
00305 if (parseNum(buf, &num)) {
00306 rpmError(RPMERR_BADSPEC, _("line %d: Bad %s number: %s\n"),
00307 spec->lineNum, name, spec->line);
00308 return RPMERR_BADSPEC;
00309 }
00310 }
00311 }
00312
00313
00314 p = xmalloc(sizeof(*p));
00315 p->num = num;
00316 p->fullSource = xstrdup(field);
00317 p->flags = flag;
00318 p->source = strrchr(p->fullSource, '/');
00319 if (p->source) {
00320 p->source++;
00321 } else {
00322 p->source = p->fullSource;
00323 }
00324
00325 if (tag != RPMTAG_ICON) {
00326 p->next = spec->sources;
00327 spec->sources = p;
00328 } else {
00329 p->next = pkg->icon;
00330 pkg->icon = p;
00331 }
00332
00333 spec->numSources++;
00334
00335 if (tag != RPMTAG_ICON) {
00336
00337 const char *body = rpmGetPath("%{_sourcedir}/", p->source, NULL);
00338
00339
00340 sprintf(buf, "%s%d",
00341 (flag & RPMBUILD_ISPATCH) ? "PATCH" : "SOURCE", num);
00342 addMacro(spec->macros, buf, NULL, body, RMIL_SPEC);
00343 sprintf(buf, "%sURL%d",
00344 (flag & RPMBUILD_ISPATCH) ? "PATCH" : "SOURCE", num);
00345 addMacro(spec->macros, buf, NULL, p->fullSource, RMIL_SPEC);
00346 body = _free(body);
00347 }
00348
00349 return 0;
00350 }
00351
00352
00355 static inline speclines newSl(void)
00356
00357 {
00358 speclines sl = NULL;
00359
00360 if (specedit) {
00361 sl = xmalloc(sizeof(*sl));
00362 sl->sl_lines = NULL;
00363 sl->sl_nalloc = 0;
00364 sl->sl_nlines = 0;
00365 }
00366
00367 return sl;
00368 }
00369
00372
00373 static inline speclines freeSl( speclines sl)
00374
00375 {
00376 int i;
00377 if (sl == NULL) return NULL;
00378 for (i = 0; i < sl->sl_nlines; i++)
00379
00380 sl->sl_lines[i] = _free(sl->sl_lines[i]);
00381
00382 sl->sl_lines = _free(sl->sl_lines);
00383 return _free(sl);
00384 }
00385
00386
00389 static inline spectags newSt(void)
00390
00391 {
00392 spectags st = NULL;
00393
00394 if (specedit) {
00395 st = xmalloc(sizeof(*st));
00396 st->st_t = NULL;
00397 st->st_nalloc = 0;
00398 st->st_ntags = 0;
00399 }
00400
00401 return st;
00402 }
00403
00406 static inline spectags freeSt( spectags st)
00407
00408 {
00409 int i;
00410 if (st == NULL) return NULL;
00411 for (i = 0; i < st->st_ntags; i++) {
00412 spectag t = st->st_t + i;
00413 t->t_lang = _free(t->t_lang);
00414 t->t_msgid = _free(t->t_msgid);
00415 }
00416 st->st_t = _free(st->st_t);
00417 return _free(st);
00418 }
00419
00420 Spec newSpec(void)
00421 {
00422 Spec spec = xcalloc(1, sizeof(*spec));
00423
00424 spec->specFile = NULL;
00425
00426 spec->sl = newSl();
00427 spec->st = newSt();
00428
00429 spec->fileStack = NULL;
00430
00431 spec->lbuf[0] = '\0';
00432
00433 spec->line = spec->lbuf;
00434 spec->nextline = NULL;
00435 spec->nextpeekc = '\0';
00436 spec->lineNum = 0;
00437 spec->readStack = xcalloc(1, sizeof(*spec->readStack));
00438 spec->readStack->next = NULL;
00439 spec->readStack->reading = 1;
00440
00441 spec->rootURL = NULL;
00442 spec->prep = NULL;
00443 spec->build = NULL;
00444 spec->install = NULL;
00445 spec->check = 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->sourceRpmName = NULL;
00454 spec->sourcePkgId = NULL;
00455 spec->sourceHeader = NULL;
00456 spec->sourceCpioList = NULL;
00457
00458 spec->gotBuildRootURL = 0;
00459 spec->buildRootURL = NULL;
00460 spec->buildSubdir = NULL;
00461
00462 spec->passPhrase = NULL;
00463 spec->timeCheck = 0;
00464 spec->cookie = NULL;
00465
00466 spec->buildRestrictions = headerNew();
00467 spec->BANames = NULL;
00468 spec->BACount = 0;
00469 spec->recursing = 0;
00470 spec->BASpecs = NULL;
00471
00472 spec->force = 0;
00473 spec->anyarch = 0;
00474
00475 spec->macros = rpmGlobalMacroContext;
00476
00477 return spec;
00478 }
00479
00480 Spec freeSpec(Spec spec)
00481 {
00482 struct ReadLevelEntry *rl;
00483
00484 if (spec == NULL) return NULL;
00485
00486 spec->sl = freeSl(spec->sl);
00487 spec->st = freeSt(spec->st);
00488
00489 spec->prep = freeStringBuf(spec->prep);
00490 spec->build = freeStringBuf(spec->build);
00491 spec->install = freeStringBuf(spec->install);
00492 spec->check = freeStringBuf(spec->check);
00493 spec->clean = freeStringBuf(spec->clean);
00494
00495 spec->buildRootURL = _free(spec->buildRootURL);
00496 spec->buildSubdir = _free(spec->buildSubdir);
00497 spec->rootURL = _free(spec->rootURL);
00498 spec->specFile = _free(spec->specFile);
00499
00500 #ifdef DEAD
00501 { struct OpenFileInfo *ofi;
00502 while (spec->fileStack) {
00503 ofi = spec->fileStack;
00504 spec->fileStack = ofi->next;
00505 ofi->next = NULL;
00506 ofi->fileName = _free(ofi->fileName);
00507 ofi = _free(ofi);
00508 }
00509 }
00510 #else
00511 closeSpec(spec);
00512 #endif
00513
00514 while (spec->readStack) {
00515 rl = spec->readStack;
00516
00517 spec->readStack = rl->next;
00518
00519 rl->next = NULL;
00520 rl = _free(rl);
00521 }
00522
00523 spec->sourceRpmName = _free(spec->sourceRpmName);
00524 spec->sourcePkgId = _free(spec->sourcePkgId);
00525 spec->sourceHeader = headerFree(spec->sourceHeader);
00526
00527 if (spec->sourceCpioList) {
00528 rpmfi fi = spec->sourceCpioList;
00529 spec->sourceCpioList = NULL;
00530 fi = rpmfiFree(fi);
00531 }
00532
00533 spec->buildRestrictions = headerFree(spec->buildRestrictions);
00534
00535 if (!spec->recursing) {
00536
00537 if (spec->BASpecs != NULL)
00538 while (spec->BACount--) {
00539
00540 spec->BASpecs[spec->BACount] =
00541 freeSpec(spec->BASpecs[spec->BACount]);
00542
00543 }
00544
00545
00546 spec->BASpecs = _free(spec->BASpecs);
00547
00548 }
00549 spec->BANames = _free(spec->BANames);
00550
00551 spec->passPhrase = _free(spec->passPhrase);
00552 spec->cookie = _free(spec->cookie);
00553
00554 spec->sources = freeSources(spec->sources);
00555 spec->packages = freePackages(spec->packages);
00556
00557 spec = _free(spec);
00558
00559 return spec;
00560 }
00561
00562
00563 struct OpenFileInfo * newOpenFileInfo(void)
00564 {
00565 struct OpenFileInfo *ofi;
00566
00567 ofi = xmalloc(sizeof(*ofi));
00568 ofi->fd = NULL;
00569 ofi->fileName = NULL;
00570 ofi->lineNum = 0;
00571
00572 ofi->readBuf[0] = '\0';
00573
00574 ofi->readPtr = NULL;
00575 ofi->next = NULL;
00576
00577 return ofi;
00578 }
00579
00584 static void
00585 printNewSpecfile(Spec spec)
00586
00587
00588 {
00589 Header h;
00590 speclines sl = spec->sl;
00591 spectags st = spec->st;
00592 const char * msgstr = NULL;
00593 int i, j;
00594
00595 if (sl == NULL || st == NULL)
00596 return;
00597
00598
00599 for (i = 0; i < st->st_ntags; i++) {
00600 spectag t = st->st_t + i;
00601 const char * tn = tagName(t->t_tag);
00602 const char * errstr;
00603 char fmt[1024];
00604
00605 fmt[0] = '\0';
00606 if (t->t_msgid == NULL)
00607 h = spec->packages->header;
00608 else {
00609 Package pkg;
00610 char *fe;
00611
00612
00613 strcpy(fmt, t->t_msgid);
00614 for (fe = fmt; *fe && *fe != '('; fe++)
00615 {} ;
00616 if (*fe == '(') *fe = '\0';
00617
00618 h = NULL;
00619 for (pkg = spec->packages; pkg != NULL; pkg = pkg->next) {
00620 const char *pkgname;
00621 h = pkg->header;
00622 (void) headerNVR(h, &pkgname, NULL, NULL);
00623 if (!strcmp(pkgname, fmt))
00624 break;
00625 }
00626 if (pkg == NULL || h == NULL)
00627 h = spec->packages->header;
00628 }
00629
00630 if (h == NULL)
00631 continue;
00632
00633 fmt[0] = '\0';
00634
00635 (void) stpcpy( stpcpy( stpcpy( fmt, "%{"), tn), "}");
00636
00637 msgstr = _free(msgstr);
00638
00639
00640 msgstr = headerSprintf(h, fmt, rpmTagTable, rpmHeaderFormats, &errstr);
00641 if (msgstr == NULL) {
00642 rpmError(RPMERR_QFMT, _("can't query %s: %s\n"), tn, errstr);
00643 return;
00644 }
00645
00646
00647 switch(t->t_tag) {
00648 case RPMTAG_SUMMARY:
00649 case RPMTAG_GROUP:
00650
00651 sl->sl_lines[t->t_startx] = _free(sl->sl_lines[t->t_startx]);
00652
00653 if (t->t_lang && strcmp(t->t_lang, RPMBUILD_DEFAULT_LANG))
00654 continue;
00655 { char *buf = xmalloc(strlen(tn) + sizeof(": ") + strlen(msgstr));
00656 (void) stpcpy( stpcpy( stpcpy(buf, tn), ": "), msgstr);
00657 sl->sl_lines[t->t_startx] = buf;
00658 }
00659 break;
00660 case RPMTAG_DESCRIPTION:
00661 for (j = 1; j < t->t_nlines; j++) {
00662 if (*sl->sl_lines[t->t_startx + j] == '%')
00663 continue;
00664
00665 sl->sl_lines[t->t_startx + j] =
00666 _free(sl->sl_lines[t->t_startx + j]);
00667
00668 }
00669 if (t->t_lang && strcmp(t->t_lang, RPMBUILD_DEFAULT_LANG)) {
00670 sl->sl_lines[t->t_startx] = _free(sl->sl_lines[t->t_startx]);
00671 continue;
00672 }
00673 sl->sl_lines[t->t_startx + 1] = xstrdup(msgstr);
00674 if (t->t_nlines > 2)
00675 sl->sl_lines[t->t_startx + 2] = xstrdup("\n\n");
00676 break;
00677 }
00678
00679 }
00680
00681 msgstr = _free(msgstr);
00682
00683
00684 for (i = 0; i < sl->sl_nlines; i++) {
00685 const char * s = sl->sl_lines[i];
00686 if (s == NULL)
00687 continue;
00688 printf("%s", s);
00689 if (strchr(s, '\n') == NULL && s[strlen(s)-1] != '\n')
00690 printf("\n");
00691 }
00692
00693 }
00694
00695 int rpmspecQuery(rpmts ts, QVA_t qva, const char * arg)
00696 {
00697 Spec spec = NULL;
00698 Package pkg;
00699 char * buildRoot = NULL;
00700 int recursing = 0;
00701 char * passPhrase = "";
00702 char *cookie = NULL;
00703 int anyarch = 1;
00704 int force = 1;
00705 int res = 1;
00706 int xx;
00707
00708 if (qva->qva_showPackage == NULL)
00709 goto exit;
00710
00711
00712
00713 if (parseSpec(ts, arg, "/", buildRoot, recursing, passPhrase,
00714 cookie, anyarch, force)
00715 || (spec = rpmtsSetSpec(ts, NULL)) == NULL)
00716 {
00717 rpmError(RPMERR_QUERY,
00718 _("query of specfile %s failed, can't parse\n"), arg);
00719 goto exit;
00720 }
00721
00722
00723
00724 res = 0;
00725 if (specedit) {
00726 printNewSpecfile(spec);
00727 goto exit;
00728 }
00729
00730 for (pkg = spec->packages; pkg != NULL; pkg = pkg->next)
00731 xx = qva->qva_showPackage(qva, ts, pkg->header);
00732
00733 exit:
00734 spec = freeSpec(spec);
00735 return res;
00736 }