1/* 2 * ---------------------------------------------------------------------------- 3 * "THE BEER-WARE LICENSE" (Revision 42): 4 * <koshy@india.hp.com> 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. Joseph Koshy 7 * ---------------------------------------------------------------------------- 8 * 9 * $FreeBSD$ 10 * 11 */ 12 13#include "ctm.h" 14#define BADREAD 32 15 16/*---------------------------------------------------------------------------*/ 17/* PassB -- Backup modified files. 18 */ 19 20int 21PassB(FILE *fd) 22{ 23 u_char *p,*q; 24 MD5_CTX ctx; 25 int i,j,sep,cnt; 26 u_char *md5=0,*md5before=0,*trash=0,*name=0,*uid=0,*gid=0,*mode=0; 27 struct CTM_Syntax *sp; 28 FILE *b = 0; /* backup command */ 29 u_char buf[BUFSIZ]; 30 char md5_1[33]; 31 int ret = 0; 32 int match = 0; 33 struct CTM_Filter *filter = NULL; 34 35 if(Verbose>3) 36 printf("PassB -- Backing up files which would be changed.\n"); 37 38 MD5Init (&ctx); 39 snprintf(buf, sizeof(buf), fmtcheck(TarCmd, TARCMD), BackupFile); 40 b=popen(buf, "w"); 41 if(!b) { warn("%s", buf); return Exit_Garbage; } 42 43 GETFIELD(p,' '); if(strcmp("CTM_BEGIN",p)) WRONG 44 GETFIELD(p,' '); if(strcmp(Version,p)) WRONG 45 GETFIELD(p,' '); if(strcmp(Name,p)) WRONG 46 GETFIELD(p,' '); if(strcmp(Nbr,p)) WRONG 47 GETFIELD(p,' '); if(strcmp(TimeStamp,p)) WRONG 48 GETFIELD(p,'\n'); if(strcmp(Prefix,p)) WRONG 49 50 for(;;) { 51 Delete(md5); 52 Delete(uid); 53 Delete(gid); 54 Delete(mode); 55 Delete(md5before); 56 Delete(trash); 57 Delete(name); 58 cnt = -1; 59 60 GETFIELD(p,' '); 61 62 if (p[0] != 'C' || p[1] != 'T' || p[2] != 'M') WRONG 63 64 if(!strcmp(p+3,"_END")) 65 break; 66 67 for(sp=Syntax;sp->Key;sp++) 68 if(!strcmp(p+3,sp->Key)) 69 goto found; 70 WRONG 71 found: 72 for(i=0;(j = sp->List[i]);i++) { 73 if (sp->List[i+1] && (sp->List[i+1] & CTM_F_MASK) != CTM_F_Bytes) 74 sep = ' '; 75 else 76 sep = '\n'; 77 78 switch (j & CTM_F_MASK) { 79 case CTM_F_Name: GETNAMECOPY(name,sep,j, Verbose); break; 80 case CTM_F_Uid: GETFIELDCOPY(uid,sep); break; 81 case CTM_F_Gid: GETFIELDCOPY(gid,sep); break; 82 case CTM_F_Mode: GETFIELDCOPY(mode,sep); break; 83 case CTM_F_MD5: 84 if(j & CTM_Q_MD5_Before) 85 GETFIELDCOPY(md5before,sep); 86 else 87 GETFIELDCOPY(md5,sep); 88 break; 89 case CTM_F_Count: GETBYTECNT(cnt,sep); break; 90 case CTM_F_Bytes: GETDATA(trash,cnt); break; 91 default: WRONG 92 } 93 } 94 /* XXX This should go away. Disallow trailing '/' */ 95 j = strlen(name)-1; 96 if(name[j] == '/') name[j] = '\0'; 97 98 if (KeepIt && 99 (!strcmp(sp->Key,"DR") || !strcmp(sp->Key,"FR"))) 100 continue; 101 102 /* match the name against the elements of the filter list. The 103 action associated with the last matched filter determines whether 104 this file should be ignored or backed up. */ 105 match = (FilterList ? !(FilterList->Action) : CTM_FILTER_ENABLE); 106 for (filter = FilterList; filter; filter = filter->Next) { 107 if (0 == regexec(&filter->CompiledRegex, name, 0, 0, 0)) 108 match = filter->Action; 109 } 110 111 if (CTM_FILTER_DISABLE == match) 112 continue; 113 114 if (!strcmp(sp->Key,"FS") || !strcmp(sp->Key,"FN") || 115 !strcmp(sp->Key,"AS") || !strcmp(sp->Key,"DR") || 116 !strcmp(sp->Key,"FR")) { 117 /* send name to the archiver for a backup */ 118 cnt = strlen(name); 119 if (cnt != fwrite(name,1,cnt,b) || EOF == fputc('\n',b)) { 120 warn("%s", name); 121 pclose(b); 122 WRONG; 123 } 124 } 125 } 126 127 ret = pclose(b); 128 129 Delete(md5); 130 Delete(uid); 131 Delete(gid); 132 Delete(mode); 133 Delete(md5before); 134 Delete(trash); 135 Delete(name); 136 137 q = MD5End (&ctx,md5_1); 138 GETFIELD(p,'\n'); /* <MD5> */ 139 if(strcmp(q,p)) WRONG 140 if (-1 != getc(fd)) WRONG 141 return ret; 142} 143