1780d15dfStholo /* This program is free software; you can redistribute it and/or modify
2780d15dfStholo it under the terms of the GNU General Public License as published by
3780d15dfStholo the Free Software Foundation; either version 2, or (at your option)
4780d15dfStholo any later version.
5780d15dfStholo
6780d15dfStholo This program is distributed in the hope that it will be useful,
7780d15dfStholo but WITHOUT ANY WARRANTY; without even the implied warranty of
8780d15dfStholo MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9780d15dfStholo GNU General Public License for more details. */
10780d15dfStholo
111e72d8d2Sderaadt #include "cvs.h"
12780d15dfStholo #include "getline.h"
131e72d8d2Sderaadt
141e72d8d2Sderaadt /*
151e72d8d2Sderaadt Original Author: athan@morgan.com <Andrew C. Athan> 2/1/94
161e72d8d2Sderaadt Modified By: vdemarco@bou.shl.com
171e72d8d2Sderaadt
181e72d8d2Sderaadt This package was written to support the NEXTSTEP concept of
191e72d8d2Sderaadt "wrappers." These are essentially directories that are to be
201e72d8d2Sderaadt treated as "files." This package allows such wrappers to be
211e72d8d2Sderaadt "processed" on the way in and out of CVS. The intended use is to
221e72d8d2Sderaadt wrap up a wrapper into a single tar, such that that tar can be
231e72d8d2Sderaadt treated as a single binary file in CVS. To solve the problem
241e72d8d2Sderaadt effectively, it was also necessary to be able to prevent rcsmerge
251e72d8d2Sderaadt application at appropriate times.
261e72d8d2Sderaadt
271e72d8d2Sderaadt ------------------
281e72d8d2Sderaadt Format of wrapper file ($CVSROOT/CVSROOT/cvswrappers or .cvswrappers)
291e72d8d2Sderaadt
301e72d8d2Sderaadt wildcard [option value][option value]...
311e72d8d2Sderaadt
321e72d8d2Sderaadt where option is one of
331e72d8d2Sderaadt -f from cvs filter value: path to filter
341e72d8d2Sderaadt -t to cvs filter value: path to filter
351e72d8d2Sderaadt -m update methodology value: MERGE or COPY
3650bf276cStholo -k default -k rcs option to use on import or add
371e72d8d2Sderaadt
381e72d8d2Sderaadt and value is a single-quote delimited value.
391e72d8d2Sderaadt
401e72d8d2Sderaadt E.g:
411e72d8d2Sderaadt *.nib -f 'gunzipuntar' -t 'targzip' -m 'COPY'
421e72d8d2Sderaadt */
431e72d8d2Sderaadt
441e72d8d2Sderaadt
451e72d8d2Sderaadt typedef struct {
461e72d8d2Sderaadt char *wildCard;
471e72d8d2Sderaadt char *tocvsFilter;
481e72d8d2Sderaadt char *fromcvsFilter;
4950bf276cStholo char *rcsOption;
501e72d8d2Sderaadt WrapMergeMethod mergeMethod;
511e72d8d2Sderaadt } WrapperEntry;
521e72d8d2Sderaadt
531e72d8d2Sderaadt static WrapperEntry **wrap_list=NULL;
541e72d8d2Sderaadt static WrapperEntry **wrap_saved_list=NULL;
551e72d8d2Sderaadt
561e72d8d2Sderaadt static int wrap_size=0;
571e72d8d2Sderaadt static int wrap_count=0;
581e72d8d2Sderaadt static int wrap_tempcount=0;
5950bf276cStholo
602286d8edStholo /* FIXME: the relationship between wrap_count, wrap_tempcount,
612286d8edStholo * wrap_saved_count, and wrap_saved_tempcount is not entirely clear;
622286d8edStholo * it is certainly suspicious that wrap_saved_count is never set to a
632286d8edStholo * value other than zero! If the variable isn't being used, it should
642286d8edStholo * be removed. And in general, we should describe how temporary
652286d8edStholo * vs. permanent wrappers are implemented, and then make sure the
662286d8edStholo * implementation is actually doing that.
672286d8edStholo *
682286d8edStholo * Right now things seem to be working, but that's no guarantee there
692286d8edStholo * isn't a bug lurking somewhere in the murk.
702286d8edStholo */
7150bf276cStholo
721e72d8d2Sderaadt static int wrap_saved_count=0;
7350bf276cStholo
741e72d8d2Sderaadt static int wrap_saved_tempcount=0;
751e72d8d2Sderaadt
761e72d8d2Sderaadt #define WRAPPER_GROW 8
771e72d8d2Sderaadt
781e72d8d2Sderaadt void wrap_add_entry PROTO((WrapperEntry *e,int temp));
791e72d8d2Sderaadt void wrap_kill PROTO((void));
801e72d8d2Sderaadt void wrap_kill_temp PROTO((void));
811e72d8d2Sderaadt void wrap_free_entry PROTO((WrapperEntry *e));
821e72d8d2Sderaadt void wrap_free_entry_internal PROTO((WrapperEntry *e));
831e72d8d2Sderaadt void wrap_restore_saved PROTO((void));
841e72d8d2Sderaadt
wrap_setup()851e72d8d2Sderaadt void wrap_setup()
861e72d8d2Sderaadt {
872286d8edStholo /* FIXME-reentrancy: if we do a multithreaded server, will need to
882286d8edStholo move this to a per-connection data structure, or better yet
892286d8edStholo think about a cleaner solution. */
902286d8edStholo static int wrap_setup_already_done = 0;
912286d8edStholo char *homedir;
922286d8edStholo
932286d8edStholo if (wrap_setup_already_done != 0)
942286d8edStholo return;
952286d8edStholo else
962286d8edStholo wrap_setup_already_done = 1;
971e72d8d2Sderaadt
9850bf276cStholo #ifdef CLIENT_SUPPORT
9943c1707eStholo if (!current_parsed_root->isremote)
10050bf276cStholo #endif
10150bf276cStholo {
102780d15dfStholo char *file;
103780d15dfStholo
10443c1707eStholo file = xmalloc (strlen (current_parsed_root->directory)
105780d15dfStholo + sizeof (CVSROOTADM)
106780d15dfStholo + sizeof (CVSROOTADM_WRAPPER)
10743c1707eStholo + 3);
10850bf276cStholo /* Then add entries found in repository, if it exists. */
10943c1707eStholo (void) sprintf (file, "%s/%s/%s", current_parsed_root->directory, CVSROOTADM,
11050bf276cStholo CVSROOTADM_WRAPPER);
11150bf276cStholo if (isfile (file))
11250bf276cStholo {
1131e72d8d2Sderaadt wrap_add_file(file,0);
1141e72d8d2Sderaadt }
115780d15dfStholo free (file);
11650bf276cStholo }
1171e72d8d2Sderaadt
11850bf276cStholo /* Then add entries found in home dir, (if user has one) and file
1192286d8edStholo exists. */
1202286d8edStholo homedir = get_homedir ();
121c71bc7e2Stholo /* If we can't find a home directory, ignore ~/.cvswrappers. This may
122c71bc7e2Stholo make tracking down problems a bit of a pain, but on the other
123c71bc7e2Stholo hand it might be obnoxious to complain when CVS will function
124c71bc7e2Stholo just fine without .cvswrappers (and many users won't even know what
125c71bc7e2Stholo .cvswrappers is). */
1262286d8edStholo if (homedir != NULL)
12750bf276cStholo {
128780d15dfStholo char *file;
129780d15dfStholo
1302286d8edStholo file = xmalloc (strlen (homedir) + sizeof (CVSDOTWRAPPER) + 10);
1312286d8edStholo (void) sprintf (file, "%s/%s", homedir, CVSDOTWRAPPER);
13250bf276cStholo if (isfile (file))
13350bf276cStholo {
1341e72d8d2Sderaadt wrap_add_file (file, 0);
1351e72d8d2Sderaadt }
136780d15dfStholo free (file);
1371e72d8d2Sderaadt }
1381e72d8d2Sderaadt
1392286d8edStholo /* FIXME: calling wrap_add() below implies that the CVSWRAPPERS
1402286d8edStholo * environment variable contains exactly one "wrapper" -- a line
1412286d8edStholo * of the form
1422286d8edStholo *
1432286d8edStholo * FILENAME_PATTERN FLAG OPTS [ FLAG OPTS ...]
1442286d8edStholo *
1452286d8edStholo * This may disagree with the documentation, which states:
1462286d8edStholo *
1472286d8edStholo * `$CVSWRAPPERS'
1482286d8edStholo * A whitespace-separated list of file name patterns that CVS
1492286d8edStholo * should treat as wrappers. *Note Wrappers::.
1502286d8edStholo *
1512286d8edStholo * Does this mean the environment variable can hold multiple
1522286d8edStholo * wrappers lines? If so, a single call to wrap_add() is
1532286d8edStholo * insufficient.
1542286d8edStholo */
1552286d8edStholo
1561e72d8d2Sderaadt /* Then add entries found in CVSWRAPPERS environment variable. */
1571e72d8d2Sderaadt wrap_add (getenv (WRAPPER_ENV), 0);
1581e72d8d2Sderaadt }
1591e72d8d2Sderaadt
16050bf276cStholo #ifdef CLIENT_SUPPORT
16150bf276cStholo /* Send -W arguments for the wrappers to the server. The command must
16250bf276cStholo be one that accepts them (e.g. update, import). */
16350bf276cStholo void
wrap_send()16450bf276cStholo wrap_send ()
16550bf276cStholo {
16650bf276cStholo int i;
16750bf276cStholo
16850bf276cStholo for (i = 0; i < wrap_count + wrap_tempcount; ++i)
16950bf276cStholo {
17050bf276cStholo if (wrap_list[i]->tocvsFilter != NULL
17150bf276cStholo || wrap_list[i]->fromcvsFilter != NULL)
17250bf276cStholo /* For greater studliness we would print the offending option
17350bf276cStholo and (more importantly) where we found it. */
17450bf276cStholo error (0, 0, "\
17550bf276cStholo -t and -f wrapper options are not supported remotely; ignored");
17650bf276cStholo if (wrap_list[i]->mergeMethod == WRAP_COPY)
17750bf276cStholo /* For greater studliness we would print the offending option
17850bf276cStholo and (more importantly) where we found it. */
17950bf276cStholo error (0, 0, "\
18050bf276cStholo -m wrapper option is not supported remotely; ignored");
18150bf276cStholo if (wrap_list[i]->rcsOption != NULL)
18250bf276cStholo {
18350bf276cStholo send_to_server ("Argument -W\012Argument ", 0);
18450bf276cStholo send_to_server (wrap_list[i]->wildCard, 0);
18550bf276cStholo send_to_server (" -k '", 0);
18650bf276cStholo send_to_server (wrap_list[i]->rcsOption, 0);
18750bf276cStholo send_to_server ("'\012", 0);
18850bf276cStholo }
18950bf276cStholo }
19050bf276cStholo }
19150bf276cStholo #endif /* CLIENT_SUPPORT */
19250bf276cStholo
1932286d8edStholo #if defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT)
1942286d8edStholo /* Output wrapper entries in the format of cvswrappers lines.
1952286d8edStholo *
1962286d8edStholo * This is useful when one side of a client/server connection wants to
1972286d8edStholo * send its wrappers to the other; since the receiving side would like
1982286d8edStholo * to use wrap_add() to incorporate the wrapper, it's best if the
1992286d8edStholo * entry arrives in this format.
2002286d8edStholo *
2012286d8edStholo * The entries are stored in `line', which is allocated here. Caller
2022286d8edStholo * can free() it.
2032286d8edStholo *
2042286d8edStholo * If first_call_p is nonzero, then start afresh. */
2052286d8edStholo void
wrap_unparse_rcs_options(line,first_call_p)2062286d8edStholo wrap_unparse_rcs_options (line, first_call_p)
2072286d8edStholo char **line;
2082286d8edStholo int first_call_p;
2092286d8edStholo {
2102286d8edStholo /* FIXME-reentrancy: we should design a reentrant interface, like
2112286d8edStholo a callback which gets handed each wrapper (a multithreaded
2122286d8edStholo server being the most concrete reason for this, but the
2132286d8edStholo non-reentrant interface is fairly unnecessary/ugly). */
2142286d8edStholo static int i;
2152286d8edStholo
2162286d8edStholo if (first_call_p)
2172286d8edStholo i = 0;
2182286d8edStholo
2192286d8edStholo for (; i < wrap_count + wrap_tempcount; ++i)
2202286d8edStholo {
2212286d8edStholo if (wrap_list[i]->rcsOption != NULL)
2222286d8edStholo {
2232286d8edStholo *line = xmalloc (strlen (wrap_list[i]->wildCard)
2242286d8edStholo + strlen ("\t")
2252286d8edStholo + strlen (" -k '")
2262286d8edStholo + strlen (wrap_list[i]->rcsOption)
2272286d8edStholo + strlen ("'")
2282286d8edStholo + 1); /* leave room for '\0' */
2292286d8edStholo
2302286d8edStholo strcpy (*line, wrap_list[i]->wildCard);
2312286d8edStholo strcat (*line, " -k '");
2322286d8edStholo strcat (*line, wrap_list[i]->rcsOption);
2332286d8edStholo strcat (*line, "'");
2342286d8edStholo
2352286d8edStholo /* We're going to miss the increment because we return, so
2362286d8edStholo do it by hand. */
2372286d8edStholo ++i;
2382286d8edStholo
2392286d8edStholo return;
2402286d8edStholo }
2412286d8edStholo }
2422286d8edStholo
2432286d8edStholo *line = NULL;
2442286d8edStholo return;
2452286d8edStholo }
2462286d8edStholo #endif /* SERVER_SUPPORT || CLIENT_SUPPORT */
2472286d8edStholo
2481e72d8d2Sderaadt /*
2492ddaa231Sotto * Remove fmt str specifier other than %% or %s. And allow
2502ddaa231Sotto * only max_s %s specifiers
2512ddaa231Sotto */
25297e794f8Sjsg void
wrap_clean_fmt_str(char * fmt,int max_s)2532ddaa231Sotto wrap_clean_fmt_str(char *fmt, int max_s)
2542ddaa231Sotto {
2552ddaa231Sotto while (*fmt) {
2562ddaa231Sotto if (fmt[0] == '%' && fmt[1])
2572ddaa231Sotto {
2582ddaa231Sotto if (fmt[1] == '%')
2592ddaa231Sotto fmt++;
2602ddaa231Sotto else
2612ddaa231Sotto if (fmt[1] == 's' && max_s > 0)
2622ddaa231Sotto {
2632ddaa231Sotto max_s--;
2642ddaa231Sotto fmt++;
2652ddaa231Sotto } else
2662ddaa231Sotto *fmt = ' ';
2672ddaa231Sotto }
2682ddaa231Sotto fmt++;
2692ddaa231Sotto }
2702ddaa231Sotto }
2712ddaa231Sotto
2722ddaa231Sotto /*
2731e72d8d2Sderaadt * Open a file and read lines, feeding each line to a line parser. Arrange
2741e72d8d2Sderaadt * for keeping a temporary list of wrappers at the end, if the "temp"
2751e72d8d2Sderaadt * argument is set.
2761e72d8d2Sderaadt */
2771e72d8d2Sderaadt void
wrap_add_file(file,temp)2781e72d8d2Sderaadt wrap_add_file (file, temp)
2791e72d8d2Sderaadt const char *file;
2801e72d8d2Sderaadt int temp;
2811e72d8d2Sderaadt {
2821e72d8d2Sderaadt FILE *fp;
283780d15dfStholo char *line = NULL;
284780d15dfStholo size_t line_allocated = 0;
2851e72d8d2Sderaadt
2861e72d8d2Sderaadt wrap_restore_saved ();
2871e72d8d2Sderaadt wrap_kill_temp ();
2881e72d8d2Sderaadt
289780d15dfStholo /* Load the file. */
290780d15dfStholo fp = CVS_FOPEN (file, "r");
291780d15dfStholo if (fp == NULL)
292780d15dfStholo {
293780d15dfStholo if (!existence_error (errno))
294780d15dfStholo error (0, errno, "cannot open %s", file);
2951e72d8d2Sderaadt return;
296780d15dfStholo }
297*f9bbbf45Sfgsch while (get_line (&line, &line_allocated, fp) >= 0)
2981e72d8d2Sderaadt wrap_add (line, temp);
2992770ece5Stholo if (line)
3002770ece5Stholo free (line);
301780d15dfStholo if (ferror (fp))
302780d15dfStholo error (0, errno, "cannot read %s", file);
303780d15dfStholo if (fclose (fp) == EOF)
304780d15dfStholo error (0, errno, "cannot close %s", file);
3051e72d8d2Sderaadt }
3061e72d8d2Sderaadt
3071e72d8d2Sderaadt void
wrap_kill()3081e72d8d2Sderaadt wrap_kill()
3091e72d8d2Sderaadt {
3101e72d8d2Sderaadt wrap_kill_temp();
3111e72d8d2Sderaadt while(wrap_count)
3121e72d8d2Sderaadt wrap_free_entry(wrap_list[--wrap_count]);
3131e72d8d2Sderaadt }
3141e72d8d2Sderaadt
3151e72d8d2Sderaadt void
wrap_kill_temp()3161e72d8d2Sderaadt wrap_kill_temp()
3171e72d8d2Sderaadt {
3181e72d8d2Sderaadt WrapperEntry **temps=wrap_list+wrap_count;
3191e72d8d2Sderaadt
3201e72d8d2Sderaadt while(wrap_tempcount)
3211e72d8d2Sderaadt wrap_free_entry(temps[--wrap_tempcount]);
3221e72d8d2Sderaadt }
3231e72d8d2Sderaadt
3241e72d8d2Sderaadt void
wrap_free_entry(e)3251e72d8d2Sderaadt wrap_free_entry(e)
3261e72d8d2Sderaadt WrapperEntry *e;
3271e72d8d2Sderaadt {
3281e72d8d2Sderaadt wrap_free_entry_internal(e);
3291e72d8d2Sderaadt free(e);
3301e72d8d2Sderaadt }
3311e72d8d2Sderaadt
3321e72d8d2Sderaadt void
wrap_free_entry_internal(e)3331e72d8d2Sderaadt wrap_free_entry_internal(e)
3341e72d8d2Sderaadt WrapperEntry *e;
3351e72d8d2Sderaadt {
3361e72d8d2Sderaadt free (e->wildCard);
3371e72d8d2Sderaadt if (e->tocvsFilter)
3381e72d8d2Sderaadt free (e->tocvsFilter);
3391e72d8d2Sderaadt if (e->fromcvsFilter)
3401e72d8d2Sderaadt free (e->fromcvsFilter);
34150bf276cStholo if (e->rcsOption)
34250bf276cStholo free (e->rcsOption);
3431e72d8d2Sderaadt }
3441e72d8d2Sderaadt
3451e72d8d2Sderaadt void
wrap_restore_saved()3461e72d8d2Sderaadt wrap_restore_saved()
3471e72d8d2Sderaadt {
3481e72d8d2Sderaadt if(!wrap_saved_list)
3491e72d8d2Sderaadt return;
3501e72d8d2Sderaadt
3511e72d8d2Sderaadt wrap_kill();
3521e72d8d2Sderaadt
3531e72d8d2Sderaadt free(wrap_list);
3541e72d8d2Sderaadt
3551e72d8d2Sderaadt wrap_list=wrap_saved_list;
3561e72d8d2Sderaadt wrap_count=wrap_saved_count;
3571e72d8d2Sderaadt wrap_tempcount=wrap_saved_tempcount;
3581e72d8d2Sderaadt
3591e72d8d2Sderaadt wrap_saved_list=NULL;
3601e72d8d2Sderaadt wrap_saved_count=0;
3611e72d8d2Sderaadt wrap_saved_tempcount=0;
3621e72d8d2Sderaadt }
3631e72d8d2Sderaadt
3641e72d8d2Sderaadt void
wrap_add(line,isTemp)3651e72d8d2Sderaadt wrap_add (line, isTemp)
3661e72d8d2Sderaadt char *line;
3671e72d8d2Sderaadt int isTemp;
3681e72d8d2Sderaadt {
3691e72d8d2Sderaadt char *temp;
3701e72d8d2Sderaadt char ctemp;
3711e72d8d2Sderaadt WrapperEntry e;
3721e72d8d2Sderaadt char opt;
3731e72d8d2Sderaadt
3741e72d8d2Sderaadt if (!line || line[0] == '#')
3751e72d8d2Sderaadt return;
3761e72d8d2Sderaadt
3771e72d8d2Sderaadt memset (&e, 0, sizeof(e));
3781e72d8d2Sderaadt
3791e72d8d2Sderaadt /* Search for the wild card */
380c71bc7e2Stholo while (*line && isspace ((unsigned char) *line))
3811e72d8d2Sderaadt ++line;
382c71bc7e2Stholo for (temp = line;
383c71bc7e2Stholo *line && !isspace ((unsigned char) *line);
384c71bc7e2Stholo ++line)
3851e72d8d2Sderaadt ;
3861e72d8d2Sderaadt if(temp==line)
3871e72d8d2Sderaadt return;
3881e72d8d2Sderaadt
3891e72d8d2Sderaadt ctemp=*line;
3901e72d8d2Sderaadt *line='\0';
3911e72d8d2Sderaadt
3921e72d8d2Sderaadt e.wildCard=xstrdup(temp);
3931e72d8d2Sderaadt *line=ctemp;
3941e72d8d2Sderaadt
3951e72d8d2Sderaadt while(*line){
3961e72d8d2Sderaadt /* Search for the option */
3971e72d8d2Sderaadt while(*line && *line!='-')
3981e72d8d2Sderaadt ++line;
3991e72d8d2Sderaadt if(!*line)
4001e72d8d2Sderaadt break;
4011e72d8d2Sderaadt ++line;
4021e72d8d2Sderaadt if(!*line)
4031e72d8d2Sderaadt break;
4041e72d8d2Sderaadt opt=*line;
4051e72d8d2Sderaadt
4061e72d8d2Sderaadt /* Search for the filter commandline */
4071e72d8d2Sderaadt for(++line;*line && *line!='\'';++line);
4081e72d8d2Sderaadt if(!*line)
4091e72d8d2Sderaadt break;
4101e72d8d2Sderaadt
4111e72d8d2Sderaadt for(temp=++line;*line && (*line!='\'' || line[-1]=='\\');++line)
4121e72d8d2Sderaadt ;
4131e72d8d2Sderaadt
41450bf276cStholo /* This used to "break;" (ignore the option) if there was a
41550bf276cStholo single character between the single quotes (I'm guessing
41650bf276cStholo that was accidental). Now it "break;"s if there are no
41750bf276cStholo characters. I'm not sure either behavior is particularly
41850bf276cStholo necessary--the current options might not require ''
41950bf276cStholo arguments, but surely some future option legitimately
42050bf276cStholo might. Also I'm not sure that ignoring the option is a
42150bf276cStholo swift way to handle syntax errors in general. */
42250bf276cStholo if (line==temp)
4231e72d8d2Sderaadt break;
4241e72d8d2Sderaadt
4251e72d8d2Sderaadt ctemp=*line;
4261e72d8d2Sderaadt *line='\0';
4271e72d8d2Sderaadt switch(opt){
4281e72d8d2Sderaadt case 'f':
429b6f6614eStholo /* Before this is reenabled, need to address the problem in
430b6f6614eStholo commit.c (see http://www.cyclic.com/cvs/dev-wrap.txt). */
431b6f6614eStholo error (1, 0,
432b6f6614eStholo "-t/-f wrappers not supported by this version of CVS");
433b6f6614eStholo
4341e72d8d2Sderaadt if(e.fromcvsFilter)
4351e72d8d2Sderaadt free(e.fromcvsFilter);
436c26070a5Stholo /* FIXME: error message should say where the bad value
437c26070a5Stholo came from. */
438c26070a5Stholo e.fromcvsFilter=expand_path (temp, "<wrapper>", 0);
43913571821Stholo if (!e.fromcvsFilter)
440c26070a5Stholo error (1, 0, "Correct above errors first");
4411e72d8d2Sderaadt break;
4421e72d8d2Sderaadt case 't':
443b6f6614eStholo /* Before this is reenabled, need to address the problem in
444b6f6614eStholo commit.c (see http://www.cyclic.com/cvs/dev-wrap.txt). */
445b6f6614eStholo error (1, 0,
446b6f6614eStholo "-t/-f wrappers not supported by this version of CVS");
447b6f6614eStholo
4481e72d8d2Sderaadt if(e.tocvsFilter)
4491e72d8d2Sderaadt free(e.tocvsFilter);
450c26070a5Stholo /* FIXME: error message should say where the bad value
451c26070a5Stholo came from. */
452c26070a5Stholo e.tocvsFilter=expand_path (temp, "<wrapper>", 0);
45313571821Stholo if (!e.tocvsFilter)
454c26070a5Stholo error (1, 0, "Correct above errors first");
4551e72d8d2Sderaadt break;
4561e72d8d2Sderaadt case 'm':
4571e72d8d2Sderaadt if(*temp=='C' || *temp=='c')
4581e72d8d2Sderaadt e.mergeMethod=WRAP_COPY;
4591e72d8d2Sderaadt else
4601e72d8d2Sderaadt e.mergeMethod=WRAP_MERGE;
4611e72d8d2Sderaadt break;
46250bf276cStholo case 'k':
46350bf276cStholo if (e.rcsOption)
46450bf276cStholo free (e.rcsOption);
46550bf276cStholo e.rcsOption = xstrdup (temp);
46650bf276cStholo break;
4671e72d8d2Sderaadt default:
4681e72d8d2Sderaadt break;
4691e72d8d2Sderaadt }
4701e72d8d2Sderaadt *line=ctemp;
4711e72d8d2Sderaadt if(!*line)break;
4721e72d8d2Sderaadt ++line;
4731e72d8d2Sderaadt }
4741e72d8d2Sderaadt
4751e72d8d2Sderaadt wrap_add_entry(&e, isTemp);
4761e72d8d2Sderaadt }
4771e72d8d2Sderaadt
4781e72d8d2Sderaadt void
wrap_add_entry(e,temp)4791e72d8d2Sderaadt wrap_add_entry(e, temp)
4801e72d8d2Sderaadt WrapperEntry *e;
4811e72d8d2Sderaadt int temp;
4821e72d8d2Sderaadt {
4831e72d8d2Sderaadt int x;
4841e72d8d2Sderaadt if(wrap_count+wrap_tempcount>=wrap_size){
4851e72d8d2Sderaadt wrap_size += WRAPPER_GROW;
4861e72d8d2Sderaadt wrap_list = (WrapperEntry **) xrealloc ((char *) wrap_list,
4871e72d8d2Sderaadt wrap_size *
4881e72d8d2Sderaadt sizeof (WrapperEntry *));
4891e72d8d2Sderaadt }
4901e72d8d2Sderaadt
4911e72d8d2Sderaadt if(!temp && wrap_tempcount){
4921e72d8d2Sderaadt for(x=wrap_count+wrap_tempcount-1;x>=wrap_count;--x)
4931e72d8d2Sderaadt wrap_list[x+1]=wrap_list[x];
4941e72d8d2Sderaadt }
4951e72d8d2Sderaadt
4961e72d8d2Sderaadt x=(temp ? wrap_count+(wrap_tempcount++):(wrap_count++));
4971e72d8d2Sderaadt wrap_list[x]=(WrapperEntry *)xmalloc(sizeof(WrapperEntry));
4981e72d8d2Sderaadt wrap_list[x]->wildCard=e->wildCard;
4991e72d8d2Sderaadt wrap_list[x]->fromcvsFilter=e->fromcvsFilter;
5001e72d8d2Sderaadt wrap_list[x]->tocvsFilter=e->tocvsFilter;
5011e72d8d2Sderaadt wrap_list[x]->mergeMethod=e->mergeMethod;
50250bf276cStholo wrap_list[x]->rcsOption = e->rcsOption;
5031e72d8d2Sderaadt }
5041e72d8d2Sderaadt
5051e72d8d2Sderaadt /* Return 1 if the given filename is a wrapper filename */
5061e72d8d2Sderaadt int
wrap_name_has(name,has)5071e72d8d2Sderaadt wrap_name_has (name,has)
5081e72d8d2Sderaadt const char *name;
5091e72d8d2Sderaadt WrapMergeHas has;
5101e72d8d2Sderaadt {
5112286d8edStholo int x,count=wrap_count+wrap_tempcount;
5121e72d8d2Sderaadt char *temp;
5131e72d8d2Sderaadt
5141e72d8d2Sderaadt for(x=0;x<count;++x)
5152770ece5Stholo if (CVS_FNMATCH (wrap_list[x]->wildCard, name, 0) == 0){
5161e72d8d2Sderaadt switch(has){
5171e72d8d2Sderaadt case WRAP_TOCVS:
5181e72d8d2Sderaadt temp=wrap_list[x]->tocvsFilter;
5191e72d8d2Sderaadt break;
5201e72d8d2Sderaadt case WRAP_FROMCVS:
5211e72d8d2Sderaadt temp=wrap_list[x]->fromcvsFilter;
5221e72d8d2Sderaadt break;
52350bf276cStholo case WRAP_RCSOPTION:
52450bf276cStholo temp = wrap_list[x]->rcsOption;
5251e72d8d2Sderaadt break;
5261e72d8d2Sderaadt default:
5271e72d8d2Sderaadt abort ();
5281e72d8d2Sderaadt }
5291e72d8d2Sderaadt if(temp==NULL)
5301e72d8d2Sderaadt return (0);
5311e72d8d2Sderaadt else
5321e72d8d2Sderaadt return (1);
5331e72d8d2Sderaadt }
5341e72d8d2Sderaadt return (0);
5351e72d8d2Sderaadt }
5361e72d8d2Sderaadt
537461cc63eStholo static WrapperEntry *wrap_matching_entry PROTO ((const char *));
538461cc63eStholo
539461cc63eStholo static WrapperEntry *
wrap_matching_entry(name)5401e72d8d2Sderaadt wrap_matching_entry (name)
5411e72d8d2Sderaadt const char *name;
5421e72d8d2Sderaadt {
5432286d8edStholo int x,count=wrap_count+wrap_tempcount;
5441e72d8d2Sderaadt
5451e72d8d2Sderaadt for(x=0;x<count;++x)
5462770ece5Stholo if (CVS_FNMATCH (wrap_list[x]->wildCard, name, 0) == 0)
5471e72d8d2Sderaadt return wrap_list[x];
5481e72d8d2Sderaadt return (WrapperEntry *)NULL;
5491e72d8d2Sderaadt }
5501e72d8d2Sderaadt
55150bf276cStholo /* Return the RCS options for FILENAME in a newly malloc'd string. If
55250bf276cStholo ASFLAG, then include "-k" at the beginning (e.g. "-kb"), otherwise
55350bf276cStholo just give the option itself (e.g. "b"). */
55450bf276cStholo char *
wrap_rcsoption(filename,asflag)55550bf276cStholo wrap_rcsoption (filename, asflag)
55650bf276cStholo const char *filename;
55750bf276cStholo int asflag;
55850bf276cStholo {
55950bf276cStholo WrapperEntry *e = wrap_matching_entry (filename);
56050bf276cStholo char *buf;
56150bf276cStholo
56250bf276cStholo if (e == NULL || e->rcsOption == NULL || (*e->rcsOption == '\0'))
56350bf276cStholo return NULL;
56450bf276cStholo
56550bf276cStholo buf = xmalloc (strlen (e->rcsOption) + 3);
56650bf276cStholo if (asflag)
56750bf276cStholo {
56850bf276cStholo strcpy (buf, "-k");
56950bf276cStholo strcat (buf, e->rcsOption);
57050bf276cStholo }
57150bf276cStholo else
57250bf276cStholo {
57350bf276cStholo strcpy (buf, e->rcsOption);
57450bf276cStholo }
57550bf276cStholo return buf;
57650bf276cStholo }
57750bf276cStholo
5781e72d8d2Sderaadt char *
wrap_tocvs_process_file(fileName)5791e72d8d2Sderaadt wrap_tocvs_process_file(fileName)
5801e72d8d2Sderaadt const char *fileName;
5811e72d8d2Sderaadt {
5821e72d8d2Sderaadt WrapperEntry *e=wrap_matching_entry(fileName);
58350bf276cStholo static char *buf = NULL;
5842286d8edStholo char *args;
5851e72d8d2Sderaadt
5861e72d8d2Sderaadt if(e==NULL || e->tocvsFilter==NULL)
5871e72d8d2Sderaadt return NULL;
5881e72d8d2Sderaadt
58950bf276cStholo if (buf != NULL)
59050bf276cStholo free (buf);
59150bf276cStholo buf = cvs_temp_name ();
5921e72d8d2Sderaadt
5932286d8edStholo args = xmalloc (strlen (e->tocvsFilter)
5942286d8edStholo + strlen (fileName)
5952286d8edStholo + strlen (buf));
5962ddaa231Sotto
5972ddaa231Sotto wrap_clean_fmt_str(e->tocvsFilter, 2);
5982286d8edStholo sprintf (args, e->tocvsFilter, fileName, buf);
5992286d8edStholo run_setup (args);
6001e72d8d2Sderaadt run_exec(RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL|RUN_REALLY );
6012286d8edStholo free (args);
6021e72d8d2Sderaadt
6031e72d8d2Sderaadt return buf;
6041e72d8d2Sderaadt }
6051e72d8d2Sderaadt
6061e72d8d2Sderaadt int
wrap_merge_is_copy(fileName)6071e72d8d2Sderaadt wrap_merge_is_copy (fileName)
6081e72d8d2Sderaadt const char *fileName;
6091e72d8d2Sderaadt {
6101e72d8d2Sderaadt WrapperEntry *e=wrap_matching_entry(fileName);
6111e72d8d2Sderaadt if(e==NULL || e->mergeMethod==WRAP_MERGE)
6121e72d8d2Sderaadt return 0;
6131e72d8d2Sderaadt
6141e72d8d2Sderaadt return 1;
6151e72d8d2Sderaadt }
6161e72d8d2Sderaadt
617780d15dfStholo void
wrap_fromcvs_process_file(fileName)6181e72d8d2Sderaadt wrap_fromcvs_process_file(fileName)
6191e72d8d2Sderaadt const char *fileName;
6201e72d8d2Sderaadt {
6212286d8edStholo char *args;
6221e72d8d2Sderaadt WrapperEntry *e=wrap_matching_entry(fileName);
6231e72d8d2Sderaadt
6241e72d8d2Sderaadt if(e==NULL || e->fromcvsFilter==NULL)
625780d15dfStholo return;
6261e72d8d2Sderaadt
6272286d8edStholo args = xmalloc (strlen (e->fromcvsFilter)
6282286d8edStholo + strlen (fileName));
6292ddaa231Sotto
6302ddaa231Sotto wrap_clean_fmt_str(e->fromcvsFilter, 1);
6312286d8edStholo sprintf (args, e->fromcvsFilter, fileName);
6322286d8edStholo run_setup (args);
6331e72d8d2Sderaadt run_exec(RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL );
6342286d8edStholo free (args);
635780d15dfStholo return;
6361e72d8d2Sderaadt }
637