ctm_pass3.c revision 9491
12926Sphk/* 22926Sphk * ---------------------------------------------------------------------------- 32926Sphk * "THE BEER-WARE LICENSE" (Revision 42): 42926Sphk * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you 52926Sphk * can do whatever you want with this stuff. If we meet some day, and you think 62926Sphk * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp 72926Sphk * ---------------------------------------------------------------------------- 82926Sphk * 99491Sphk * $Id: ctm_pass3.c,v 1.10 1995/05/30 03:47:27 rgrimes Exp $ 102926Sphk * 112926Sphk */ 122926Sphk 132886Sphk#include "ctm.h" 142926Sphk#define BADREAD 32 152886Sphk 162886Sphk/*---------------------------------------------------------------------------*/ 174816Sphk/* Pass3 -- Validate the incoming CTM-file. 182886Sphk */ 192886Sphk 202886Sphkint 212886SphkPass3(FILE *fd) 222886Sphk{ 232886Sphk u_char *p,*q,buf[BUFSIZ]; 242886Sphk MD5_CTX ctx; 252886Sphk int i,j,sep,cnt; 262886Sphk u_char *md5=0,*md5before=0,*trash=0,*name=0,*uid=0,*gid=0,*mode=0; 272886Sphk struct CTM_Syntax *sp; 282886Sphk FILE *ed=0; 292886Sphk struct stat st; 309491Sphk char md5_1[33]; 312886Sphk 328857Srgrimes if(Verbose>3) 332886Sphk printf("Pass3 -- Applying the CTM-patch\n"); 342886Sphk MD5Init (&ctx); 352886Sphk 362886Sphk GETFIELD(p,' '); if(strcmp("CTM_BEGIN",p)) WRONG 372886Sphk GETFIELD(p,' '); if(strcmp(Version,p)) WRONG 382886Sphk GETFIELD(p,' '); if(strcmp(Name,p)) WRONG 392886Sphk GETFIELD(p,' '); if(strcmp(Nbr,p)) WRONG 402886Sphk GETFIELD(p,' '); if(strcmp(TimeStamp,p)) WRONG 412886Sphk GETFIELD(p,'\n'); if(strcmp(Prefix,p)) WRONG 422886Sphk 432886Sphk for(;;) { 442886Sphk if(md5) {Free(md5), md5 = 0;} 452886Sphk if(uid) {Free(uid), uid = 0;} 462886Sphk if(gid) {Free(gid), gid = 0;} 472886Sphk if(mode) {Free(mode), mode = 0;} 482886Sphk if(md5before) {Free(md5before), md5before = 0;} 492886Sphk if(trash) {Free(trash), trash = 0;} 502886Sphk if(name) {Free(name), name = 0;} 512886Sphk cnt = -1; 522886Sphk 532886Sphk GETFIELD(p,' '); 542886Sphk 552886Sphk if (p[0] != 'C' || p[1] != 'T' || p[2] != 'M') WRONG 562886Sphk 572886Sphk if(!strcmp(p+3,"_END")) 582886Sphk break; 592886Sphk 602886Sphk for(sp=Syntax;sp->Key;sp++) 612886Sphk if(!strcmp(p+3,sp->Key)) 622886Sphk goto found; 632886Sphk WRONG 642886Sphk found: 652886Sphk for(i=0;(j = sp->List[i]);i++) { 662886Sphk if (sp->List[i+1] && (sp->List[i+1] & CTM_F_MASK) != CTM_F_Bytes) 672886Sphk sep = ' '; 682886Sphk else 692886Sphk sep = '\n'; 702886Sphk 712886Sphk switch (j & CTM_F_MASK) { 722886Sphk case CTM_F_Name: GETFIELDCOPY(name,sep); break; 732886Sphk case CTM_F_Uid: GETFIELDCOPY(uid,sep); break; 742886Sphk case CTM_F_Gid: GETFIELDCOPY(gid,sep); break; 752886Sphk case CTM_F_Mode: GETFIELDCOPY(mode,sep); break; 762886Sphk case CTM_F_MD5: 772886Sphk if(j & CTM_Q_MD5_Before) 788857Srgrimes GETFIELDCOPY(md5before,sep); 792886Sphk else 808857Srgrimes GETFIELDCOPY(md5,sep); 812886Sphk break; 822886Sphk case CTM_F_Count: GETBYTECNT(cnt,sep); break; 832886Sphk case CTM_F_Bytes: GETDATA(trash,cnt); break; 842886Sphk default: WRONG 852886Sphk } 862886Sphk } 872948Sphk /* XXX This should go away. Disallow trailing '/' */ 882886Sphk j = strlen(name)-1; 892886Sphk if(name[j] == '/') name[j] = '\0'; 902948Sphk 912886Sphk fprintf(stderr,"> %s %s\n",sp->Key,name); 922886Sphk if(!strcmp(sp->Key,"FM") || !strcmp(sp->Key, "FS")) { 937372Sjoerg i = open(name,O_WRONLY|O_CREAT|O_TRUNC,0666); 942886Sphk if(i < 0) { 952886Sphk perror(name); 962948Sphk WRONG 972886Sphk } 982886Sphk if(cnt != write(i,trash,cnt)) { 992886Sphk perror(name); 1002948Sphk WRONG 1012886Sphk } 1022886Sphk close(i); 1039491Sphk if(strcmp(md5,MD5File(name,md5_1))) { 1042886Sphk fprintf(stderr," %s %s MD5 didn't come out right\n", 1052886Sphk sp->Key,name); 1062948Sphk WRONG 1072886Sphk } 1082886Sphk continue; 1098857Srgrimes } 1102886Sphk if(!strcmp(sp->Key,"FE")) { 1112971Sphk ed = popen("ed","w"); 1122886Sphk if(!ed) { 1132886Sphk WRONG 1142886Sphk } 1152971Sphk fprintf(ed,"e %s\n",name); 1162886Sphk if(cnt != fwrite(trash,1,cnt,ed)) { 1172886Sphk perror(name); 1182886Sphk pclose(ed); 1192948Sphk WRONG 1202886Sphk } 1212886Sphk fprintf(ed,"w %s\n",name); 1222886Sphk if(pclose(ed)) { 1232886Sphk perror("ed"); 1242948Sphk WRONG 1252886Sphk } 1269491Sphk if(strcmp(md5,MD5File(name,md5_1))) { 1272886Sphk fprintf(stderr," %s %s MD5 didn't come out right\n", 1282886Sphk sp->Key,name); 1292948Sphk WRONG 1302886Sphk } 1312886Sphk continue; 1322886Sphk } 1332926Sphk if(!strcmp(sp->Key,"FN")) { 1342926Sphk strcpy(buf,name); 1352926Sphk strcat(buf,".ctm"); 1362926Sphk i = ctm_edit(trash,cnt,name,buf); 1372926Sphk if(i) { 1382948Sphk fprintf(stderr," %s %s Edit failed with code %d.\n", 1392948Sphk sp->Key,name,i); 1402948Sphk WRONG 1412926Sphk } 1422926Sphk rename(buf,name); 1439491Sphk if(strcmp(md5,MD5File(name,md5_1))) { 1442948Sphk fprintf(stderr," %s %s Edit failed MD5 check.\n", 1452948Sphk sp->Key,name); 1462948Sphk WRONG 1472948Sphk } 1482948Sphk continue; 1492926Sphk } 1502886Sphk if(!strcmp(sp->Key,"DM")) { 1517372Sjoerg if(0 > mkdir(name,0777)) { 1522886Sphk sprintf(buf,"mkdir -p %s",name); 1532886Sphk system(buf); 1542886Sphk } 1552886Sphk if(0 > stat(name,&st) || ((st.st_mode & S_IFMT) != S_IFDIR)) { 1562886Sphk fprintf(stderr,"<%s> mkdir failed\n",name); 1572948Sphk WRONG 1582886Sphk } 1592886Sphk continue; 1608857Srgrimes } 1614816Sphk if(!strcmp(sp->Key,"FR")) { 1624947Sphk if (0 != unlink(name)) { 1634947Sphk fprintf(stderr,"<%s> unlink failed\n",name); 1646181Sphk if (!Force) 1656181Sphk WRONG 1664947Sphk } 1674947Sphk continue; 1688857Srgrimes } 1698857Srgrimes if(!strcmp(sp->Key,"DR")) { 1704947Sphk /* 1714947Sphk * We cannot use rmdir() because we do not get the directories 1724947Sphk * in '-depth' order (cvs-cur.0018.gz for examples) 1734947Sphk */ 1744816Sphk sprintf(buf,"rm -rf %s",name); 1754816Sphk system(buf); 1762886Sphk continue; 1778857Srgrimes } 1782886Sphk WRONG 1792886Sphk } 1809491Sphk q = MD5End (&ctx,md5_1); 1812886Sphk GETFIELD(p,'\n'); 1822886Sphk if(strcmp(q,p)) WRONG 1832886Sphk if (-1 != getc(fd)) WRONG 1842886Sphk return 0; 1852886Sphk} 186