ctm.c revision 2887
1/* $Id$ 2 * 3 * ---------------------------------------------------------------------------- 4 * "THE BEER-WARE LICENSE" (Revision 42): 5 * <phk@login.dkuug.dk> wrote this file. As long as you retain this notice you 6 * can do whatever you want with this stuff. If we meet some day, and you think 7 * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp 8 * ---------------------------------------------------------------------------- 9 * 10 * $Id$ 11 * 12 * This is the client program of 'CTM'. It will apply a CTM-patch to a 13 * collection of files. 14 * 15 * Options we'd like to see: 16 * 17 * -a Attempt best effort. 18 * -b <dir> Base-dir 19 * -B <file> Backup to tar-file. 20 * -c Check it out, "ma non troppo" 21 * -d <int> Debug TBD. 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 * Exit-codes, bitmap, logical or of: 32 * 1 Couldn't do something we wanted to, not fatal. 33 * 2 Couldn't do something we wanted to, fatal. 34 * 4 Input file corrupt. 35 * 8 Cannot apply input file. 36 * 16 Corruption while applying input file. 37 * 38 */ 39 40#define EXTERN /* */ 41#include "ctm.h" 42 43extern int Proc(char *); 44 45int 46main(int argc, char **argv) 47{ 48 int stat=0; 49 int i,j,c; 50 extern int optopt,optind; 51 extern char * optarg; 52 53 Verbose = 1; 54 Paranoid = 1; 55 setbuf(stderr,0); 56 setbuf(stdout,0); 57 58 while((c=getopt(argc,argv,"ab:B:cd:m:pPqr:R:T:Vv")) != -1) { 59 switch (c) { 60 case 'p': Paranoid--; break; /* Less Paranoid */ 61 case 'P': Paranoid++; break; /* More Paranoid */ 62 case 'q': Verbose--; break; /* Quiet */ 63 case 'v': Verbose++; break; /* Verbose */ 64 case 'T': TmpDir = optarg; break; 65 case ':': 66 fprintf(stderr,"Option '%c' requires an argument.\n",optopt); 67 stat++; 68 break; 69 case '?': 70 fprintf(stderr,"Option '%c' not supported.\n",optopt); 71 stat++; 72 break; 73 default: 74 fprintf(stderr,"Option '%c' not yet implemented.\n",optopt); 75 break; 76 } 77 } 78 79 if(stat) { 80 fprintf(stderr,"%d errors during option processing\n",stat); 81 exit(1); 82 } 83 stat = 0; 84 argc -= optind; 85 argv += optind; 86 87 if(!argc) 88 stat |= Proc("-"); 89 90 while(argc--) 91 stat |= Proc(*argv++); 92 93 return stat; 94} 95 96int 97Proc(char *filename) 98{ 99 FILE *f; 100 int i; 101 char *p = strrchr(filename,'.'); 102 103 if(!strcmp(filename,"-")) { 104 p = 0; 105 f = stdin; 106 } else if(!strcmp(p,".gz") || !strcmp(p,".Z")) { 107 p = Malloc(100); 108 strcpy(p,"gunzip < "); 109 strcat(p,filename); 110 f = popen(p,"r"); 111 } else { 112 p = 0; 113 f = fopen(filename,"r"); 114 } 115 if(!f) { 116 perror(filename); 117 return 1; 118 } 119 120 if(Verbose > 1) 121 fprintf(stderr,"Working on <%s>\n",filename); 122 123 if(FileName) Free(FileName); 124 FileName = String(filename); 125 126 /* If we cannot seek, we're doomed, so copy to a tmp-file in that case */ 127 if(!p && -1 == fseek(f,0,SEEK_END)) { 128 char *fn = tempnam(NULL,"CMTclient"); 129 FILE *f2 = fopen(fn,"w+"); 130 int i; 131 132 if(!f2) { 133 perror(fn); 134 fclose(f); 135 return 2; 136 } 137 unlink(fn); 138 fprintf(stderr,"Writing tmp-file \"%s\"\n",fn); 139 while(EOF != (i=getc(f))) 140 putc(i,f2); 141 fclose(f); 142 f = f2; 143 } 144 145 if(!p) 146 rewind(f); 147 if((i=Pass1(f))) 148 return i; 149 if(!p) { 150 rewind(f); 151 } else { 152 pclose(f); 153 f = popen(p,"r"); 154 } 155 if((i=Pass2(f))) 156 return i; 157 if(!p) { 158 rewind(f); 159 } else { 160 pclose(f); 161 f = popen(p,"r"); 162 } 163 if((i=Pass3(f))) 164 return i; 165 if(!p) { 166 fclose(f); 167 } else { 168 pclose(f); 169 } 170 return 0; 171} 172