1126288Smtm/*
298186Sgordon * ----------------------------------------------------------------------------
378344Sobrien * "THE BEER-WARE LICENSE" (Revision 42):
498186Sgordon * <phk@FreeBSD.org> wrote this file.  As long as you retain this notice you
578344Sobrien * can do whatever you want with this stuff. If we meet some day, and you think
678344Sobrien * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
778344Sobrien * ----------------------------------------------------------------------------
878344Sobrien *
978344Sobrien * $FreeBSD$
1078344Sobrien *
1178344Sobrien */
1278344Sobrien
1378344Sobrien#include <ctype.h>
1478344Sobrien#include <err.h>
1578344Sobrien#include <errno.h>
1678344Sobrien#include <stdio.h>
1778344Sobrien#include <stdlib.h>
1878344Sobrien#include <string.h>
1978344Sobrien#include <time.h>
2078344Sobrien#include <unistd.h>
2178344Sobrien#include <md5.h>
2278344Sobrien#include <regex.h>
2378344Sobrien#include <sys/types.h>
2478344Sobrien#include <sys/stat.h>
2578344Sobrien#include <sys/file.h>
2678344Sobrien#include <sys/time.h>
2778344Sobrien
2878344Sobrien#define VERSION "2.0"
2978344Sobrien
3078344Sobrien#define SUBSUFF ".ctm"
3178344Sobrien#define TMPSUFF ".ctmtmp"
3278344Sobrien#define TARCMD  "tar -rf %s -T -"
3378344Sobrien
3478344Sobrien/* The fields... */
3578344Sobrien#define CTM_F_MASK		0xff
3678344Sobrien#define CTM_F_Name		0x01
3778344Sobrien#define CTM_F_Uid		0x02
3878344Sobrien#define CTM_F_Gid		0x03
3978344Sobrien#define CTM_F_Mode		0x04
4078344Sobrien#define CTM_F_MD5		0x05
4178344Sobrien#define CTM_F_Count		0x06
4278344Sobrien#define CTM_F_Bytes		0x07
4398186Sgordon
4498186Sgordon/* The qualifiers... */
4598186Sgordon#define CTM_Q_MASK		0xff00
46131550Scperciva#define CTM_Q_Name_File		0x0100
47131550Scperciva#define CTM_Q_Name_Dir		0x0200
48131550Scperciva#define CTM_Q_Name_New		0x0400
49131550Scperciva#define CTM_Q_Name_Subst	0x0800
5098186Sgordon#define CTM_Q_MD5_After		0x0100
5198186Sgordon#define CTM_Q_MD5_Before	0x0200
5298186Sgordon#define CTM_Q_MD5_Chunk		0x0400
53103018Sgordon#define CTM_Q_MD5_Force		0x0800
54124832Smtm
55124832Smtmstruct CTM_Syntax {
5698186Sgordon    char	*Key;		/* CTM key for operation */
57103018Sgordon    int		*List;		/* List of operations */
5898186Sgordon    };
5998186Sgordon
6098186Sgordonextern struct CTM_Syntax Syntax[];
6198186Sgordon
6298186Sgordonstruct CTM_Filter {
6398186Sgordon    struct CTM_Filter	*Next;	/* next filter in the list */
6498186Sgordon    int 		Action;	/* enable or disable */
6598186Sgordon    regex_t 		CompiledRegex;	/* compiled regex */
6698186Sgordon};
6778344Sobrien
6878344Sobrien#define	CTM_FILTER_DISABLE	0
6978344Sobrien#define	CTM_FILTER_ENABLE	1
7078344Sobrien
7198186Sgordon#define Malloc malloc
7298186Sgordon#define Free free
7398186Sgordon#define Delete(foo) if (!foo) ; else {Free(foo); foo = 0; }
7498186Sgordon#define String(foo) strdup(foo)
7598186Sgordon
7698186Sgordon#ifndef EXTERN
7798186Sgordon#  define EXTERN extern
7898186Sgordon#endif
7998186SgordonEXTERN u_char *Version;
8098186SgordonEXTERN u_char *Name;
8198186SgordonEXTERN u_char *Nbr;
8298186SgordonEXTERN u_char *TimeStamp;
8398186SgordonEXTERN u_char *Prefix;
8498186SgordonEXTERN u_char *FileName;
8598186SgordonEXTERN u_char *TmpDir;
8698186SgordonEXTERN u_char *CatPtr;
8798186SgordonEXTERN u_char *Buffer;
88103018SgordonEXTERN u_char *BackupFile;
8998186SgordonEXTERN u_char *TarCmd;
9098186Sgordon
9198186Sgordon/*
9298186Sgordon * Paranoid -- Just in case they should be after us...
9398186Sgordon *  0 not at all.
9498186Sgordon *  1 normal.
9598186Sgordon *  2 somewhat.
9698186Sgordon *  3 you bet!.
9798186Sgordon *
9898186Sgordon * Verbose -- What to tell mom...
9998186Sgordon *  0 Nothing which wouldn't surprise.
10098186Sgordon *  1 Normal.
10198186Sgordon *  2 Show progress '.'.
10298186Sgordon *  3 Show progress names, and actions.
10398186Sgordon *  4 even more...
10498186Sgordon *  and so on
10598186Sgordon *
10698186Sgordon * ExitCode -- our Epitaph
10798186Sgordon *  0 Perfect, all input digested, no problems
10898186Sgordon *  1 Bad input, no point in retrying.
10998186Sgordon *  2 Pilot error, commandline problem &c
11098186Sgordon *  4 Out of resources.
11198186Sgordon *  8 Destination-tree not correct.
11298186Sgordon * 16 Destination-tree not correct, can force.
113146490Sschweikh * 32 Internal problems.
11498186Sgordon *
11598186Sgordon */
11698186Sgordon
11798186SgordonEXTERN int Paranoid;
11898186SgordonEXTERN int Verbose;
11998186SgordonEXTERN int Exit;
12098186SgordonEXTERN int Force;
12178344SobrienEXTERN int CheckIt;
12278344SobrienEXTERN int KeepIt;
12378344SobrienEXTERN int ListIt;
12478344SobrienEXTERN int SetTime;
12578344SobrienEXTERN struct timeval Times[2];
12678344SobrienEXTERN struct CTM_Filter	*FilterList;
12778344SobrienEXTERN struct CTM_Filter	*LastFilter;
12898186Sgordon
12978344Sobrien#define Exit_OK		0
13078344Sobrien#define Exit_Garbage	1
13178344Sobrien#define Exit_Pilot	2
13278344Sobrien#define Exit_Broke	4
13378344Sobrien#define Exit_NotOK	8
13478344Sobrien#define Exit_Forcible	16
13578344Sobrien#define Exit_Mess	32
13678344Sobrien#define Exit_Done	64
13778344Sobrien#define Exit_Version	128
13878344Sobrien#define Exit_NoMatch	256
13978344Sobrien
14078344Sobrienvoid Fatal_(int ln, char *fn, char *kind);
141106643Sgordon#define Fatal(foo) Fatal_(__LINE__,__FILE__,foo)
14278344Sobrien#define Assert() Fatal_(__LINE__,__FILE__,"Assert failed.")
14378344Sobrien#define WRONG {Assert(); return Exit_Mess;}
14478344Sobrien
14578344Sobrienu_char * Ffield(FILE *fd, MD5_CTX *ctx,u_char term);
14678344Sobrienu_char * Fname(FILE *fd, MD5_CTX *ctx,u_char term,int qual, int verbose);
14798186Sgordon
14898186Sgordonint Fbytecnt(FILE *fd, MD5_CTX *ctx, u_char term);
14978344Sobrien
15098186Sgordonu_char * Fdata(FILE *fd, int u_chars, MD5_CTX *ctx);
15198186Sgordon
15298186Sgordon#define GETFIELD(p,q) if(!((p)=Ffield(fd,&ctx,(q)))) return BADREAD
153126286Smtm#define GETFIELDCOPY(p,q) if(!((p)=Ffield(fd,&ctx,(q)))) return BADREAD; else p=String(p)
15498186Sgordon#define GETBYTECNT(p,q) if(0 >((p)= Fbytecnt(fd,&ctx,(q)))) return BADREAD
15598186Sgordon#define GETDATA(p,q) if(!((p) = Fdata(fd,(q),&ctx))) return BADREAD
15698186Sgordon#define GETNAMECOPY(p,q,r,v) if(!((p)=Fname(fd,&ctx,(q),(r),(v)))) return BADREAD; else p=String(p)
15798186Sgordon
15898186Sgordonint Pass1(FILE *fd, unsigned applied);
15978344Sobrienint Pass2(FILE *fd);
16098186Sgordonint PassB(FILE *fd);
16198186Sgordonint Pass3(FILE *fd);
16298186Sgordon
16398186Sgordonint ctm_edit(u_char *script, int length, char *filein, char *fileout);
16498186Sgordon