Add the DragonFly cvs id and perform general cleanups on cvs/rcs/sccs ids. Most
[dragonfly.git] / usr.sbin / ctm / ctm / ctm_passb.c
1 /*
2  * ----------------------------------------------------------------------------
3  * "THE BEER-WARE LICENSE" (Revision 42):
4  * <koshy@india.hp.com> 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.   Joseph Koshy
7  * ----------------------------------------------------------------------------
8  *
9  * $FreeBSD: src/usr.sbin/ctm/ctm/ctm_passb.c,v 1.5.2.1 2001/07/05 07:46:57 kris Exp $
10  * $DragonFly: src/usr.sbin/ctm/ctm/Attic/ctm_passb.c,v 1.2 2003/06/17 04:29:53 dillon Exp $
11  *
12  */
13
14 #include "ctm.h"
15 #define BADREAD 32
16
17 /*---------------------------------------------------------------------------*/
18 /* PassB -- Backup modified files.
19  */
20
21 int
22 PassB(FILE *fd)
23 {
24     u_char *p,*q;
25     MD5_CTX ctx;
26     int i,j,sep,cnt;
27     u_char *md5=0,*md5before=0,*trash=0,*name=0,*uid=0,*gid=0,*mode=0;
28     struct CTM_Syntax *sp;
29     FILE *b = 0;        /* backup command */
30     u_char buf[BUFSIZ];
31     char md5_1[33];
32     int ret = 0;
33     int match = 0;
34     struct CTM_Filter *filter = NULL;
35
36     if(Verbose>3)
37         printf("PassB -- Backing up files which would be changed.\n");
38
39     MD5Init (&ctx);
40     snprintf(buf, sizeof(buf), fmtcheck(TarCmd, TARCMD), BackupFile);
41     b=popen(buf, "w");
42     if(!b) { warn("%s", buf); return Exit_Garbage; }
43
44     GETFIELD(p,' '); if(strcmp("CTM_BEGIN",p)) WRONG
45     GETFIELD(p,' '); if(strcmp(Version,p)) WRONG
46     GETFIELD(p,' '); if(strcmp(Name,p)) WRONG
47     GETFIELD(p,' '); if(strcmp(Nbr,p)) WRONG
48     GETFIELD(p,' '); if(strcmp(TimeStamp,p)) WRONG
49     GETFIELD(p,'\n'); if(strcmp(Prefix,p)) WRONG
50
51     for(;;) {
52         Delete(md5);
53         Delete(uid);
54         Delete(gid);
55         Delete(mode);
56         Delete(md5before);
57         Delete(trash);
58         Delete(name);
59         cnt = -1;
60
61         GETFIELD(p,' ');
62
63         if (p[0] != 'C' || p[1] != 'T' || p[2] != 'M') WRONG
64
65         if(!strcmp(p+3,"_END"))
66             break;
67
68         for(sp=Syntax;sp->Key;sp++)
69             if(!strcmp(p+3,sp->Key))
70                 goto found;
71         WRONG
72     found:
73         for(i=0;(j = sp->List[i]);i++) {
74             if (sp->List[i+1] && (sp->List[i+1] & CTM_F_MASK) != CTM_F_Bytes)
75                 sep = ' ';
76             else
77                 sep = '\n';
78
79             switch (j & CTM_F_MASK) {
80                 case CTM_F_Name: GETNAMECOPY(name,sep,j, Verbose); break;
81                 case CTM_F_Uid:  GETFIELDCOPY(uid,sep); break;
82                 case CTM_F_Gid:  GETFIELDCOPY(gid,sep); break;
83                 case CTM_F_Mode: GETFIELDCOPY(mode,sep); break;
84                 case CTM_F_MD5:
85                     if(j & CTM_Q_MD5_Before)
86                         GETFIELDCOPY(md5before,sep);
87                     else
88                         GETFIELDCOPY(md5,sep);
89                     break;
90                 case CTM_F_Count: GETBYTECNT(cnt,sep); break;
91                 case CTM_F_Bytes: GETDATA(trash,cnt); break;
92                 default: WRONG
93                 }
94             }
95         /* XXX This should go away.  Disallow trailing '/' */
96         j = strlen(name)-1;
97         if(name[j] == '/') name[j] = '\0';
98
99         if (KeepIt && 
100             (!strcmp(sp->Key,"DR") || !strcmp(sp->Key,"FR")))
101             continue;
102                 
103         /* match the name against the elements of the filter list.  The
104            action associated with the last matched filter determines whether
105            this file should be ignored or backed up. */
106         match = (FilterList ? !(FilterList->Action) : CTM_FILTER_ENABLE);
107         for (filter = FilterList; filter; filter = filter->Next) {
108             if (0 == regexec(&filter->CompiledRegex, name, 0, 0, 0))
109                 match = filter->Action;
110         }
111
112         if (CTM_FILTER_DISABLE == match)
113                 continue;
114
115         if (!strcmp(sp->Key,"FS") || !strcmp(sp->Key,"FN") ||
116             !strcmp(sp->Key,"AS") || !strcmp(sp->Key,"DR") || 
117             !strcmp(sp->Key,"FR")) {
118             /* send name to the archiver for a backup */
119             cnt = strlen(name);
120             if (cnt != fwrite(name,1,cnt,b) || EOF == fputc('\n',b)) {
121                 warn("%s", name);
122                 pclose(b);
123                 WRONG;
124             }
125         }
126     }
127
128     ret = pclose(b);
129
130     Delete(md5);
131     Delete(uid);
132     Delete(gid);
133     Delete(mode);
134     Delete(md5before);
135     Delete(trash);
136     Delete(name);
137
138     q = MD5End (&ctx,md5_1);
139     GETFIELD(p,'\n');                   /* <MD5> */
140     if(strcmp(q,p)) WRONG
141     if (-1 != getc(fd)) WRONG
142     return ret;
143 }