diff options
Diffstat (limited to 'contrib/cvs/src/wrapper.c')
-rw-r--r-- | contrib/cvs/src/wrapper.c | 214 |
1 files changed, 168 insertions, 46 deletions
diff --git a/contrib/cvs/src/wrapper.c b/contrib/cvs/src/wrapper.c index 8a6ff94..13e7e43 100644 --- a/contrib/cvs/src/wrapper.c +++ b/contrib/cvs/src/wrapper.c @@ -1,4 +1,15 @@ +/* This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. */ + #include "cvs.h" +#include "getline.h" /* Original Author: athan@morgan.com <Andrew C. Athan> 2/1/94 @@ -22,6 +33,7 @@ -f from cvs filter value: path to filter -t to cvs filter value: path to filter -m update methodology value: MERGE or COPY + -k default -k rcs option to use on import or add and value is a single-quote delimited value. @@ -34,7 +46,7 @@ typedef struct { char *wildCard; char *tocvsFilter; char *fromcvsFilter; - char *conflictHook; + char *rcsOption; WrapMergeMethod mergeMethod; } WrapperEntry; @@ -44,7 +56,16 @@ static WrapperEntry **wrap_saved_list=NULL; static int wrap_size=0; static int wrap_count=0; static int wrap_tempcount=0; + +/* FIXME: wrap_saved_count is never set to any non-zero value. + wrap_name_has and wrap_matching_entry should be using + wrap_tempcount instead. I believe the consequence of this is that + .cvswrappers files are ignored (that was my own experience when I + tried to use one). If this bug is fixed, would be nice to write a + sanity.sh testcase for .cvswrappers files. */ + static int wrap_saved_count=0; + static int wrap_saved_tempcount=0; #define WRAPPER_GROW 8 @@ -58,27 +79,81 @@ void wrap_restore_saved PROTO((void)); void wrap_setup() { - char file[PATH_MAX]; struct passwd *pw; - /* Then add entries found in repository, if it exists */ - (void) sprintf (file, "%s/%s/%s", CVSroot, CVSROOTADM, CVSROOTADM_WRAPPER); - if (isfile (file)){ - wrap_add_file(file,0); +#ifdef CLIENT_SUPPORT + if (!client_active) +#endif + { + char *file; + + file = xmalloc (strlen (CVSroot_directory) + + sizeof (CVSROOTADM) + + sizeof (CVSROOTADM_WRAPPER) + + 10); + /* Then add entries found in repository, if it exists. */ + (void) sprintf (file, "%s/%s/%s", CVSroot_directory, CVSROOTADM, + CVSROOTADM_WRAPPER); + if (isfile (file)) + { + wrap_add_file(file,0); + } + free (file); } - /* Then add entries found in home dir, (if user has one) and file exists */ - if ((pw = (struct passwd *) getpwuid (getuid ())) && pw->pw_dir){ + /* Then add entries found in home dir, (if user has one) and file + exists. (FIXME: I think this probably should be using + get_homedir, i.e. $HOME). */ + if ((pw = (struct passwd *) getpwuid (getuid ())) && pw->pw_dir) + { + char *file; + + file = xmalloc (strlen (pw->pw_dir) + sizeof (CVSDOTWRAPPER) + 10); (void) sprintf (file, "%s/%s", pw->pw_dir, CVSDOTWRAPPER); - if (isfile (file)){ + if (isfile (file)) + { wrap_add_file (file, 0); } + free (file); } - /* Then add entries found in CVSWRAPPERS environment variable. */ + /* Then add entries found in CVSWRAPPERS environment variable. */ wrap_add (getenv (WRAPPER_ENV), 0); } +#ifdef CLIENT_SUPPORT +/* Send -W arguments for the wrappers to the server. The command must + be one that accepts them (e.g. update, import). */ +void +wrap_send () +{ + int i; + + for (i = 0; i < wrap_count + wrap_tempcount; ++i) + { + if (wrap_list[i]->tocvsFilter != NULL + || wrap_list[i]->fromcvsFilter != NULL) + /* For greater studliness we would print the offending option + and (more importantly) where we found it. */ + error (0, 0, "\ +-t and -f wrapper options are not supported remotely; ignored"); + if (wrap_list[i]->mergeMethod == WRAP_COPY) + /* For greater studliness we would print the offending option + and (more importantly) where we found it. */ + error (0, 0, "\ +-m wrapper option is not supported remotely; ignored"); + if (wrap_list[i]->rcsOption != NULL) + { + send_to_server ("Argument -W\012Argument ", 0); + send_to_server (wrap_list[i]->wildCard, 0); + send_to_server (" -k '", 0); + send_to_server (wrap_list[i]->rcsOption, 0); + send_to_server ("'\012", 0); + } + } +} +#endif /* CLIENT_SUPPORT */ + /* * Open a file and read lines, feeding each line to a line parser. Arrange * for keeping a temporary list of wrappers at the end, if the "temp" @@ -90,17 +165,28 @@ wrap_add_file (file, temp) int temp; { FILE *fp; - char line[1024]; - - wrap_restore_saved(); - wrap_kill_temp(); - - /* load the file */ - if (!(fp = fopen (file, "r"))) + char *line = NULL; + size_t line_allocated = 0; + + wrap_restore_saved (); + wrap_kill_temp (); + + /* Load the file. */ + fp = CVS_FOPEN (file, "r"); + if (fp == NULL) + { + if (!existence_error (errno)) + error (0, errno, "cannot open %s", file); return; - while (fgets (line, sizeof (line), fp)) + } + while (getline (&line, &line_allocated, fp) >= 0) wrap_add (line, temp); - (void) fclose (fp); + if (line) + free (line); + if (ferror (fp)) + error (0, errno, "cannot read %s", file); + if (fclose (fp) == EOF) + error (0, errno, "cannot close %s", file); } void @@ -132,13 +218,13 @@ void wrap_free_entry_internal(e) WrapperEntry *e; { - free(e->wildCard); - if(e->tocvsFilter) - free(e->tocvsFilter); - if(e->fromcvsFilter) - free(e->fromcvsFilter); - if(e->conflictHook) - free(e->conflictHook); + free (e->wildCard); + if (e->tocvsFilter) + free (e->tocvsFilter); + if (e->fromcvsFilter) + free (e->fromcvsFilter); + if (e->rcsOption) + free (e->rcsOption); } void @@ -208,7 +294,15 @@ wrap_add (line, isTemp) for(temp=++line;*line && (*line!='\'' || line[-1]=='\\');++line) ; - if(line==temp+1) + /* This used to "break;" (ignore the option) if there was a + single character between the single quotes (I'm guessing + that was accidental). Now it "break;"s if there are no + characters. I'm not sure either behavior is particularly + necessary--the current options might not require '' + arguments, but surely some future option legitimately + might. Also I'm not sure that ignoring the option is a + swift way to handle syntax errors in general. */ + if (line==temp) break; ctemp=*line; @@ -232,21 +326,19 @@ wrap_add (line, isTemp) if (!e.tocvsFilter) error (1, 0, "Correct above errors first"); break; - case 'c': - if(e.conflictHook) - free(e.conflictHook); - /* FIXME: error message should say where the bad value - came from. */ - e.conflictHook=expand_path (temp, "<wrapper>", 0); - if (!e.conflictHook) - error (1, 0, "Correct above errors first"); - break; case 'm': + /* FIXME: look into whether this option is still relevant given + the 24 Jun 96 change to merge_file. */ if(*temp=='C' || *temp=='c') e.mergeMethod=WRAP_COPY; else e.mergeMethod=WRAP_MERGE; break; + case 'k': + if (e.rcsOption) + free (e.rcsOption); + e.rcsOption = xstrdup (temp); + break; default: break; } @@ -281,8 +373,8 @@ wrap_add_entry(e, temp) wrap_list[x]->wildCard=e->wildCard; wrap_list[x]->fromcvsFilter=e->fromcvsFilter; wrap_list[x]->tocvsFilter=e->tocvsFilter; - wrap_list[x]->conflictHook=e->conflictHook; wrap_list[x]->mergeMethod=e->mergeMethod; + wrap_list[x]->rcsOption = e->rcsOption; } /* Return 1 if the given filename is a wrapper filename */ @@ -303,8 +395,8 @@ wrap_name_has (name,has) case WRAP_FROMCVS: temp=wrap_list[x]->fromcvsFilter; break; - case WRAP_CONFLICT: - temp=wrap_list[x]->conflictHook; + case WRAP_RCSOPTION: + temp = wrap_list[x]->rcsOption; break; default: abort (); @@ -317,7 +409,9 @@ wrap_name_has (name,has) return (0); } -WrapperEntry * +static WrapperEntry *wrap_matching_entry PROTO ((const char *)); + +static WrapperEntry * wrap_matching_entry (name) const char *name; { @@ -329,17 +423,46 @@ wrap_matching_entry (name) return (WrapperEntry *)NULL; } +/* Return the RCS options for FILENAME in a newly malloc'd string. If + ASFLAG, then include "-k" at the beginning (e.g. "-kb"), otherwise + just give the option itself (e.g. "b"). */ +char * +wrap_rcsoption (filename, asflag) + const char *filename; + int asflag; +{ + WrapperEntry *e = wrap_matching_entry (filename); + char *buf; + + if (e == NULL || e->rcsOption == NULL || (*e->rcsOption == '\0')) + return NULL; + + buf = xmalloc (strlen (e->rcsOption) + 3); + if (asflag) + { + strcpy (buf, "-k"); + strcat (buf, e->rcsOption); + } + else + { + strcpy (buf, e->rcsOption); + } + return buf; +} + char * wrap_tocvs_process_file(fileName) const char *fileName; { WrapperEntry *e=wrap_matching_entry(fileName); - static char buf[L_tmpnam+1]; + static char *buf = NULL; if(e==NULL || e->tocvsFilter==NULL) return NULL; - tmpnam(buf); + if (buf != NULL) + free (buf); + buf = cvs_temp_name (); run_setup(e->tocvsFilter,fileName,buf); run_exec(RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL|RUN_REALLY ); @@ -358,17 +481,16 @@ wrap_merge_is_copy (fileName) return 1; } -char * +void wrap_fromcvs_process_file(fileName) const char *fileName; { WrapperEntry *e=wrap_matching_entry(fileName); - static char buf[PATH_MAX]; if(e==NULL || e->fromcvsFilter==NULL) - return NULL; + return; run_setup(e->fromcvsFilter,fileName); run_exec(RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL ); - return buf; + return; } |