]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/cvs/src/wrapper.c
Import of slightly trimmed cvs-1.8 distribution. Generated files
[FreeBSD/FreeBSD.git] / contrib / cvs / src / wrapper.c
1 #include "cvs.h"
2
3 /*
4   Original Author:  athan@morgan.com <Andrew C. Athan> 2/1/94
5   Modified By:      vdemarco@bou.shl.com
6
7   This package was written to support the NEXTSTEP concept of
8   "wrappers."  These are essentially directories that are to be
9   treated as "files."  This package allows such wrappers to be
10   "processed" on the way in and out of CVS.  The intended use is to
11   wrap up a wrapper into a single tar, such that that tar can be
12   treated as a single binary file in CVS.  To solve the problem
13   effectively, it was also necessary to be able to prevent rcsmerge
14   application at appropriate times.
15
16   ------------------
17   Format of wrapper file ($CVSROOT/CVSROOT/cvswrappers or .cvswrappers)
18
19   wildcard      [option value][option value]...
20
21   where option is one of
22   -f            from cvs filter         value: path to filter
23   -t            to cvs filter           value: path to filter
24   -m            update methodology      value: MERGE or COPY
25
26   and value is a single-quote delimited value.
27
28   E.g:
29   *.nib         -f 'gunzipuntar' -t 'targzip' -m 'COPY'
30 */
31
32
33 typedef struct {
34     char *wildCard;
35     char *tocvsFilter;
36     char *fromcvsFilter;
37     char *conflictHook;
38     WrapMergeMethod mergeMethod;
39 } WrapperEntry;
40
41 static WrapperEntry **wrap_list=NULL;
42 static WrapperEntry **wrap_saved_list=NULL;
43
44 static int wrap_size=0;
45 static int wrap_count=0;
46 static int wrap_tempcount=0;
47 static int wrap_saved_count=0;
48 static int wrap_saved_tempcount=0;
49
50 #define WRAPPER_GROW    8
51
52 void wrap_add_entry PROTO((WrapperEntry *e,int temp));
53 void wrap_kill PROTO((void));
54 void wrap_kill_temp PROTO((void));
55 void wrap_free_entry PROTO((WrapperEntry *e));
56 void wrap_free_entry_internal PROTO((WrapperEntry *e));
57 void wrap_restore_saved PROTO((void));
58
59 void wrap_setup()
60 {
61     char file[PATH_MAX];
62     struct passwd *pw;
63
64         /* Then add entries found in repository, if it exists */
65     (void) sprintf (file, "%s/%s/%s", CVSroot, CVSROOTADM, CVSROOTADM_WRAPPER);
66     if (isfile (file)){
67         wrap_add_file(file,0);
68     }
69
70         /* Then add entries found in home dir, (if user has one) and file exists */
71     if ((pw = (struct passwd *) getpwuid (getuid ())) && pw->pw_dir){
72         (void) sprintf (file, "%s/%s", pw->pw_dir, CVSDOTWRAPPER);
73         if (isfile (file)){
74             wrap_add_file (file, 0);
75         }
76     }
77
78         /* Then add entries found in CVSWRAPPERS environment variable. */
79     wrap_add (getenv (WRAPPER_ENV), 0);
80 }
81
82 /*
83  * Open a file and read lines, feeding each line to a line parser. Arrange
84  * for keeping a temporary list of wrappers at the end, if the "temp"
85  * argument is set.
86  */
87 void
88 wrap_add_file (file, temp)
89     const char *file;
90     int temp;
91 {
92     FILE *fp;
93     char line[1024];
94
95     wrap_restore_saved();
96     wrap_kill_temp();
97
98         /* load the file */
99     if (!(fp = fopen (file, "r")))
100         return;
101     while (fgets (line, sizeof (line), fp))
102         wrap_add (line, temp);
103     (void) fclose (fp);
104 }
105
106 void
107 wrap_kill()
108 {
109     wrap_kill_temp();
110     while(wrap_count)
111         wrap_free_entry(wrap_list[--wrap_count]);
112 }
113
114 void
115 wrap_kill_temp()
116 {
117     WrapperEntry **temps=wrap_list+wrap_count;
118
119     while(wrap_tempcount)
120         wrap_free_entry(temps[--wrap_tempcount]);
121 }
122
123 void
124 wrap_free_entry(e)
125      WrapperEntry *e;
126 {
127     wrap_free_entry_internal(e);
128     free(e);
129 }
130
131 void
132 wrap_free_entry_internal(e)
133     WrapperEntry *e;
134 {
135     free(e->wildCard);
136     if(e->tocvsFilter)
137         free(e->tocvsFilter);
138     if(e->fromcvsFilter)
139         free(e->fromcvsFilter);
140     if(e->conflictHook)
141         free(e->conflictHook);
142 }
143
144 void
145 wrap_restore_saved()
146 {
147     if(!wrap_saved_list)
148         return;
149
150     wrap_kill();
151
152     free(wrap_list);
153
154     wrap_list=wrap_saved_list;
155     wrap_count=wrap_saved_count;
156     wrap_tempcount=wrap_saved_tempcount;
157
158     wrap_saved_list=NULL;
159     wrap_saved_count=0;
160     wrap_saved_tempcount=0;
161 }
162
163 void
164 wrap_add (line, isTemp)
165    char *line;
166    int         isTemp;
167 {
168     char *temp;
169     char ctemp;
170     WrapperEntry e;
171     char opt;
172
173     if (!line || line[0] == '#')
174         return;
175
176     memset (&e, 0, sizeof(e));
177
178         /* Search for the wild card */
179     while(*line && isspace(*line))
180         ++line;
181     for(temp=line;*line && !isspace(*line);++line)
182         ;
183     if(temp==line)
184         return;
185
186     ctemp=*line;
187     *line='\0';
188
189     e.wildCard=xstrdup(temp);
190     *line=ctemp;
191
192     while(*line){
193             /* Search for the option */
194         while(*line && *line!='-')
195             ++line;
196         if(!*line)
197             break;
198         ++line;
199         if(!*line)
200             break;
201         opt=*line;
202
203             /* Search for the filter commandline */
204         for(++line;*line && *line!='\'';++line);
205         if(!*line)
206             break;
207
208         for(temp=++line;*line && (*line!='\'' || line[-1]=='\\');++line)
209             ;
210
211         if(line==temp+1)
212             break;
213
214         ctemp=*line;
215         *line='\0';
216         switch(opt){
217         case 'f':
218             if(e.fromcvsFilter)
219                 free(e.fromcvsFilter);
220             /* FIXME: error message should say where the bad value
221                came from.  */
222             e.fromcvsFilter=expand_path (temp, "<wrapper>", 0);
223             if (!e.fromcvsFilter)
224                 error (1, 0, "Correct above errors first");
225             break;
226         case 't':
227             if(e.tocvsFilter)
228                 free(e.tocvsFilter);
229             /* FIXME: error message should say where the bad value
230                came from.  */
231             e.tocvsFilter=expand_path (temp, "<wrapper>", 0);
232             if (!e.tocvsFilter)
233                 error (1, 0, "Correct above errors first");
234             break;
235         case 'c':
236             if(e.conflictHook)
237                 free(e.conflictHook);
238             /* FIXME: error message should say where the bad value
239                came from.  */
240             e.conflictHook=expand_path (temp, "<wrapper>", 0);
241             if (!e.conflictHook)
242                 error (1, 0, "Correct above errors first");
243             break;
244         case 'm':
245             if(*temp=='C' || *temp=='c')
246                 e.mergeMethod=WRAP_COPY;
247             else
248                 e.mergeMethod=WRAP_MERGE;
249             break;
250         default:
251             break;
252         }
253         *line=ctemp;
254         if(!*line)break;
255         ++line;
256     }
257
258     wrap_add_entry(&e, isTemp);
259 }
260
261 void
262 wrap_add_entry(e, temp)
263     WrapperEntry *e;
264     int temp;
265 {
266     int x;
267     if(wrap_count+wrap_tempcount>=wrap_size){
268         wrap_size += WRAPPER_GROW;
269         wrap_list = (WrapperEntry **) xrealloc ((char *) wrap_list,
270                                                 wrap_size *
271                                                 sizeof (WrapperEntry *));
272     }
273
274     if(!temp && wrap_tempcount){
275         for(x=wrap_count+wrap_tempcount-1;x>=wrap_count;--x)
276             wrap_list[x+1]=wrap_list[x];
277     }
278
279     x=(temp ? wrap_count+(wrap_tempcount++):(wrap_count++));
280     wrap_list[x]=(WrapperEntry *)xmalloc(sizeof(WrapperEntry));
281     wrap_list[x]->wildCard=e->wildCard;
282     wrap_list[x]->fromcvsFilter=e->fromcvsFilter;
283     wrap_list[x]->tocvsFilter=e->tocvsFilter;
284     wrap_list[x]->conflictHook=e->conflictHook;
285     wrap_list[x]->mergeMethod=e->mergeMethod;
286 }
287
288 /* Return 1 if the given filename is a wrapper filename */
289 int
290 wrap_name_has (name,has)
291     const char   *name;
292     WrapMergeHas  has;
293 {
294     int x,count=wrap_count+wrap_saved_count;
295     char *temp;
296
297     for(x=0;x<count;++x)
298         if (fnmatch (wrap_list[x]->wildCard, name, 0) == 0){
299             switch(has){
300             case WRAP_TOCVS:
301                 temp=wrap_list[x]->tocvsFilter;
302                 break;
303             case WRAP_FROMCVS:
304                 temp=wrap_list[x]->fromcvsFilter;
305                 break;
306             case WRAP_CONFLICT:
307                 temp=wrap_list[x]->conflictHook;
308                 break;
309             default:
310                 abort ();
311             }
312             if(temp==NULL)
313                 return (0);
314             else
315                 return (1);
316         }
317     return (0);
318 }
319
320 WrapperEntry *
321 wrap_matching_entry (name)
322     const char *name;
323 {
324     int x,count=wrap_count+wrap_saved_count;
325
326     for(x=0;x<count;++x)
327         if (fnmatch (wrap_list[x]->wildCard, name, 0) == 0)
328             return wrap_list[x];
329     return (WrapperEntry *)NULL;
330 }
331
332 char *
333 wrap_tocvs_process_file(fileName)
334     const char *fileName;
335 {
336     WrapperEntry *e=wrap_matching_entry(fileName);
337     static char buf[L_tmpnam+1];
338
339     if(e==NULL || e->tocvsFilter==NULL)
340         return NULL;
341
342     tmpnam(buf);
343
344     run_setup(e->tocvsFilter,fileName,buf);
345     run_exec(RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL|RUN_REALLY );
346
347     return buf;
348 }
349
350 int
351 wrap_merge_is_copy (fileName)
352     const char *fileName;
353 {
354     WrapperEntry *e=wrap_matching_entry(fileName);
355     if(e==NULL || e->mergeMethod==WRAP_MERGE)
356         return 0;
357
358     return 1;
359 }
360
361 char *
362 wrap_fromcvs_process_file(fileName)
363     const char *fileName;
364 {
365     WrapperEntry *e=wrap_matching_entry(fileName);
366     static char buf[PATH_MAX];
367
368     if(e==NULL || e->fromcvsFilter==NULL)
369         return NULL;
370
371     run_setup(e->fromcvsFilter,fileName);
372     run_exec(RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL );
373     return buf;
374 }