home *** CD-ROM | disk | FTP | other *** search
/ Chip 1998 February / CHIP_2_98.iso / misc / src / rpm / build / vspec.c < prev   
C/C++ Source or Header  |  1997-09-17  |  5KB  |  207 lines

  1. /* Routine to "verify" a parsed spec file */
  2.  
  3. /***************
  4.  
  5. Here's what we do
  6.  
  7. . check for duplicate fields
  8. . make sure a certain set of fields are present
  9. . in subpackages, make sure a certain set of fields are present
  10. . in subpackages, make sure certain fields are *not* present
  11.  
  12. . check for duplicate sources/patch numbers
  13. . do some checking on the field values for legit characters
  14.  
  15. ****************/
  16.  
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <ctype.h>
  20. #include <string.h>
  21.  
  22. #include "header.h"
  23. #include "spec.h"
  24. #include "specP.h"
  25. #include "messages.h"
  26. #include "rpmlib.h"
  27. #include "stringbuf.h"
  28. #include "misc.h"
  29.  
  30. #define EMPTY(s) ((!(s)) || (!(*(s))))
  31. #define OOPS(s) {fprintf(stderr, "verifySpec: %s\n", s); res = 1;}
  32. #define MUST 1
  33.  
  34. struct packageFieldsRec {
  35.     int tag;
  36.     int present;
  37.     int shouldBePresent;
  38. };
  39.  
  40. struct fieldNamesRec {
  41.     int tag;
  42.     char *name;
  43. };
  44.  
  45. static int checkHeaderTags(Header inh, struct packageFieldsRec *pfr);
  46. static char *tagName(int tag);
  47.  
  48. /* This is a list of tags related to the "main" package. */
  49. /* Only list those that must or must not be present.     */
  50.  
  51. static struct packageFieldsRec packageFields[] = {
  52.     { RPMTAG_NAME,            0, MUST },
  53.     { RPMTAG_VERSION,         0, MUST },
  54.     { RPMTAG_RELEASE,         0, MUST },
  55. /*    { RPMTAG_SUMMARY,         0, MUST }, */
  56.     { RPMTAG_DESCRIPTION,     0, MUST },
  57.     { RPMTAG_COPYRIGHT,       0, MUST },
  58. /*    { RPMTAG_PACKAGER,        0, MUST }, */
  59.     { RPMTAG_GROUP,           0, MUST },
  60.     { 0, 0, 0 },
  61. };
  62.  
  63. /* This is a list of tags related to "sub" packages. */
  64. /* Only list those that must or must not be present. */
  65.  
  66. static struct packageFieldsRec subpackageFields[] = {
  67.     { RPMTAG_NAME,            0, MUST },  /* This is inserted automaticaly */
  68.     { RPMTAG_SUMMARY,         0, MUST },
  69.     { RPMTAG_DESCRIPTION,     0, MUST },
  70.     { RPMTAG_GROUP,           0, MUST },
  71.     { RPMTAG_NAME,            0, 0 },
  72.     { RPMTAG_COPYRIGHT,       0, 0 },
  73.     { RPMTAG_PACKAGER,        0, 0 },
  74.     { RPMTAG_BUILDROOT,       0, 0 },
  75.     { 0, 0, 0 },
  76. };
  77.  
  78. static struct packageFieldsRec *findTag(int tag, struct packageFieldsRec *pfr)
  79. {
  80.     struct packageFieldsRec *p = pfr;
  81.  
  82.     while (p->tag) {
  83.     if (p->tag == tag)
  84.         return p;
  85.     p++;
  86.     }
  87.  
  88.     return NULL;
  89. }
  90.  
  91. static char *tagName(int tag)
  92. {
  93.     int i = 0;
  94.     static char nameBuf[1024];
  95.     char *s;
  96.  
  97.     strcpy(nameBuf, "(unknown)");
  98.     while (i < rpmTagTableSize) {
  99.     if (tag == rpmTagTable[i].val) {
  100.         strcpy(nameBuf, rpmTagTable[i].name + 7);
  101.         s = nameBuf+1;
  102.         while (*s) {
  103.         *s = tolower(*s);
  104.         s++;
  105.         }
  106.     }
  107.     i++;
  108.     }
  109.  
  110.     return nameBuf;
  111. }
  112.  
  113. static int checkHeaderTags(Header inh, struct packageFieldsRec *pfr)
  114. {
  115.     Header h;
  116.     HeaderIterator headerIter;
  117.     int res = 0;
  118.     int_32 tag, lastTag, type, c;
  119.     void *ptr;
  120.     struct packageFieldsRec *p;
  121.  
  122.     /* Sort the index, so it'll be easy to catch dups */
  123.     h = headerCopy(inh);
  124.     headerSort(h);
  125.  
  126.     headerIter = headerInitIterator(h);
  127.     lastTag = 0;
  128.     while (headerNextIterator(headerIter, &tag, &type, &ptr, &c)) {
  129.     if (tag == lastTag) {
  130.         rpmError(RPMERR_BADSPEC, "Duplicate fields for     : %s",
  131.           tagName(tag));
  132.         res = 1;
  133.     }
  134.     p = findTag(tag, pfr);
  135.     if (p) 
  136.         p->present = 1;
  137.     lastTag = tag;
  138.     }
  139.     headerFreeIterator(headerIter);
  140.     headerFree(h);
  141.  
  142.     p = pfr;
  143.     while (p->tag) {
  144.     if (p->shouldBePresent != p->present) {
  145.         rpmError(RPMERR_BADSPEC, "Field must%s be present%s: %s",
  146.           p->present ? " NOT" : "", p->present ? "" : "    ",
  147.           tagName(p->tag));
  148.         res = 1;
  149.     }
  150.     p->present = 0;  /* hack to clear it for next time :-) */
  151.     p++;
  152.     }
  153.     
  154.     return res;
  155. }
  156.  
  157. int verifySpec(Spec s)
  158. {
  159.     int res = 0;
  160.     struct PackageRec *pr;
  161.     struct packageFieldsRec *fields;
  162.     char name[1024];
  163.     char *val;
  164.     
  165.     if (EMPTY(s->name)) {
  166.     OOPS("No Name field");
  167.     }
  168.  
  169.     /* Check each package/subpackage */
  170.     pr = s->packages;
  171.     fields = packageFields;
  172.     while (pr) {
  173.     if (! pr->subname) {
  174.         if (pr->newname) {
  175.         strcpy(name, pr->newname);
  176.         } else {
  177.         strcpy(name, s->name);
  178.         }
  179.     } else {
  180.         sprintf(name, "%s-%s", s->name, pr->subname);
  181.     }
  182.     printf("* Package: %s\n", name);
  183.  
  184.     if (checkHeaderTags(pr->header, fields)) {
  185.         res = 1;
  186.     }
  187.  
  188.     val = NULL;
  189.     headerGetEntry(pr->header, RPMTAG_VERSION, NULL, (void *) &val, NULL);
  190.     if (val && strchr(val, '-')) {
  191.         rpmError(RPMERR_BADSPEC, "Illegal '-' char in version: %s\n", val);
  192.         res = 1;
  193.     }
  194.     val = NULL;
  195.     headerGetEntry(pr->header, RPMTAG_RELEASE, NULL, (void *) &val, NULL);
  196.     if (val && strchr(val, '-')) {
  197.         rpmError(RPMERR_BADSPEC, "Illegal '-' char in release: %s\n", val);
  198.         res = 1;
  199.     }
  200.     
  201.     pr = pr->next;
  202.     fields = subpackageFields;
  203.     }
  204.     
  205.     return res;
  206. }
  207.