ctm_pass2.c revision 2886
1#include "ctm.h"
2
3/*---------------------------------------------------------------------------*/
4/* Pass2 -- Validate the incomming CTM-file.
5 */
6
7int
8Pass2(FILE *fd)
9{
10    u_char *p,*q;
11    MD5_CTX ctx;
12    int i,j,sep,cnt;
13    u_char *trash=0,*name=0;
14    struct CTM_Syntax *sp;
15    struct stat st;
16
17    if(Verbose>3)
18	printf("Pass2 -- Checking if CTM-patch will apply\n");
19    MD5Init (&ctx);
20
21    GETFIELD(p,' '); if(strcmp("CTM_BEGIN",p)) WRONG
22    GETFIELD(p,' '); if(strcmp(Version,p)) WRONG
23    GETFIELD(p,' '); if(strcmp(Name,p)) WRONG
24    /* XXX Lookup name in /etc/ctm,conf, read stuff */
25    GETFIELD(p,' '); if(strcmp(Nbr,p)) WRONG
26    /* XXX Verify that this is the next patch to apply */
27    GETFIELD(p,' '); if(strcmp(TimeStamp,p)) WRONG
28    GETFIELD(p,'\n'); if(strcmp(Prefix,p)) WRONG
29    /* XXX drop or use ? */
30
31    for(;;) {
32	if(trash)	{Free(trash), trash = 0;}
33	if(name)	{Free(name), name = 0;}
34	cnt = -1;
35
36	GETFIELD(p,' ');
37
38	if (p[0] != 'C' || p[1] != 'T' || p[2] != 'M') WRONG
39
40	if(!strcmp(p+3,"_END"))
41	    break;
42
43	for(sp=Syntax;sp->Key;sp++)
44	    if(!strcmp(p+3,sp->Key))
45		goto found;
46	WRONG
47    found:
48	for(i=0;(j = sp->List[i]);i++) {
49	    if (sp->List[i+1] && (sp->List[i+1] & CTM_F_MASK) != CTM_F_Bytes)
50		sep = ' ';
51	    else
52		sep = '\n';
53
54	    switch (j & CTM_F_MASK) {
55		case CTM_F_Name:
56		    GETFIELDCOPY(name,sep);
57		    /* XXX Check DR DM rec's for parent-dir */
58		    if(j & CTM_Q_Name_New) {
59			/* XXX Check DR FR rec's for item */
60			if(-1 != stat(name,&st)) {
61			    fprintf(stderr,"  %s: %s exists.\n",sp->Key,name);
62			}
63			break;
64		    }
65		    if(-1 == stat(name,&st)) {
66			fprintf(stderr,"  %s: %s doesn't exists.\n",
67			    sp->Key,name);
68			break;
69		    }
70		    if (j & CTM_Q_Name_Dir) {
71			if((st.st_mode & S_IFMT) != S_IFDIR)
72			    fprintf(stderr,
73				"  %s: %s exist, but isn't dir.\n",
74				sp->Key,name);
75			break;
76		    }
77		    if (j & CTM_Q_Name_File) {
78			if((st.st_mode & S_IFMT) != S_IFREG)
79			    fprintf(stderr,
80				"  %s: %s exist, but isn't file.\n",
81				sp->Key,name);
82			break;
83		    }
84		    break;
85		case CTM_F_Uid:
86		case CTM_F_Gid:
87		case CTM_F_Mode:
88		    GETFIELD(p,sep);
89		    break;
90		case CTM_F_MD5:
91		    if(!name) WRONG
92		    GETFIELD(p,sep);
93		    if((st.st_mode & S_IFMT) == S_IFREG) {
94			if(j & CTM_Q_MD5_Before && strcmp(MD5File(name),p)) {
95			    fprintf(stderr,"  %s: %s md5 mismatch.\n",sp->Key,name);
96			}
97		    }
98		    break;
99		case CTM_F_Count:
100		    GETBYTECNT(cnt,sep);
101		    break;
102		case CTM_F_Bytes:
103		    if(cnt < 0) WRONG
104		    GETDATA(trash,cnt);
105		    p = MD5Data(trash,cnt);
106		    break;
107		default: WRONG
108	    }
109        }
110    }
111    q = MD5End (&ctx);
112    GETFIELD(p,'\n');			/* <MD5> */
113    if(strcmp(q,p)) WRONG
114    if (-1 != getc(fd)) WRONG
115    return 0;
116}
117