1/*
2 * ----------------------------------------------------------------------------
3 * "THE BEER-WARE LICENSE" (Revision 42):
4 * <phk@FreeBSD.org> 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$
10 *
11 */
12
13#include <ctype.h>
14#include <err.h>
15#include <errno.h>
16#include <stdio.h>
17#include <stdlib.h>
18#include <string.h>
19#include <time.h>
20#include <unistd.h>
21#include <md5.h>
22#include <regex.h>
23#include <sys/types.h>
24#include <sys/stat.h>
25#include <sys/file.h>
26#include <sys/time.h>
27
28#define VERSION "2.0"
29
30#define SUBSUFF ".ctm"
31#define TMPSUFF ".ctmtmp"
32#define TARCMD  "tar -rf %s -T -"
33
34/* The fields... */
35#define CTM_F_MASK		0xff
36#define CTM_F_Name		0x01
37#define CTM_F_Uid		0x02
38#define CTM_F_Gid		0x03
39#define CTM_F_Mode		0x04
40#define CTM_F_MD5		0x05
41#define CTM_F_Count		0x06
42#define CTM_F_Bytes		0x07
43
44/* The qualifiers... */
45#define CTM_Q_MASK		0xff00
46#define CTM_Q_Name_File		0x0100
47#define CTM_Q_Name_Dir		0x0200
48#define CTM_Q_Name_New		0x0400
49#define CTM_Q_Name_Subst	0x0800
50#define CTM_Q_MD5_After		0x0100
51#define CTM_Q_MD5_Before	0x0200
52#define CTM_Q_MD5_Chunk		0x0400
53#define CTM_Q_MD5_Force		0x0800
54
55struct CTM_Syntax {
56    char	*Key;		/* CTM key for operation */
57    int		*List;		/* List of operations */
58    };
59
60extern struct CTM_Syntax Syntax[];
61
62struct CTM_Filter {
63    struct CTM_Filter	*Next;	/* next filter in the list */
64    int 		Action;	/* enable or disable */
65    regex_t 		CompiledRegex;	/* compiled regex */
66};
67
68#define	CTM_FILTER_DISABLE	0
69#define	CTM_FILTER_ENABLE	1
70
71#define Malloc malloc
72#define Free free
73#define Delete(foo) if (!foo) ; else {Free(foo); foo = 0; }
74#define String(foo) strdup(foo)
75
76#ifndef EXTERN
77#  define EXTERN extern
78#endif
79EXTERN u_char *Version;
80EXTERN u_char *Name;
81EXTERN u_char *Nbr;
82EXTERN u_char *TimeStamp;
83EXTERN u_char *Prefix;
84EXTERN u_char *FileName;
85EXTERN u_char *TmpDir;
86EXTERN u_char *CatPtr;
87EXTERN u_char *Buffer;
88EXTERN u_char *BackupFile;
89EXTERN u_char *TarCmd;
90
91/*
92 * Paranoid -- Just in case they should be after us...
93 *  0 not at all.
94 *  1 normal.
95 *  2 somewhat.
96 *  3 you bet!.
97 *
98 * Verbose -- What to tell mom...
99 *  0 Nothing which wouldn't surprise.
100 *  1 Normal.
101 *  2 Show progress '.'.
102 *  3 Show progress names, and actions.
103 *  4 even more...
104 *  and so on
105 *
106 * ExitCode -- our Epitaph
107 *  0 Perfect, all input digested, no problems
108 *  1 Bad input, no point in retrying.
109 *  2 Pilot error, commandline problem &c
110 *  4 Out of resources.
111 *  8 Destination-tree not correct.
112 * 16 Destination-tree not correct, can force.
113 * 32 Internal problems.
114 *
115 */
116
117EXTERN int Paranoid;
118EXTERN int Verbose;
119EXTERN int Exit;
120EXTERN int Force;
121EXTERN int CheckIt;
122EXTERN int KeepIt;
123EXTERN int ListIt;
124EXTERN int SetTime;
125EXTERN struct timeval Times[2];
126EXTERN struct CTM_Filter	*FilterList;
127EXTERN struct CTM_Filter	*LastFilter;
128
129#define Exit_OK		0
130#define Exit_Garbage	1
131#define Exit_Pilot	2
132#define Exit_Broke	4
133#define Exit_NotOK	8
134#define Exit_Forcible	16
135#define Exit_Mess	32
136#define Exit_Done	64
137#define Exit_Version	128
138#define Exit_NoMatch	256
139
140void Fatal_(int ln, char *fn, char *kind);
141#define Fatal(foo) Fatal_(__LINE__,__FILE__,foo)
142#define Assert() Fatal_(__LINE__,__FILE__,"Assert failed.")
143#define WRONG {Assert(); return Exit_Mess;}
144
145u_char * Ffield(FILE *fd, MD5_CTX *ctx,u_char term);
146u_char * Fname(FILE *fd, MD5_CTX *ctx,u_char term,int qual, int verbose);
147
148int Fbytecnt(FILE *fd, MD5_CTX *ctx, u_char term);
149
150u_char * Fdata(FILE *fd, int u_chars, MD5_CTX *ctx);
151
152#define GETFIELD(p,q) if(!((p)=Ffield(fd,&ctx,(q)))) return BADREAD
153#define GETFIELDCOPY(p,q) if(!((p)=Ffield(fd,&ctx,(q)))) return BADREAD; else p=String(p)
154#define GETBYTECNT(p,q) if(0 >((p)= Fbytecnt(fd,&ctx,(q)))) return BADREAD
155#define GETDATA(p,q) if(!((p) = Fdata(fd,(q),&ctx))) return BADREAD
156#define GETNAMECOPY(p,q,r,v) if(!((p)=Fname(fd,&ctx,(q),(r),(v)))) return BADREAD; else p=String(p)
157
158int Pass1(FILE *fd, unsigned applied);
159int Pass2(FILE *fd);
160int PassB(FILE *fd);
161int Pass3(FILE *fd);
162
163int ctm_edit(u_char *script, int length, char *filein, char *fileout);
164