ctm_input.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 */
12
13#include "ctm.h"
14
15/*---------------------------------------------------------------------------*/
16char *
17String(char *s)
18{
19    char *p = malloc(strlen(s) + 1);
20    strcpy(p,s);
21    return p;
22}
23/*---------------------------------------------------------------------------*/
24void
25Fatal_(int ln, char *fn, char *kind)
26{
27    if(Verbose > 2)
28	fprintf(stderr,"Fatal error. (%s:%d)\n",fn,ln);
29    fprintf(stderr,"%s Fatal error: %s\n",FileName, kind);
30}
31#define Fatal(foo) Fatal_(__LINE__,__FILE__,foo)
32#define Assert() Fatal_(__LINE__,__FILE__,"Assert failed.")
33
34/*---------------------------------------------------------------------------*/
35/* get next field, check that the terminating whitespace is what we expect */
36u_char *
37Ffield(FILE *fd, MD5_CTX *ctx,u_char term)
38{
39    static u_char buf[BUFSIZ];
40    int i,l;
41
42    for(l=0;;) {
43	if((i=getc(fd)) == EOF) {
44	    Fatal("Truncated patch.");
45	    return 0;
46	}
47	buf[l++] = i;
48	if(isspace(i))
49	    break;
50	if(l >= sizeof buf) {
51	    Fatal("Corrupt patch.");
52	    printf("Token is too long.\n");
53	    return 0;
54	}
55    }
56    buf[l] = '\0';
57    MD5Update(ctx,buf,l);
58    if(buf[l-1] != term) {
59        Fatal("Corrupt patch.");
60	fprintf(stderr,"Expected \"%s\" but didn't find it {%02x}.\n",
61	    term == '\n' ? "\\n" : " ",buf[l-1]);
62	if(Verbose > 4)
63	    fprintf(stderr,"{%s}\n",buf);
64	return 0;
65    }
66    buf[--l] = '\0';
67    if(Verbose > 4)
68        fprintf(stderr,"<%s>\n",buf);
69    return buf;
70}
71
72int
73Fbytecnt(FILE *fd, MD5_CTX *ctx, u_char term)
74{
75    u_char *p,*q;
76    int u_chars=0;
77
78    p = Ffield(fd,ctx,term);
79    if(!p) return -1;
80    for(q=p;*q;q++) {
81	if(!isdigit(*q)) {
82	    Fatal("Bytecount contains non-digit.");
83	    return -1;
84	}
85	u_chars *= 10;
86	u_chars += (*q - '0');
87    }
88    if(u_chars > MAXSIZE) {
89	Fatal("Bytecount too large.");
90	return -1;
91    }
92    return u_chars;
93}
94
95u_char *
96Fdata(FILE *fd, int u_chars, MD5_CTX *ctx)
97{
98    u_char *p = Malloc(u_chars+1);
99
100    if(u_chars+1 != fread(p,1,u_chars+1,fd)) {
101	Fatal("Truncated patch.");
102	return 0;
103    }
104    MD5Update(ctx,p,u_chars+1);
105    if(p[u_chars] != '\n') {
106	if(Verbose > 3)
107	    printf("FileData wasn't followed by a newline.\n");
108        Fatal("Corrupt patch.");
109	return 0;
110    }
111    p[u_chars] = '\0';
112    return p;
113}
114