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