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