ctm_input.c revision 50479
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 * $FreeBSD: head/usr.sbin/ctm/ctm/ctm_input.c 50479 1999-08-28 01:35:59Z peter $ 10 * 11 */ 12 13#include "ctm.h" 14 15/*---------------------------------------------------------------------------*/ 16void 17Fatal_(int ln, char *fn, char *kind) 18{ 19 if(Verbose > 2) 20 fprintf(stderr,"Fatal error. (%s:%d)\n",fn,ln); 21 fprintf(stderr,"%s Fatal error: %s\n",FileName, kind); 22} 23#define Fatal(foo) Fatal_(__LINE__,__FILE__,foo) 24#define Assert() Fatal_(__LINE__,__FILE__,"Assert failed.") 25 26/*---------------------------------------------------------------------------*/ 27/* get next field, check that the terminating whitespace is what we expect */ 28u_char * 29Ffield(FILE *fd, MD5_CTX *ctx,u_char term) 30{ 31 static u_char buf[BUFSIZ]; 32 int i,l; 33 34 for(l=0;;) { 35 if((i=getc(fd)) == EOF) { 36 Fatal("Truncated patch."); 37 return 0; 38 } 39 buf[l++] = i; 40 if(isspace(i)) 41 break; 42 if(l >= sizeof buf) { 43 Fatal("Corrupt patch."); 44 printf("Token is too long.\n"); 45 return 0; 46 } 47 } 48 buf[l] = '\0'; 49 MD5Update(ctx,buf,l); 50 if(buf[l-1] != term) { 51 Fatal("Corrupt patch."); 52 fprintf(stderr,"Expected \"%s\" but didn't find it {%02x}.\n", 53 term == '\n' ? "\\n" : " ",buf[l-1]); 54 if(Verbose > 4) 55 fprintf(stderr,"{%s}\n",buf); 56 return 0; 57 } 58 buf[--l] = '\0'; 59 if(Verbose > 4) 60 fprintf(stderr,"<%s>\n",buf); 61 return buf; 62} 63 64int 65Fbytecnt(FILE *fd, MD5_CTX *ctx, u_char term) 66{ 67 u_char *p,*q; 68 int u_chars=0; 69 70 p = Ffield(fd,ctx,term); 71 if(!p) return -1; 72 for(q=p;*q;q++) { 73 if(!isdigit(*q)) { 74 Fatal("Bytecount contains non-digit."); 75 return -1; 76 } 77 u_chars *= 10; 78 u_chars += (*q - '0'); 79 } 80 if(u_chars > MAXSIZE) { 81 Fatal("Bytecount too large."); 82 return -1; 83 } 84 return u_chars; 85} 86 87u_char * 88Fdata(FILE *fd, int u_chars, MD5_CTX *ctx) 89{ 90 u_char *p = Malloc(u_chars+1); 91 92 if(u_chars+1 != fread(p,1,u_chars+1,fd)) { 93 Fatal("Truncated patch."); 94 return 0; 95 } 96 MD5Update(ctx,p,u_chars+1); 97 if(p[u_chars] != '\n') { 98 if(Verbose > 3) 99 printf("FileData wasn't followed by a newline.\n"); 100 Fatal("Corrupt patch."); 101 return 0; 102 } 103 p[u_chars] = '\0'; 104 return p; 105} 106 107/*---------------------------------------------------------------------------*/ 108/* get the filename in the next field, prepend BaseDir and give back the result 109 strings. The sustitute filename is return (the one with the suffix SUBSUFF) 110 if it exists and the qualifier contains CTM_Q_Name_Subst 111 NOTA: Buffer is already initialize with BaseDir, CatPtr is the insertion 112 point on this buffer + the length test in Ffield() is enough for Fname() */ 113 114u_char * 115Fname(FILE *fd, MD5_CTX *ctx,u_char term,int qual, int verbose) 116{ 117 u_char * p; 118 struct stat st; 119 120 if ((p = Ffield(fd,ctx,term)) == NULL) return(NULL); 121 122 strcpy(CatPtr, p); 123 124 if (!(qual & CTM_Q_Name_Subst)) return(Buffer); 125 126 p = Buffer + strlen(Buffer); 127 128 strcat(Buffer, SUBSUFF); 129 130 if ( -1 == stat(Buffer, &st) ) { 131 *p = '\0'; 132 } else { 133 if(verbose > 2) 134 fprintf(stderr,"Using %s as substitute file\n", Buffer); 135 } 136 137 return (Buffer); 138} 139