2 * ----------------------------------------------------------------------------
3 * "THE BEER-WARE LICENSE" (Revision 42):
4 * <phk@login.dknet.dk> 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 * ----------------------------------------------------------------------------
9 * $FreeBSD: src/usr.sbin/ctm/ctm/ctm_pass1.c,v 1.16 1999/08/28 01:15:59 peter Exp $
10 * $DragonFly: src/usr.sbin/ctm/ctm/Attic/ctm_pass1.c,v 1.2 2003/06/17 04:29:53 dillon Exp $
17 /*---------------------------------------------------------------------------*/
18 /* Pass1 -- Validate the incoming CTM-file.
22 Pass1(FILE *fd, unsigned applied)
27 u_char *md5=0,*name=0,*trash=0;
28 struct CTM_Syntax *sp;
29 int slashwarn=0, match=0, total_matches=0;
34 printf("Pass1 -- Checking integrity of incoming CTM-patch\n");
37 GETFIELD(p,' '); /* CTM_BEGIN */
38 if(strcmp(p,"CTM_BEGIN")) {
39 Fatal("Probably not a CTM-patch at all.");
41 fprintf(stderr,"Expected \"CTM_BEGIN\" got \"%s\".\n",p);
45 GETFIELDCOPY(Version,' '); /* <Version> */
46 if(strcmp(Version,VERSION)) {
47 Fatal("CTM-patch is wrong version.");
49 fprintf(stderr,"Expected \"%s\" got \"%s\".\n",VERSION,p);
53 GETFIELDCOPY(Name,' '); /* <Name> */
54 GETFIELDCOPY(Nbr,' '); /* <Nbr> */
55 GETFIELDCOPY(TimeStamp,' '); /* <TimeStamp> */
56 GETFIELDCOPY(Prefix,'\n'); /* <Prefix> */
58 sscanf(Nbr, "%u", ¤t);
59 if (FilterList || ListIt)
60 current = 0; /* ignore if -l or if filters are present */
61 if(current && current <= applied) {
63 fprintf(stderr,"Delta number %u is already applied; ignoring.\n",
73 /* if a filter list is defined we assume that all pathnames require
74 an action opposite to that requested by the first filter in the
76 If no filter is defined, all pathnames are assumed to match. */
77 match = (FilterList ? !(FilterList->Action) : CTM_FILTER_ENABLE);
79 GETFIELD(p,' '); /* CTM_something */
81 if (p[0] != 'C' || p[1] != 'T' || p[2] != 'M') {
82 Fatal("Expected CTM keyword.");
83 fprintf(stderr,"Got [%s]\n",p);
87 if(!strcmp(p+3,"_END"))
90 for(sp=Syntax;sp->Key;sp++)
91 if(!strcmp(p+3,sp->Key))
93 Fatal("Expected CTM keyword.");
94 fprintf(stderr,"Got [%s]\n",p);
98 fprintf(stderr,"%s ",sp->Key);
99 for(i=0;(j = sp->List[i]);i++) {
100 if (sp->List[i+1] && (sp->List[i+1] & CTM_F_MASK) != CTM_F_Bytes)
106 fprintf(stderr," %x(%d)",sp->List[i],sep);
108 switch (j & CTM_F_MASK) {
109 case CTM_F_Name: /* XXX check for garbage and .. */
110 GETFIELDCOPY(name,sep);
112 if(name[j-1] == '/' && !slashwarn) {
113 fprintf(stderr,"Warning: contains trailing slash\n");
116 if (name[0] == '/') {
117 Fatal("Absolute paths are illegal.");
122 if (q[0] == '.' && q[1] == '.')
123 if (q[2] == '/' || q[2] == '\0') {
124 Fatal("Paths containing '..' are illegal.");
127 if ((q = strchr(q, '/')) == NULL)
132 /* if we have been asked to `keep' files then skip
133 removes; i.e. we don't match these entries at
136 (!strcmp(sp->Key,"DR") || !strcmp(sp->Key,"FR"))) {
137 match = CTM_FILTER_DISABLE;
141 /* If filter expression have been defined, match the
142 path name against the expression list. */
145 struct CTM_Filter *filter;
147 for (filter = FilterList; filter;
148 filter = filter->Next) {
149 if (0 == regexec(&filter->CompiledRegex, name,
151 /* if the name matches, adopt the
153 match = filter->Action;
157 /* Add up the total number of matches */
158 total_matches += match;
164 Fatal("Non-digit in uid.");
174 Fatal("Non-digit in gid.");
184 Fatal("Non-digit in mode.");
191 if(j & CTM_Q_MD5_Chunk) {
192 GETFIELDCOPY(md5,sep); /* XXX check for garbage */
193 } else if(j & CTM_Q_MD5_Before) {
194 GETFIELD(p,sep); /* XXX check for garbage */
195 } else if(j & CTM_Q_MD5_After) {
196 GETFIELD(p,sep); /* XXX check for garbage */
198 fprintf(stderr,"List = 0x%x\n",j);
199 Fatal("Unqualified MD5.");
209 p = MD5Data(trash,cnt,md5_1);
210 if(md5 && strcmp(md5,p)) {
211 Fatal("Internal MD5 failed.");
214 fprintf(stderr,"List = 0x%x\n",j);
215 Fatal("List had garbage.");
223 printf("> %s %s\n", sp->Key, name);
230 q = MD5End (&ctx,md5_1);
232 printf("Expecting Global MD5 <%s>\n",q);
233 GETFIELD(p,'\n'); /* <MD5> */
235 printf("Reference Global MD5 <%s>\n",p);
237 Fatal("MD5 sum doesn't match.");
238 fprintf(stderr,"\tI have:<%s>\n",q);
239 fprintf(stderr,"\tShould have been:<%s>\n",p);
242 if (-1 != getc(fd)) {
244 Fatal("Trailing junk in CTM-file. Can Force with -F.");
248 if ((Verbose > 1) && (0 == total_matches))
249 printf("No matches in \"%s\"\n", FileName);
250 return (total_matches ? Exit_OK : Exit_NoMatch);