12926Sphk/*
22926Sphk * ----------------------------------------------------------------------------
32926Sphk * "THE BEER-WARE LICENSE" (Revision 42):
493150Sphk * <phk@FreeBSD.org> wrote this file.  As long as you retain this notice you
52926Sphk * can do whatever you want with this stuff. If we meet some day, and you think
62926Sphk * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
72926Sphk * ----------------------------------------------------------------------------
82926Sphk *
950479Speter * $FreeBSD$
102926Sphk *
112926Sphk */
122926Sphk
132886Sphk#include "ctm.h"
142886Sphk
152886Sphk/*---------------------------------------------------------------------------*/
162886Sphkvoid
172886SphkFatal_(int ln, char *fn, char *kind)
182886Sphk{
192886Sphk    if(Verbose > 2)
202886Sphk	fprintf(stderr,"Fatal error. (%s:%d)\n",fn,ln);
212886Sphk    fprintf(stderr,"%s Fatal error: %s\n",FileName, kind);
222886Sphk}
232886Sphk#define Fatal(foo) Fatal_(__LINE__,__FILE__,foo)
242886Sphk#define Assert() Fatal_(__LINE__,__FILE__,"Assert failed.")
252886Sphk
262886Sphk/*---------------------------------------------------------------------------*/
272886Sphk/* get next field, check that the terminating whitespace is what we expect */
282886Sphku_char *
292886SphkFfield(FILE *fd, MD5_CTX *ctx,u_char term)
302886Sphk{
312886Sphk    static u_char buf[BUFSIZ];
322886Sphk    int i,l;
332886Sphk
342886Sphk    for(l=0;;) {
352886Sphk	if((i=getc(fd)) == EOF) {
362886Sphk	    Fatal("Truncated patch.");
372886Sphk	    return 0;
382886Sphk	}
392886Sphk	buf[l++] = i;
402886Sphk	if(isspace(i))
412886Sphk	    break;
422886Sphk	if(l >= sizeof buf) {
432886Sphk	    Fatal("Corrupt patch.");
442886Sphk	    printf("Token is too long.\n");
452886Sphk	    return 0;
462886Sphk	}
472886Sphk    }
482886Sphk    buf[l] = '\0';
492886Sphk    MD5Update(ctx,buf,l);
502886Sphk    if(buf[l-1] != term) {
512886Sphk        Fatal("Corrupt patch.");
522948Sphk	fprintf(stderr,"Expected \"%s\" but didn't find it {%02x}.\n",
532948Sphk	    term == '\n' ? "\\n" : " ",buf[l-1]);
542948Sphk	if(Verbose > 4)
552948Sphk	    fprintf(stderr,"{%s}\n",buf);
562886Sphk	return 0;
572886Sphk    }
582886Sphk    buf[--l] = '\0';
592948Sphk    if(Verbose > 4)
602948Sphk        fprintf(stderr,"<%s>\n",buf);
612886Sphk    return buf;
622886Sphk}
632886Sphk
642886Sphkint
652886SphkFbytecnt(FILE *fd, MD5_CTX *ctx, u_char term)
662886Sphk{
672886Sphk    u_char *p,*q;
682948Sphk    int u_chars=0;
692886Sphk
702886Sphk    p = Ffield(fd,ctx,term);
712886Sphk    if(!p) return -1;
722948Sphk    for(q=p;*q;q++) {
732886Sphk	if(!isdigit(*q)) {
742886Sphk	    Fatal("Bytecount contains non-digit.");
752886Sphk	    return -1;
762886Sphk	}
772948Sphk	u_chars *= 10;
782948Sphk	u_chars += (*q - '0');
792948Sphk    }
802886Sphk    return u_chars;
812886Sphk}
822886Sphk
832886Sphku_char *
842886SphkFdata(FILE *fd, int u_chars, MD5_CTX *ctx)
852886Sphk{
862886Sphk    u_char *p = Malloc(u_chars+1);
872886Sphk
882886Sphk    if(u_chars+1 != fread(p,1,u_chars+1,fd)) {
892886Sphk	Fatal("Truncated patch.");
902886Sphk	return 0;
912886Sphk    }
922886Sphk    MD5Update(ctx,p,u_chars+1);
932886Sphk    if(p[u_chars] != '\n') {
942886Sphk	if(Verbose > 3)
952886Sphk	    printf("FileData wasn't followed by a newline.\n");
962886Sphk        Fatal("Corrupt patch.");
972886Sphk	return 0;
982886Sphk    }
992886Sphk    p[u_chars] = '\0';
1002886Sphk    return p;
1012886Sphk}
10213917Sphk
10313917Sphk/*---------------------------------------------------------------------------*/
10413917Sphk/* get the filename in the next field, prepend BaseDir and give back the result
10513917Sphk   strings. The sustitute filename is return (the one with the suffix SUBSUFF)
10613917Sphk   if it exists and the qualifier contains CTM_Q_Name_Subst
10713917Sphk   NOTA: Buffer is already initialize with BaseDir, CatPtr is the insertion
10813917Sphk   point on this buffer + the length test in Ffield() is enough for Fname() */
10913917Sphk
11013917Sphku_char *
11113917SphkFname(FILE *fd, MD5_CTX *ctx,u_char term,int qual, int verbose)
11213917Sphk{
11313917Sphk    u_char * p;
11413917Sphk    struct stat st;
11513917Sphk
11613917Sphk    if ((p = Ffield(fd,ctx,term)) == NULL) return(NULL);
11713917Sphk
11813917Sphk    strcpy(CatPtr, p);
11913917Sphk
12013917Sphk    if (!(qual & CTM_Q_Name_Subst)) return(Buffer);
12113917Sphk
12213917Sphk    p = Buffer + strlen(Buffer);
12313917Sphk
12413917Sphk    strcat(Buffer, SUBSUFF);
12513917Sphk
12613917Sphk    if ( -1 == stat(Buffer, &st) ) {
12713917Sphk	*p = '\0';
12813917Sphk    } else {
12913917Sphk	if(verbose > 2)
13013917Sphk	    fprintf(stderr,"Using %s as substitute file\n", Buffer);
13113917Sphk    }
13213917Sphk
13313917Sphk    return (Buffer);
13413917Sphk}
135