ctm.c revision 2948
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$ 10 * 11 * This is the client program of 'CTM'. It will apply a CTM-patch to a 12 * collection of files. 13 * 14 * Options we'd like to see: 15 * 16 * -a Attempt best effort. 17 * -b <dir> Base-dir 18 * -B <file> Backup to tar-file. 19 * -c Check it out, "ma non troppo" 20 * -d <int> Debug TBD. 21 * -F Force 22 * -m <mail-addr> Email me instead. 23 * -p Less paranoid. 24 * -P Paranoid. 25 * -q Be quiet. 26 * -r <name> Reconstruct file. 27 * -R <file> Read list of files to reconstruct. 28 * -T <tmpdir>. Temporary files. 29 * -v Tell about each file. 30 * 31 */ 32 33#define EXTERN /* */ 34#include "ctm.h" 35 36extern int Proc(char *); 37 38int 39main(int argc, char **argv) 40{ 41 int stat=0; 42 int c; 43 extern int optopt,optind; 44 extern char * optarg; 45 46 Verbose = 1; 47 Paranoid = 1; 48 setbuf(stderr,0); 49 setbuf(stdout,0); 50 51 while((c=getopt(argc,argv,"ab:B:cd:Fm:pPqr:R:T:Vv")) != -1) { 52 switch (c) { 53 case 'c': CheckIt++; break; /* Only check it */ 54 case 'p': Paranoid--; break; /* Less Paranoid */ 55 case 'P': Paranoid++; break; /* More Paranoid */ 56 case 'q': Verbose--; break; /* Quiet */ 57 case 'v': Verbose++; break; /* Verbose */ 58 case 'T': TmpDir = optarg; break; 59 case 'F': Force = 1; break; 60 case ':': 61 fprintf(stderr,"Option '%c' requires an argument.\n",optopt); 62 stat++; 63 break; 64 case '?': 65 fprintf(stderr,"Option '%c' not supported.\n",optopt); 66 stat++; 67 break; 68 default: 69 fprintf(stderr,"Option '%c' not yet implemented.\n",optopt); 70 break; 71 } 72 } 73 74 if(stat) { 75 fprintf(stderr,"%d errors during option processing\n",stat); 76 exit(2); 77 } 78 stat = 0; 79 argc -= optind; 80 argv += optind; 81 82 if(!argc) 83 stat |= Proc("-"); 84 85 while(argc-- && !stat) 86 stat |= Proc(*argv++); 87 88 return stat; 89} 90 91int 92Proc(char *filename) 93{ 94 FILE *f; 95 int i; 96 char *p = strrchr(filename,'.'); 97 98 if(!strcmp(filename,"-")) { 99 p = 0; 100 f = stdin; 101 } else if(!strcmp(p,".gz") || !strcmp(p,".Z")) { 102 p = Malloc(100); 103 strcpy(p,"gunzip < "); 104 strcat(p,filename); 105 f = popen(p,"r"); 106 } else { 107 p = 0; 108 f = fopen(filename,"r"); 109 } 110 if(!f) { 111 perror(filename); 112 return 1; 113 } 114 115 if(Verbose > 1) 116 fprintf(stderr,"Working on <%s>\n",filename); 117 118 if(FileName) Free(FileName); 119 FileName = String(filename); 120 121 /* If we cannot seek, we're doomed, so copy to a tmp-file in that case */ 122 if(!p && -1 == fseek(f,0,SEEK_END)) { 123 char *fn = tempnam(TmpDir,"CMTclient"); 124 FILE *f2 = fopen(fn,"w+"); 125 int i; 126 127 if(!f2) { 128 perror(fn); 129 fclose(f); 130 return 4; 131 } 132 unlink(fn); 133 fprintf(stderr,"Writing tmp-file \"%s\"\n",fn); 134 while(EOF != (i=getc(f))) 135 putc(i,f2); 136 fclose(f); 137 f = f2; 138 } 139 140 if(!p) 141 rewind(f); 142 143 if((i=Pass1(f))) 144 return i; 145 146 if(!p) { 147 rewind(f); 148 } else { 149 pclose(f); 150 f = popen(p,"r"); 151 } 152 153 if((i=Pass2(f))) 154 return i; 155 156 if(!p) { 157 rewind(f); 158 } else { 159 pclose(f); 160 f = popen(p,"r"); 161 } 162 163 if(CheckIt) { 164 fprintf(stderr,"All ok\n"); 165 return 0; 166 } 167 168 if((i=Pass3(f))) 169 return i; 170 171 if(!p) { 172 fclose(f); 173 } else { 174 pclose(f); 175 Free(p); 176 } 177 178 fprintf(stderr,"All ok\n"); 179 return 0; 180} 181