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.");
121 if (q[0] == '.' && q[1] == '.')
122 if (q[2] == '/' || q[2] == '\0') {
123 Fatal("Paths containing '..' are illegal.");
126 if ((q = strchr(q, '/')) == NULL)
131 /* if we have been asked to `keep' files then skip
132 removes; i.e. we don't match these entries at
135 (!strcmp(sp->Key,"DR") || !strcmp(sp->Key,"FR"))) {
136 match = CTM_FILTER_DISABLE;
140 /* If filter expression have been defined, match the
141 path name against the expression list. */
144 struct CTM_Filter *filter;
146 for (filter = FilterList; filter;
147 filter = filter->Next) {
148 if (0 == regexec(&filter->CompiledRegex, name,
150 /* if the name matches, adopt the
152 match = filter->Action;
156 /* Add up the total number of matches */
157 total_matches += match;
163 Fatal("Non-digit in uid.");
173 Fatal("Non-digit in gid.");
183 Fatal("Non-digit in mode.");
190 if(j & CTM_Q_MD5_Chunk) {
191 GETFIELDCOPY(md5,sep); /* XXX check for garbage */
192 } else if(j & CTM_Q_MD5_Before) {
193 GETFIELD(p,sep); /* XXX check for garbage */
194 } else if(j & CTM_Q_MD5_After) {
195 GETFIELD(p,sep); /* XXX check for garbage */
197 fprintf(stderr,"List = 0x%x\n",j);
198 Fatal("Unqualified MD5.");
208 p = MD5Data(trash,cnt,md5_1);
209 if(md5 && strcmp(md5,p)) {
210 Fatal("Internal MD5 failed.");
213 fprintf(stderr,"List = 0x%x\n",j);
214 Fatal("List had garbage.");
222 printf("> %s %s\n", sp->Key, name);
229 q = MD5End (&ctx,md5_1);
231 printf("Expecting Global MD5 <%s>\n",q);
232 GETFIELD(p,'\n'); /* <MD5> */
234 printf("Reference Global MD5 <%s>\n",p);
236 Fatal("MD5 sum doesn't match.");
237 fprintf(stderr,"\tI have:<%s>\n",q);
238 fprintf(stderr,"\tShould have been:<%s>\n",p);
241 if (-1 != getc(fd)) {
243 Fatal("Trailing junk in CTM-file. Can Force with -F.");
247 if ((Verbose > 1) && (0 == total_matches))
248 printf("No matches in \"%s\"\n", FileName);
249 return (total_matches ? Exit_OK : Exit_NoMatch);