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 * ----------------------------------------------------------------------------
9 * $FreeBSD: src/usr.sbin/ctm/ctm/ctm_pass2.c,v 1.18.2.1 2001/07/05 07:46:57 kris Exp $
10 * $DragonFly: src/usr.sbin/ctm/ctm/Attic/ctm_pass2.c,v 1.2 2003/06/17 04:29:53 dillon Exp $
17 /*---------------------------------------------------------------------------*/
18 /* Pass2 -- Validate the incoming CTM-file.
26 int i,j,sep,cnt,fdesc;
27 u_char *trash=0,*name=0;
28 struct CTM_Syntax *sp;
33 struct CTM_Filter *filter;
35 static char *template = NULL;
38 printf("Pass2 -- Checking if CTM-patch will apply\n");
41 GETFIELD(p,' '); if(strcmp("CTM_BEGIN",p)) WRONG
42 GETFIELD(p,' '); if(strcmp(Version,p)) WRONG
43 GETFIELD(p,' '); if(strcmp(Name,p)) WRONG
44 /* XXX Lookup name in /etc/ctm,conf, read stuff */
45 GETFIELD(p,' '); if(strcmp(Nbr,p)) WRONG
46 /* XXX Verify that this is the next patch to apply */
47 GETFIELD(p,' '); if(strcmp(TimeStamp,p)) WRONG
48 GETFIELD(p,'\n'); if(strcmp(Prefix,p)) WRONG
49 /* XXX drop or use ? */
57 /* if a filter list was specified, check file name against
59 if no filter was given operate on all files. */
61 !(FilterList->Action) : CTM_FILTER_ENABLE);
65 if (p[0] != 'C' || p[1] != 'T' || p[2] != 'M') WRONG
67 if(!strcmp(p+3,"_END"))
70 for(sp=Syntax;sp->Key;sp++)
71 if(!strcmp(p+3,sp->Key))
75 for(i=0;(j = sp->List[i]);i++) {
76 if (sp->List[i+1] && (sp->List[i+1] & CTM_F_MASK) != CTM_F_Bytes)
81 switch (j & CTM_F_MASK) {
83 GETNAMECOPY(name,sep,j,0);
84 /* If `keep' was specified, we won't remove any files,
85 so don't check if the file exists */
87 (!strcmp(sp->Key,"FR") || !strcmp(sp->Key,"DR"))) {
88 match = CTM_FILTER_DISABLE;
92 for (filter = FilterList; filter; filter = filter->Next) if (0 == regexec(&filter->CompiledRegex, name,
94 match = filter->Action;
97 if (CTM_FILTER_DISABLE == match)
98 break; /* should ignore this file */
100 /* XXX Check DR DM rec's for parent-dir */
101 if(j & CTM_Q_Name_New) {
102 /* XXX Check DR FR rec's for item */
103 if(-1 != stat(name,&st)) {
104 fprintf(stderr," %s: %s exists.\n",
106 ret |= Exit_Forcible;
110 if(-1 == stat(name,&st)) {
111 fprintf(stderr," %s: %s doesn't exist.\n",
113 if (sp->Key[1] == 'R')
114 ret |= Exit_Forcible;
119 if (SetTime && getuid() && (getuid() != st.st_uid)) {
121 " %s: %s not mine, cannot set time.\n",
125 if (j & CTM_Q_Name_Dir) {
126 if((st.st_mode & S_IFMT) != S_IFDIR) {
128 " %s: %s exist, but isn't dir.\n",
134 if (j & CTM_Q_Name_File) {
135 if((st.st_mode & S_IFMT) != S_IFREG) {
137 " %s: %s exist, but isn't file.\n",
151 if(j & CTM_Q_MD5_Before) {
154 if(match && (st.st_mode & S_IFMT) == S_IFREG &&
155 (tmp = MD5File(name,md5_1)) != NULL &&
157 fprintf(stderr," %s: %s md5 mismatch.\n",
159 GETFIELDCOPY(md5,sep);
160 if(md5 != NULL && strcmp(tmp,md5) == 0) {
161 fprintf(stderr," %s: %s already applied.\n",
163 match = CTM_FILTER_DISABLE;
164 } else if(j & CTM_Q_MD5_Force) {
166 fprintf(stderr," Can and will force.\n");
168 fprintf(stderr," Could have forced.\n");
169 ret |= Exit_Forcible;
175 } else if(j & CTM_Q_MD5_After) {
177 GETFIELDCOPY(md5,sep);
181 /* Unqualified MD5 */
193 if (asprintf(&template, "%s/CTMclientXXXXXX",
195 fprintf(stderr, " %s: malloc failed.\n",
201 if(!strcmp(sp->Key,"FN")) {
202 if ((p = strdup(template)) == NULL) {
203 fprintf(stderr, " %s: malloc failed.\n",
208 if ((fdesc = mkstemp(p)) == -1) {
209 fprintf(stderr, " %s: mkstemp failed.\n",
215 if (close(fdesc) == -1) {
216 fprintf(stderr, " %s: close failed.\n",
223 j = ctm_edit(trash,cnt,name,p);
225 fprintf(stderr," %s: %s edit returned %d.\n",
231 } else if(strcmp(md5,MD5File(p,md5_1))) {
232 fprintf(stderr," %s: %s edit fails.\n",
241 } else if (!strcmp(sp->Key,"FE")) {
242 if ((p = strdup(template)) == NULL) {
243 fprintf(stderr, " %s: malloc failed.\n",
248 if ((fdesc = mkstemp(p)) == -1) {
249 fprintf(stderr, " %s: mkstemp failed.\n",
255 if (close(fdesc) == -1) {
256 fprintf(stderr, " %s: close failed.\n",
263 ed = popen("ed","w");
267 fprintf(ed,"e %s\n", name);
268 if (cnt != fwrite(trash,1,cnt,ed)) {
273 fprintf(ed,"w %s\n",p);
278 if(strcmp(md5,MD5File(p,md5_1))) {
279 fprintf(stderr,"%s %s MD5 didn't come out right\n",
297 q = MD5End (&ctx,md5_1);
298 GETFIELD(p,'\n'); /* <MD5> */
299 if(strcmp(q,p)) WRONG
300 if (-1 != getc(fd)) WRONG