summaryrefslogtreecommitdiffstats
path: root/usr.sbin/ctm/ctm/ctm_input.c
blob: 284272d9391093d51367a44cc0fa2c4f56700643 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/*
 * ----------------------------------------------------------------------------
 * "THE BEER-WARE LICENSE" (Revision 42):
 * <phk@login.dknet.dk> wrote this file.  As long as you retain this notice you
 * can do whatever you want with this stuff. If we meet some day, and you think
 * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
 * ----------------------------------------------------------------------------
 *
 * $Id: ctm_input.c,v 1.4 1994/09/22 02:49:18 phk Exp $
 *
 */

#include "ctm.h"

/*---------------------------------------------------------------------------*/
void
Fatal_(int ln, char *fn, char *kind)
{
    if(Verbose > 2)
	fprintf(stderr,"Fatal error. (%s:%d)\n",fn,ln);
    fprintf(stderr,"%s Fatal error: %s\n",FileName, kind);
}
#define Fatal(foo) Fatal_(__LINE__,__FILE__,foo)
#define Assert() Fatal_(__LINE__,__FILE__,"Assert failed.")

/*---------------------------------------------------------------------------*/
/* get next field, check that the terminating whitespace is what we expect */
u_char *
Ffield(FILE *fd, MD5_CTX *ctx,u_char term)
{
    static u_char buf[BUFSIZ];
    int i,l;

    for(l=0;;) {
	if((i=getc(fd)) == EOF) {
	    Fatal("Truncated patch.");
	    return 0;
	}
	buf[l++] = i;
	if(isspace(i))
	    break;
	if(l >= sizeof buf) {
	    Fatal("Corrupt patch.");
	    printf("Token is too long.\n");
	    return 0;
	}
    }
    buf[l] = '\0';
    MD5Update(ctx,buf,l);
    if(buf[l-1] != term) {
        Fatal("Corrupt patch.");
	fprintf(stderr,"Expected \"%s\" but didn't find it {%02x}.\n",
	    term == '\n' ? "\\n" : " ",buf[l-1]);
	if(Verbose > 4)
	    fprintf(stderr,"{%s}\n",buf);
	return 0;
    }
    buf[--l] = '\0';
    if(Verbose > 4)
        fprintf(stderr,"<%s>\n",buf);
    return buf;
}

int
Fbytecnt(FILE *fd, MD5_CTX *ctx, u_char term)
{
    u_char *p,*q;
    int u_chars=0;

    p = Ffield(fd,ctx,term);
    if(!p) return -1;
    for(q=p;*q;q++) {
	if(!isdigit(*q)) {
	    Fatal("Bytecount contains non-digit.");
	    return -1;
	}
	u_chars *= 10;
	u_chars += (*q - '0');
    }
    if(u_chars > MAXSIZE) {
	Fatal("Bytecount too large.");
	return -1;
    }
    return u_chars;
}

u_char *
Fdata(FILE *fd, int u_chars, MD5_CTX *ctx)
{
    u_char *p = Malloc(u_chars+1);

    if(u_chars+1 != fread(p,1,u_chars+1,fd)) {
	Fatal("Truncated patch.");
	return 0;
    }
    MD5Update(ctx,p,u_chars+1);
    if(p[u_chars] != '\n') {
	if(Verbose > 3)
	    printf("FileData wasn't followed by a newline.\n");
        Fatal("Corrupt patch.");
	return 0;
    }
    p[u_chars] = '\0';
    return p;
}

/*---------------------------------------------------------------------------*/
/* get the filename in the next field, prepend BaseDir and give back the result
   strings. The sustitute filename is return (the one with the suffix SUBSUFF) 
   if it exists and the qualifier contains CTM_Q_Name_Subst
   NOTA: Buffer is already initialize with BaseDir, CatPtr is the insertion
   point on this buffer + the length test in Ffield() is enough for Fname() */

u_char *
Fname(FILE *fd, MD5_CTX *ctx,u_char term,int qual, int verbose)
{
    u_char * p;
    struct stat st;

    if ((p = Ffield(fd,ctx,term)) == NULL) return(NULL);

    strcpy(CatPtr, p);

    if (!(qual & CTM_Q_Name_Subst)) return(Buffer);

    p = Buffer + strlen(Buffer);

    strcat(Buffer, SUBSUFF);

    if ( -1 == stat(Buffer, &st) ) {
	*p = '\0';
    } else {
	if(verbose > 2)
	    fprintf(stderr,"Using %s as substitute file\n", Buffer);
    }

    return (Buffer);
}
OpenPOWER on IntegriCloud