4 Original Author: athan@morgan.com <Andrew C. Athan> 2/1/94
5 Modified By: vdemarco@bou.shl.com
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.
17 Format of wrapper file ($CVSROOT/CVSROOT/cvswrappers or .cvswrappers)
19 wildcard [option value][option value]...
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
26 and value is a single-quote delimited value.
29 *.nib -f 'gunzipuntar' -t 'targzip' -m 'COPY'
38 WrapMergeMethod mergeMethod;
41 static WrapperEntry **wrap_list=NULL;
42 static WrapperEntry **wrap_saved_list=NULL;
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;
50 #define WRAPPER_GROW 8
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));
64 /* Then add entries found in repository, if it exists */
65 (void) sprintf (file, "%s/%s/%s", CVSroot, CVSROOTADM, CVSROOTADM_WRAPPER);
67 wrap_add_file(file,0);
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);
74 wrap_add_file (file, 0);
78 /* Then add entries found in CVSWRAPPERS environment variable. */
79 wrap_add (getenv (WRAPPER_ENV), 0);
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"
88 wrap_add_file (file, temp)
99 if (!(fp = fopen (file, "r")))
101 while (fgets (line, sizeof (line), fp))
102 wrap_add (line, temp);
111 wrap_free_entry(wrap_list[--wrap_count]);
117 WrapperEntry **temps=wrap_list+wrap_count;
119 while(wrap_tempcount)
120 wrap_free_entry(temps[--wrap_tempcount]);
127 wrap_free_entry_internal(e);
132 wrap_free_entry_internal(e)
137 free(e->tocvsFilter);
139 free(e->fromcvsFilter);
141 free(e->conflictHook);
154 wrap_list=wrap_saved_list;
155 wrap_count=wrap_saved_count;
156 wrap_tempcount=wrap_saved_tempcount;
158 wrap_saved_list=NULL;
160 wrap_saved_tempcount=0;
164 wrap_add (line, isTemp)
173 if (!line || line[0] == '#')
176 memset (&e, 0, sizeof(e));
178 /* Search for the wild card */
179 while(*line && isspace(*line))
181 for(temp=line;*line && !isspace(*line);++line)
189 e.wildCard=xstrdup(temp);
193 /* Search for the option */
194 while(*line && *line!='-')
203 /* Search for the filter commandline */
204 for(++line;*line && *line!='\'';++line);
208 for(temp=++line;*line && (*line!='\'' || line[-1]=='\\');++line)
219 free(e.fromcvsFilter);
220 /* FIXME: error message should say where the bad value
222 e.fromcvsFilter=expand_path (temp, "<wrapper>", 0);
223 if (!e.fromcvsFilter)
224 error (1, 0, "Correct above errors first");
229 /* FIXME: error message should say where the bad value
231 e.tocvsFilter=expand_path (temp, "<wrapper>", 0);
233 error (1, 0, "Correct above errors first");
237 free(e.conflictHook);
238 /* FIXME: error message should say where the bad value
240 e.conflictHook=expand_path (temp, "<wrapper>", 0);
242 error (1, 0, "Correct above errors first");
245 if(*temp=='C' || *temp=='c')
246 e.mergeMethod=WRAP_COPY;
248 e.mergeMethod=WRAP_MERGE;
258 wrap_add_entry(&e, isTemp);
262 wrap_add_entry(e, temp)
267 if(wrap_count+wrap_tempcount>=wrap_size){
268 wrap_size += WRAPPER_GROW;
269 wrap_list = (WrapperEntry **) xrealloc ((char *) wrap_list,
271 sizeof (WrapperEntry *));
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];
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;
288 /* Return 1 if the given filename is a wrapper filename */
290 wrap_name_has (name,has)
294 int x,count=wrap_count+wrap_saved_count;
298 if (fnmatch (wrap_list[x]->wildCard, name, 0) == 0){
301 temp=wrap_list[x]->tocvsFilter;
304 temp=wrap_list[x]->fromcvsFilter;
307 temp=wrap_list[x]->conflictHook;
321 wrap_matching_entry (name)
324 int x,count=wrap_count+wrap_saved_count;
327 if (fnmatch (wrap_list[x]->wildCard, name, 0) == 0)
329 return (WrapperEntry *)NULL;
333 wrap_tocvs_process_file(fileName)
334 const char *fileName;
336 WrapperEntry *e=wrap_matching_entry(fileName);
337 static char buf[L_tmpnam+1];
339 if(e==NULL || e->tocvsFilter==NULL)
344 run_setup(e->tocvsFilter,fileName,buf);
345 run_exec(RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL|RUN_REALLY );
351 wrap_merge_is_copy (fileName)
352 const char *fileName;
354 WrapperEntry *e=wrap_matching_entry(fileName);
355 if(e==NULL || e->mergeMethod==WRAP_MERGE)
362 wrap_fromcvs_process_file(fileName)
363 const char *fileName;
365 WrapperEntry *e=wrap_matching_entry(fileName);
366 static char buf[PATH_MAX];
368 if(e==NULL || e->fromcvsFilter==NULL)
371 run_setup(e->fromcvsFilter,fileName);
372 run_exec(RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL );