ctm_pass2.c revision 8857
1/* 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 * ---------------------------------------------------------------------------- 8 * 9 * $Id: ctm_pass2.c,v 1.7 1995/03/19 12:01:23 roberto Exp $ 10 * 11 */ 12 13#include "ctm.h" 14#define BADREAD 32 15 16/*---------------------------------------------------------------------------*/ 17/* Pass2 -- Validate the incoming CTM-file. 18 */ 19 20int 21Pass2(FILE *fd) 22{ 23 u_char *p,*q,*md5=0; 24 MD5_CTX ctx; 25 int i,j,sep,cnt; 26 u_char *trash=0,*name=0; 27 struct CTM_Syntax *sp; 28 struct stat st; 29 int ret = 0; 30 31 if(Verbose>3) 32 printf("Pass2 -- Checking if CTM-patch will apply\n"); 33 MD5Init (&ctx); 34 35 GETFIELD(p,' '); if(strcmp("CTM_BEGIN",p)) WRONG 36 GETFIELD(p,' '); if(strcmp(Version,p)) WRONG 37 GETFIELD(p,' '); if(strcmp(Name,p)) WRONG 38 /* XXX Lookup name in /etc/ctm,conf, read stuff */ 39 GETFIELD(p,' '); if(strcmp(Nbr,p)) WRONG 40 /* XXX Verify that this is the next patch to apply */ 41 GETFIELD(p,' '); if(strcmp(TimeStamp,p)) WRONG 42 GETFIELD(p,'\n'); if(strcmp(Prefix,p)) WRONG 43 /* XXX drop or use ? */ 44 45 for(;;) { 46 if(trash) {Free(trash), trash = 0;} 47 if(name) {Free(name), name = 0;} 48 if(md5) {Free(md5), md5 = 0;} 49 cnt = -1; 50 51 GETFIELD(p,' '); 52 53 if (p[0] != 'C' || p[1] != 'T' || p[2] != 'M') WRONG 54 55 if(!strcmp(p+3,"_END")) 56 break; 57 58 for(sp=Syntax;sp->Key;sp++) 59 if(!strcmp(p+3,sp->Key)) 60 goto found; 61 WRONG 62 found: 63 for(i=0;(j = sp->List[i]);i++) { 64 if (sp->List[i+1] && (sp->List[i+1] & CTM_F_MASK) != CTM_F_Bytes) 65 sep = ' '; 66 else 67 sep = '\n'; 68 69 switch (j & CTM_F_MASK) { 70 case CTM_F_Name: 71 GETFIELDCOPY(name,sep); 72 /* XXX Check DR DM rec's for parent-dir */ 73 if(j & CTM_Q_Name_New) { 74 /* XXX Check DR FR rec's for item */ 75 if(-1 != stat(name,&st)) { 76 fprintf(stderr," %s: %s exists.\n", 77 sp->Key,name); 78 ret |= Exit_Forcible; 79 } 80 break; 81 } 82 if(-1 == stat(name,&st)) { 83 fprintf(stderr," %s: %s doesn't exist.\n", 84 sp->Key,name); 85 if (sp->Key[1] == 'R') 86 ret |= Exit_Forcible; 87 else 88 ret |= Exit_NotOK; 89 break; 90 } 91 if (j & CTM_Q_Name_Dir) { 92 if((st.st_mode & S_IFMT) != S_IFDIR) { 93 fprintf(stderr, 94 " %s: %s exist, but isn't dir.\n", 95 sp->Key,name); 96 ret |= Exit_NotOK; 97 } 98 break; 99 } 100 if (j & CTM_Q_Name_File) { 101 if((st.st_mode & S_IFMT) != S_IFREG) { 102 fprintf(stderr, 103 " %s: %s exist, but isn't file.\n", 104 sp->Key,name); 105 ret |= Exit_NotOK; 106 } 107 break; 108 } 109 break; 110 case CTM_F_Uid: 111 case CTM_F_Gid: 112 case CTM_F_Mode: 113 GETFIELD(p,sep); 114 break; 115 case CTM_F_MD5: 116 if(!name) WRONG 117 if(j & CTM_Q_MD5_Before) { 118 GETFIELD(p,sep); 119 if((st.st_mode & S_IFMT) == S_IFREG && 120 strcmp(MD5File(name),p)) { 121 fprintf(stderr," %s: %s md5 mismatch.\n", 122 sp->Key,name); 123 if(j & CTM_Q_MD5_Force) { 124 if(Force) 125 fprintf(stderr," Can and will force.\n"); 126 else 127 fprintf(stderr," Could have forced.\n"); 128 ret |= Exit_Forcible; 129 } else { 130 ret |= Exit_NotOK; 131 } 132 } 133 break; 134 } 135 if(j & CTM_Q_MD5_After) { 136 GETFIELDCOPY(md5,sep); 137 break; 138 } 139 /* Unqualified MD5 */ 140 WRONG 141 break; 142 case CTM_F_Count: 143 GETBYTECNT(cnt,sep); 144 break; 145 case CTM_F_Bytes: 146 if(cnt < 0) WRONG 147 GETDATA(trash,cnt); 148 if(!strcmp(sp->Key,"FN")) { 149 p = tempnam(TmpDir,"CTMclient"); 150 j = ctm_edit(trash,cnt,name,p); 151 if(j) { 152 fprintf(stderr," %s: %s edit returned %d.\n", 153 sp->Key,name,j); 154 ret |= j; 155 return ret; 156 } else if(strcmp(md5,MD5File(p))) { 157 fprintf(stderr," %s: %s edit fails.\n", 158 sp->Key,name); 159 ret |= Exit_Mess; 160 return ret; 161 } 162 unlink(p); 163 free(p); 164 } 165 166 break; 167 default: WRONG 168 } 169 } 170 } 171 q = MD5End (&ctx); 172 GETFIELD(p,'\n'); /* <MD5> */ 173 if(strcmp(q,p)) WRONG 174 if (-1 != getc(fd)) WRONG 175 return ret; 176} 177