2 * ----------------------------------------------------------------------------
3 * "THE BEER-WARE LICENSE" (Revision 42):
4 * <phk@FreeBSD.org> wrote this file. As long as you retain this notice you
5 * can do whatever you want with this stuff. If we meet some day, and you think
6 * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
7 * ----------------------------------------------------------------------------
16 /*---------------------------------------------------------------------------*/
17 /* Pass1 -- Validate the incoming CTM-file.
21 Pass1(FILE *fd, unsigned applied)
26 u_char *md5=0,*name=0,*trash=0;
27 struct CTM_Syntax *sp;
28 int slashwarn=0, match=0, total_matches=0;
33 printf("Pass1 -- Checking integrity of incoming CTM-patch\n");
36 GETFIELD(p,' '); /* CTM_BEGIN */
37 if(strcmp(p,"CTM_BEGIN")) {
38 Fatal("Probably not a CTM-patch at all.");
40 fprintf(stderr,"Expected \"CTM_BEGIN\" got \"%s\".\n",p);
44 GETFIELDCOPY(Version,' '); /* <Version> */
45 if(strcmp(Version,VERSION)) {
46 Fatal("CTM-patch is wrong version.");
48 fprintf(stderr,"Expected \"%s\" got \"%s\".\n",VERSION,p);
52 GETFIELDCOPY(Name,' '); /* <Name> */
53 GETFIELDCOPY(Nbr,' '); /* <Nbr> */
54 GETFIELDCOPY(TimeStamp,' '); /* <TimeStamp> */
55 GETFIELDCOPY(Prefix,'\n'); /* <Prefix> */
57 sscanf(Nbr, "%u", ¤t);
58 if (FilterList || ListIt)
59 current = 0; /* ignore if -l or if filters are present */
60 if(current && current <= applied) {
62 fprintf(stderr,"Delta number %u is already applied; ignoring.\n",
72 /* if a filter list is defined we assume that all pathnames require
73 an action opposite to that requested by the first filter in the
75 If no filter is defined, all pathnames are assumed to match. */
76 match = (FilterList ? !(FilterList->Action) : CTM_FILTER_ENABLE);
78 GETFIELD(p,' '); /* CTM_something */
80 if (p[0] != 'C' || p[1] != 'T' || p[2] != 'M') {
81 Fatal("Expected CTM keyword.");
82 fprintf(stderr,"Got [%s]\n",p);
86 if(!strcmp(p+3,"_END"))
89 for(sp=Syntax;sp->Key;sp++)
90 if(!strcmp(p+3,sp->Key))
92 Fatal("Expected CTM keyword.");
93 fprintf(stderr,"Got [%s]\n",p);
97 fprintf(stderr,"%s ",sp->Key);
98 for(i=0;(j = sp->List[i]);i++) {
99 if (sp->List[i+1] && (sp->List[i+1] & CTM_F_MASK) != CTM_F_Bytes)
105 fprintf(stderr," %x(%d)",sp->List[i],sep);
107 switch (j & CTM_F_MASK) {
108 case CTM_F_Name: /* XXX check for garbage and .. */
109 GETFIELDCOPY(name,sep);
111 if(name[j-1] == '/' && !slashwarn) {
112 fprintf(stderr,"Warning: contains trailing slash\n");
115 if (name[0] == '/') {
116 Fatal("Absolute paths are illegal.");
122 if (q[0] == '.' && q[1] == '.')
123 if (q[2] == '/' || q[2] == '\0') {
124 Fatal("Paths containing '..' are illegal.");
128 if ((q = strchr(q, '/')) == NULL)
133 /* if we have been asked to `keep' files then skip
134 removes; i.e. we don't match these entries at
137 (!strcmp(sp->Key,"DR") || !strcmp(sp->Key,"FR"))) {
138 match = CTM_FILTER_DISABLE;
142 /* If filter expression have been defined, match the
143 path name against the expression list. */
146 struct CTM_Filter *filter;
148 for (filter = FilterList; filter;
149 filter = filter->Next) {
150 if (0 == regexec(&filter->CompiledRegex, name,
152 /* if the name matches, adopt the
154 match = filter->Action;
158 /* Add up the total number of matches */
159 total_matches += match;
165 Fatal("Non-digit in uid.");
175 Fatal("Non-digit in gid.");
185 Fatal("Non-digit in mode.");
192 if(j & CTM_Q_MD5_Chunk) {
193 GETFIELDCOPY(md5,sep); /* XXX check for garbage */
194 } else if(j & CTM_Q_MD5_Before) {
195 GETFIELD(p,sep); /* XXX check for garbage */
196 } else if(j & CTM_Q_MD5_After) {
197 GETFIELD(p,sep); /* XXX check for garbage */
199 fprintf(stderr,"List = 0x%x\n",j);
200 Fatal("Unqualified MD5.");
210 p = MD5Data(trash,cnt,md5_1);
211 if(md5 && strcmp(md5,p)) {
212 Fatal("Internal MD5 failed.");
215 fprintf(stderr,"List = 0x%x\n",j);
216 Fatal("List had garbage.");
224 printf("> %s %s\n", sp->Key, name);
231 q = MD5End (&ctx,md5_1);
233 printf("Expecting Global MD5 <%s>\n",q);
234 GETFIELD(p,'\n'); /* <MD5> */
236 printf("Reference Global MD5 <%s>\n",p);
238 Fatal("MD5 sum doesn't match.");
239 fprintf(stderr,"\tI have:<%s>\n",q);
240 fprintf(stderr,"\tShould have been:<%s>\n",p);
243 if (-1 != getc(fd)) {
245 Fatal("Trailing junk in CTM-file. Can Force with -F.");
249 if ((Verbose > 1) && (0 == total_matches))
250 printf("No matches in \"%s\"\n", FileName);
251 return (total_matches ? Exit_OK : Exit_NoMatch);