1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696 |
- /*
- * CDE - Common Desktop Environment
- *
- * Copyright (c) 1993-2012, The Open Group. All rights reserved.
- *
- * These libraries and programs are free software; you can
- * redistribute them and/or modify them under the terms of the GNU
- * Lesser General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * These libraries and programs are distributed in the hope that
- * they will be useful, but WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with these librararies and programs; if not, write
- * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
- * Floor, Boston, MA 02110-1301 USA
- */
- /***************************************************************************
- *
- * File: findnewrcs.c
- * RCS: $XConsortium: findnewrcs.c /main/3 1995/10/30 13:42:46 rswiston $
- * Description: The 'findnewrcs' command is used to descend a tree, checking
- * out the newest version of any RCS file which has been updated.
- * It can also be used to create a clone of a source tree using
- * symbolic links.
- * Author: Dave Serisky, Corvallis Workstation Operation
- * Created: Tue Jun 7 09:39:47 1988
- * Modified: Brian Cripe, (bcripe@hpcvlx) bcripe@hpcvxbc
- * Modified: Marc Ayotte, (marca@hpcvlx)
- * Language: C
- * Package: N/A
- * Status: Experimental (Do Not Distribute)
- *
- * (c) Copyright 1988, Hewlett-Packard Company, all rights reserved.
- *
- ********************************************************************************
- */
- static char version[] = "@(#) $XConsortium: findnewrcs.c /main/3 1995/10/30 13:42:46 rswiston $";
- #include <stdio.h>
- #include <string.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #ifdef apollo
- #ifndef S_ISLNK
- #define S_ISLNK(m) (((m) & 0170000) == 0120000)
- #endif
- #ifndef S_ISDIR
- #define S_ISDIR(m) (((m) & 0170000) == 0040000)
- #endif
- #ifndef S_ISREG
- #define S_ISREG(m) (((m) & 0170000) == 0100000)
- #endif
- #define UID_NO_CHANGE -1
- #include <sys/dir.h>
- #else
- # if defined(USL) && !defined(S_ISLNK)
- # define S_ISLNK(m) ((m&0xF000) == S_IFLNK)
- # endif
- #include <dirent.h>
- #endif
- #ifndef __hpux
- #define UID_NO_CHANGE -1
- #endif
- #include <errno.h>
- #include <fcntl.h>
- #include <grp.h>
- #ifdef apollo
- #include <sys/time.h>
- #else
- #include <utime.h>
- #endif
- extern char *getcwd();
- extern char *malloc();
- extern DIR *opendir();
- #ifdef apollo
- extern struct direct *readdir();
- #else
- extern struct dirent *readdir();
- #endif
- extern long telldir();
- extern char *mktemp();
- char Buffer[BUFSIZ];
- char *WorkingDirCmp;
- int WorkingLen;
- char *SourceDirCmp;
- int SourceLen;
- void GetNew();
- char *ResolveLink();
- static int Debug = 0;
- static int Quiet = 0;
- static int Verbose = 0;
- static int MakeDirs = 0;
- static int DoDiffs = 0;
- static int SourcePriority = 0;
- static int NoRcsLinks = 0;
- static int NoRealFiles = 0;
- static int LinkFiles = 0;
- static int CloneDotA = 0;
- static int CloneDotO = 0;
- static int CloneMakefile = 0;
- static int CloneExecutables = 0;
- static int Check = 0;
- static int DoExecute = 0;
- static int FollowDirLinks = 0;
- static int ResolveFileLinks = 1;
- static int ProcessSCCSdirs = 0;
- static char *DiffCommand = "diff";
- static char *OutFile = "/tmp/,outXXXXXX";
- static char *Makefile = "Makefile";
- typedef struct _flist {
- char *fullname;
- char *keyname;
- int keylen;
- int used;
- struct stat st;
- int st_valid;
- struct stat lst;
- int lst_valid;
- struct _flist *next;
- } flist;
- void
- Usage(ProgName)
- char *ProgName;
- {
- (void) fprintf(stderr, "\
- usage: %s [options] [-W <working dir>] [-S <RCS dir>] [subdir ...] \n\
- \n\
- options:\n\
- -i[Aaoxm]\n\
- clone: A - all the following\n\
- a - \"*.a\" files\n\
- o - \"*.o\" files\n\
- x - executables ('x' mode bits set)\n\
- m - \"Makefile*\" files\n\
- -v verbose (the more, the verboser)\n\
- source files\n\
- -L take checked out source over RCS regardless of time\n\
- -O don't check out new files, Only create symbolic links to exiting files\n\
- (this option is for cloning build trees from controlled source trees)\n\
- -R don't create any RCS links\n\
- -l symbolicly link files instead of copying them\n\
- -m make any missing directories\n\
- -q quiet\n\
- -d diff new versions of existing files\n\
- -c<cmd> use <cmd> to do diffs (default is diffc)\n\
- -o<out> write diffs to <out> instead of /tmp/,out??????\n\
- -W<dir> use working directory <dir> (default is \".\")\n\
- -S<dir> use RCS/source directory <dir>\n\
- (default is /RCS directories of working tree)\n\
- -f follow source-tree links to non-RCS dirs (old behavior)\n\
- -X execute instead of generating shell script\n\
- -C process SCCS directories if present\n\
- -s do not resolve symbolic links for files. use file name\n\
- ", ProgName);
- (void) exit(1);
- }
- static void do_rm_rf(), do_touch(), do_ln_s(), do_diff(), do_rm_f();
- static void do_cp(), do_chmod(), do_co_q(), do_mkdir(), do_chgrp();
- main(argc, argv)
- int argc;
- char **argv;
- {
- char *WorkingDir = (char *) 0;
- char *SourceDir = (char *) 0;
- register int i;
- register char *c;
- int same = 0;
- struct stat st;
- extern int getopt();
- extern char *optarg;
- extern int optind;
- extern int opterr;
- (void) setvbuf(stdout, (char *) 0, _IOLBF, BUFSIZ);
- OutFile = mktemp(OutFile);
- while ((i = getopt(argc, argv, "-S:-W:i:OLRXflsCmqvd~c:o:")) != EOF) {
- switch (i) {
- case 'W' :
- /* Working directory. Default is current directory */
- WorkingDir = optarg;
- break;
- case 'S' :
- /* Source directory. Default is to use working directories
- ** /RCS directories.
- */
- SourceDir = optarg;
- break;
- case 'i' :
- /* Parse off no ignore options */
- for (c = optarg; *c; c++) {
- switch (*c) {
- case 'A' :
- /* don't ignore any... */
- (void) CloneDotA++;
- (void) CloneDotO++;
- (void) CloneExecutables++;
- (void) CloneMakefile++;
- break;
- case 'a' :
- /* don't ignore *.a files */
- (void) CloneDotA++;
- break;
- case 'o' :
- /* don't ignore *.o files */
- (void) CloneDotO++;
- break;
- case 'x' :
- /* don't ignore executables */
- (void) CloneExecutables++;
- break;
- case 'm' :
- /* don't ignore Makefiles */
- (void) CloneMakefile++;
- break;
- default :
- (void) Usage(argv[0]);
- (void) exit(1);
- break;
- }
- }
- break;
- case 'R' :
- /* dont create any links for "/RCS" */
- (void) NoRcsLinks++;
- break;
- case 'L' :
- /* Take existing checked out files even if they are older than
- ** the RCS copy.
- */
- (void) SourcePriority++;
- break;
-
- case 'O' :
- /* Don't check out new files, just create sym links to existing files.
- ** This is to protect controlled source/build trees from having
- ** files bypass the crt process.
- */
- (void) NoRealFiles++;
- break;
-
- case 'f' :
- FollowDirLinks = 1;
- break;
- case 'C' :
- ProcessSCCSdirs = 1;
- break;
- case 'X' :
- DoExecute = 1;
- break;
- case 'l' :
- /* Link files (when possible) instead of creating them. */
- (void) LinkFiles++;
- break;
- case 'm' :
- /* Make any directories necessary. */
- (void) MakeDirs++;
- break;
- case 'q' :
- /* Be quiet. */
- (void) Quiet++;
- break;
- case 'v' :
- /* Increase verbosity. */
- (void) Verbose++;
- break;
- case 'd' :
- /* Diff out new files. */
- (void) DoDiffs++;
- break;
- case 'c' :
- /* Alternative diff command. */
- DiffCommand = optarg;
- break;
- case 'o' :
- /* Output file name for diffs */
- OutFile = optarg;
- break;
- case 's' :
- /* don't resolve symbolic links for files */
- ResolveFileLinks = 0;
- break;
- case '~' :
- /* Increment debug switch */
- (void) Debug++;
- break;
-
- default:
- (void) Usage(argv[0]);
- (void) exit(1);
- break;
- }
- }
- /* no WorkingDir specified or not root relative? */
- if (!WorkingDir || !*WorkingDir || ('/' != *WorkingDir)) {
- /* get the current directory */
- if (NULL == (c = getcwd(Buffer, sizeof(Buffer)))) {
- (void) fprintf(stderr, "%s: can't get current working directory\n",
- argv[0]);
- (void) exit(1);
- }
- /* did they specify a partial path? */
- if (WorkingDir && *WorkingDir) {
- /* prepend the path to the working dir */
- char *c2;
- c2 = malloc((unsigned) (strlen(c) + strlen(WorkingDir) + 2));
- (void) sprintf(c2, "%s/%s", c, WorkingDir);
- WorkingDir = c2;
- } else {
- /* working dir is current path */
- WorkingDir = malloc((unsigned) (strlen(c) + 1));
- (void) strcpy(WorkingDir, c);
- }
- }
- /* SourceDir specified? */
- if (!SourceDir || !*SourceDir) {
- /* Let's see if there is an /RCS dir in WorkingDir */
- SourceDir = malloc((unsigned) (strlen(WorkingDir) + 5));
- (void) strcpy(SourceDir, WorkingDir);
- (void) strcat(SourceDir, "/RCS");
- if (!lstat(SourceDir, &st)) {
- if (S_ISLNK(st.st_mode)) {
- SourceDir = ResolveLink(SourceDir, 1);
- }
- }
- /* strip off the "/RCS" portion of it */
- c = strrchr(SourceDir, '/');
- if (*c && !strcmp(c, "/RCS"))
- *c = '\0';
- (void) fprintf(stderr, "using sourcedir of \"%s\"\n", SourceDir);
- } else {
- /* is it root relative? */
- if ('/' != *SourceDir) {
- /* get the current directory */
- char *c2;
- if (NULL == (c = getcwd(Buffer, sizeof(Buffer)))) {
- (void) fprintf(stderr,
- "%s: can't get current working directory\n",
- argv[0]);
- (void) exit(1);
- }
- c2 = malloc((unsigned) (strlen(c) + strlen(SourceDir) + 2));
- (void) sprintf(c2, "%s/%s", c, SourceDir);
- SourceDir = c2;
- }
- }
- /* are the 2 directories the same name?
- */
- if (!strcmp(SourceDir, WorkingDir)) {
- (void) same++;
- }
- WorkingDirCmp = malloc((unsigned) (strlen(WorkingDir) + 2));
- (void) strcpy(WorkingDirCmp, WorkingDir);
- (void) strcat(WorkingDirCmp, "/");
- SourceDirCmp = malloc((unsigned) (strlen(SourceDir) + 2));
- (void) strcpy(SourceDirCmp, SourceDir);
- (void) strcat(SourceDirCmp, "/");
- WorkingLen = strlen(WorkingDirCmp);
- SourceLen = strlen(SourceDirCmp);
- if (DoExecute)
- {
- if (DoDiffs)
- {
- do_rm_rf(OutFile);
- do_touch(OutFile);
- }
- }
- else
- {
- printf("#!/bin/sh\n");
- printf("#\n# the following makes things more readeable\n\n");
- printf("w='%s'\t# Working directory\n", WorkingDir);
- printf("s='%s'\t# Source directory\n", SourceDir);
- if (DoDiffs)
- printf("rm -rf %s; touch %s\n", OutFile, OutFile);
- printf("\n");
- }
- if (optind < argc) {
- char *SubSourceDir;
- char *SubWorkingDir;
- for (; optind < argc; optind++) {
- SubSourceDir = malloc((unsigned) (strlen(SourceDir) +
- strlen(argv[optind]) + 2));
- (void) sprintf(SubSourceDir, "%s/%s", SourceDir, argv[optind]);
- SubWorkingDir = malloc((unsigned) (strlen(WorkingDir) +
- strlen(argv[optind]) + 2));
- (void) sprintf(SubWorkingDir, "%s/%s", WorkingDir, argv[optind]);
- (void) GetNew(SubWorkingDir, SubSourceDir, same);
- (void) free(SubWorkingDir);
- (void) free(SubSourceDir);
- }
- } else {
- (void) GetNew(WorkingDir, SourceDir, same);
- }
- (void) exit(0);
- /*NOTREACHED*/
- }
- void
- GetNew(WorkingDir, SourceDir, same)
- char *WorkingDir;
- char *SourceDir;
- int same;
- {
- FILE *f;
- char *NextSourceDir;
- char *NextWorkingDir;
- char *RcsDir;
- char *SourceFile;
- char *WorkingFile;
- int FreeSourceFile;
- int FreeWorkingFile;
- DIR *D;
- #ifdef apollo
- struct direct *dir;
- #else
- struct dirent *dir;
- #endif
- struct stat st;
- int Tries;
- char *c,*d;
- char buf[BUFSIZ];
- flist *WorkingHead = (flist *) 0;
- flist *SourceHead = (flist *) 0;
- flist *RcsHead = (flist *) 0;
- flist *WorkingPtr;
- flist *SourcePtr;
- flist *RcsPtr;
- int shouldnt_have_source;
- if (Verbose)
- (void) fprintf(stderr, "Scanning directory \"%s\"\n", SourceDir);
- if (Debug > 1)
- (void) fprintf(stderr, ">> GetNew(\"%s\", \"%s\")\n", WorkingDir,
- SourceDir);
- /* set up the working directory's RCS directory name */
- RcsDir = malloc((unsigned char *) strlen(WorkingDir) + strlen("/RCS") + 1);
- (void) sprintf(RcsDir, "%s/RCS", WorkingDir);
- if (Debug > 0)
- (void) fprintf(stderr, ">> RcsDir=\"%s\"\n", RcsDir);
- /* check to see if the working dir's RCS directory exists */
- /* if you can't stat it and it is a symlink to nowhere, do not
- * recreate the link. The cde source server works on RCS symlinks
- * to nowhere.
- */
- if (stat(RcsDir, &st)) {
- /* if not a symlink, create the RCS directory */
- if (readlink(RcsDir, buf, sizeof(buf)) < 0) {
- /* no -- create one off of the SourceDir */
- c = malloc((unsigned char *) strlen(SourceDir) +
- strlen("/RCS") + 1);
- (void) sprintf(c, "%s/RCS", SourceDir);
- d = malloc((unsigned char *) strlen(SourceDir) +
- strlen("/RCS") + 1);
- (void) sprintf(d, "%s/RCS", SourceDir);
- /* resolve out symbolic links */
- c = ResolveLink(c, 1);
- if (Debug > 0)
- (void) fprintf(stderr, ">> RCS RcsDir=\"%s\"\n", c);
- /* do we want RCS links? */
- /* If Rcsdir points to a symlink, recreate the link
- * even if no destination directory exists.
- */
- if ((!stat(c, &st) || (readlink(d, buf, sizeof(buf)) > 0))
- && !NoRcsLinks) {
- /* yes -- since the WorkingDir didn't have an /RCS directory,
- ** let's make one.
- */
- if (!Quiet)
- (void) fprintf(stderr, "%s: creating symlink\n",
- RcsDir + WorkingLen);
- /* check and see if the RCS dir is in the SourceDir */
- if (DoExecute)
- {
- do_rm_f(RcsDir);
- do_ln_s(c, RcsDir);
- }
- else
- {
- /* remove the link before linking */
- (void) printf("rm -f ${w}/%s\n",
- RcsDir + WorkingLen);
- if (strncmp(c, SourceDir, SourceLen) ||
- (c[SourceLen] != '/')) {
- /* need full RCS path */
- (void) printf("ln -s %s ${w}/%s\n",
- c, RcsDir + WorkingLen);
- }
- else {
- /* RCS path is relative to SourceDir */
- (void) printf("ln -s ${s}/%s ${w}/%s\n",
- c + SourceLen, RcsDir + WorkingLen);
- }
- }
- }
- (void) free(RcsDir);
- RcsDir = c;
- }
- }
- /* resolve "fake" symbolic links to get a real directory */
- for (Tries = 10; Tries > 0; Tries--) {
- if (!lstat(RcsDir, &st)) {
- if (S_ISLNK(st.st_mode)) {
- RcsDir = ResolveLink(RcsDir, 1);
- } else if (S_ISREG(st.st_mode)) {
- /* open the file... */
- if (f = fopen(RcsDir, "r")) {
- /* read it... */
- (void) fgets(Buffer, sizeof(Buffer), f);
- Buffer[strlen(Buffer) - 1] = '\0';
- (void) free(RcsDir);
- /* RcsDir is the contents of the file... */
- RcsDir = malloc((unsigned) strlen(Buffer) + 1);
- (void) strcpy(RcsDir, Buffer);
- if (Debug)
- (void) fprintf(stderr, ">> soft link RcsDir=\"%s\"\n",
- RcsDir);
- /* we are done, close it... */
- (void) fclose(f);
- }
- } else {
- /* not a symlink or "soft" link */
- break;
- }
- } else {
- /* directory does not exist */
- break;
- }
- }
- if (Tries <= 0) {
- if (!Quiet)
- (void) fprintf(stderr, "%s: >10 \"soft\" links\n", RcsDir);
- }
- /* cd to the RcsDir, and scan it */
- RcsHead = (flist *) 0;
- if (chdir(RcsDir)) {
- if (errno != ENOENT)
- (void) perror(RcsDir);
- } else {
- if (D = opendir(".")) {
- while (dir = readdir(D)) {
- /* all RCS files have a length > 2 */
- #ifndef apollo
- if (strlen(dir->d_name) < 3)
- #else
- if (dir->d_namlen < 3)
- #endif
- continue;
-
- /* all RCS files have a name ending in ",v" */
- #ifndef apollo
- if (strcmp(dir->d_name + strlen(dir->d_name) - 2, ",v"))
- #else
- if (strcmp(dir->d_name + dir->d_namlen - 2, ",v"))
- #endif
- continue;
- /* build the full name of the file */
- (void) strcpy(Buffer, RcsDir);
- (void) strcat(Buffer, "/");
- (void) strcat(Buffer, dir->d_name);
- /* stat the file */
- if (stat(dir->d_name, &st)) {
- (void) perror(Buffer);
- continue;
- }
- /* Valid entry. It's time to stuff it away */
- if (RcsHead) {
- RcsPtr->next = (flist *) malloc(sizeof(flist));
- RcsPtr = RcsPtr->next;
- } else {
- RcsHead = (flist *) malloc(sizeof(flist));
- RcsPtr = RcsHead;
- }
- /* null out link */
- RcsPtr->next = (flist *) 0;
- /* this entry is new */
- RcsPtr->used =0;
- /* stuff away full path */
- RcsPtr->fullname = malloc((unsigned) (strlen(Buffer) + 1));
- (void) strcpy(RcsPtr->fullname, Buffer);
- /* drop ",v" of dir->d_name */
- /* stuff away key path */
- #ifndef apollo
- dir->d_name[strlen(dir->d_name) - 2] = '\0';
- RcsPtr->keyname = malloc((unsigned) (strlen(dir->d_name) + 1));
- (void) strcpy(RcsPtr->keyname, dir->d_name);
- RcsPtr->keylen = strlen(dir->d_name);
- #else
- dir->d_name[dir->d_namlen - 2] = '\0';
- dir->d_namlen -= 2;
- RcsPtr->keyname = malloc((unsigned) (dir->d_namlen + 1));
- (void) strcpy(RcsPtr->keyname, dir->d_name);
- RcsPtr->keylen = dir->d_namlen;
- #endif
- /* stuff away stat structure */
- RcsPtr->st = st;
- RcsPtr->st_valid = 1;
- RcsPtr->lst_valid = 0;
- }
- (void) closedir(D);
- }
- }
- /* cd to the WorkingDir, and scan it */
- WorkingHead = (flist *) 0;
- if (chdir(WorkingDir)) {
- if (errno != ENOENT)
- (void) perror(WorkingDir);
- } else {
- if (D = opendir(".")) {
- while (dir = readdir(D)) {
- /* ignore "." and ".." */
- #ifndef apollo
- if (('.' == *(dir->d_name)) || (!strcmp(dir->d_name, "..")))
- continue;
- #else
- if (((1 == dir->d_namlen) && ('.' == *(dir->d_name))) ||
- ((2 == dir->d_namlen) && !strcmp(dir->d_name, "..")))
- continue;
- #endif
-
- /* build the full name of the file */
- (void) strcpy(Buffer, WorkingDir);
- (void) strcat(Buffer, "/");
- (void) strcat(Buffer, dir->d_name);
- /* stat the file */
- if (stat(dir->d_name, &st)) {
- /* don't send error if RCS directory is a
- * symlink to nowhere.
- */
- if (strcmp("RCS",dir->d_name)) {
- (void) perror(Buffer);
- }
- continue;
- }
- /* Valid entry. It's time to stuff it away */
- if (WorkingHead) {
- WorkingPtr->next = (flist *) malloc(sizeof(flist));
- WorkingPtr = WorkingPtr->next;
- } else {
- WorkingHead = (flist *) malloc(sizeof(flist));
- WorkingPtr = WorkingHead;
- }
- /* null out link */
- WorkingPtr->next = (flist *) 0;
- /* this entry is new */
- WorkingPtr->used =0;
- /* stuff away full path */
- WorkingPtr->fullname = malloc((unsigned) (strlen(Buffer) + 1));
- (void) strcpy(WorkingPtr->fullname, Buffer);
- /* stuff away key path */
- #ifndef apollo
- WorkingPtr->keyname = malloc((unsigned) (strlen(dir->d_name) + 1));
- (void) strcpy(WorkingPtr->keyname, dir->d_name);
- WorkingPtr->keylen = strlen(dir->d_name);
- #else
- WorkingPtr->keyname = malloc((unsigned) (dir->d_namlen + 1));
- (void) strcpy(WorkingPtr->keyname, dir->d_name);
- WorkingPtr->keylen = dir->d_namlen;
- #endif
- /* stuff away stat structure */
- WorkingPtr->st = st;
- WorkingPtr->st_valid = 1;
- if (S_ISDIR(st.st_mode) && !lstat(dir->d_name, &st))
- {
- WorkingPtr->lst = st;
- WorkingPtr->lst_valid = 1;
- }
- else
- WorkingPtr->lst_valid = 0;
- }
- (void) closedir(D);
- }
- }
- /* cd to the SourceDir, and scan it. If the dirs are the same, we
- ** can just forget this part
- */
- SourceHead = (flist *) 0;
- if (!same) {
- if (chdir(SourceDir)) {
- if (errno != ENOENT)
- (void) perror(SourceDir);
- } else {
- if (D = opendir(".")) {
- while (dir = readdir(D)) {
- /* ignore "." and ".." */
- #ifndef apollo
- if ((('.' == *(dir->d_name))) ||
- (!strcmp(dir->d_name, "..")))
- continue;
- #else
- if (((1 == dir->d_namlen) && ('.' == *(dir->d_name))) ||
- ((2 == dir->d_namlen) &&
- !strcmp(dir->d_name, "..")))
- continue;
- #endif
-
- /* build the full name of the file */
- (void) strcpy(Buffer, SourceDir);
- (void) strcat(Buffer, "/");
- (void) strcat(Buffer, dir->d_name);
- /* lstat the file */
- if (lstat(dir->d_name, &st)) {
- (void) perror(Buffer);
- continue;
- }
- /* Valid entry. It's time to stuff it away */
- if (SourceHead) {
- SourcePtr->next = (flist *) malloc(sizeof(flist));
- SourcePtr = SourcePtr->next;
- } else {
- SourceHead = (flist *) malloc(sizeof(flist));
- SourcePtr = SourceHead;
- }
- /* null out link */
- SourcePtr->next = (flist *) 0;
- /* this entry is new */
- SourcePtr->used =0;
- /* stuff away full path */
- SourcePtr->fullname =
- malloc((unsigned) (strlen(Buffer) + 1));
- (void) strcpy(SourcePtr->fullname, Buffer);
- /* stuff away key path */
- #ifndef apollo
- SourcePtr->keyname = malloc((unsigned) (strlen(dir->d_name) + 1));
- (void) strcpy(SourcePtr->keyname, dir->d_name);
- SourcePtr->keylen = strlen(dir->d_name);
- #else
- SourcePtr->keyname = malloc((unsigned) (dir->d_namlen + 1));
- (void) strcpy(SourcePtr->keyname, dir->d_name);
- SourcePtr->keylen = dir->d_namlen;
- #endif
- /* stuff away lstat structure */
- SourcePtr->lst = st;
- SourcePtr->lst_valid = 1;
- /* was it a symbolic link? */
- if (S_ISLNK(st.st_mode)) {
- /* do a plain stat on it */
- (void) stat(dir->d_name, &st);
- }
- /* stuff it away */
- SourcePtr->st = st;
- SourcePtr->st_valid = 1;
- }
- (void) closedir(D);
- }
- }
- }
- /*
- ** PASS 1:
- **
- ** Check all the files in the working dir.
- */
- if (Debug)
- (void) fprintf(stderr, ">> Pass 1: scanning WorkingDir \"%s\"\n",
- WorkingDir);
- for (WorkingPtr = WorkingHead; WorkingPtr; WorkingPtr = WorkingPtr->next) {
- /* initialize */
- if (Debug > 1)
- (void) fprintf(stderr, ">> keyname=\"%s\", fullname=\"%s\"\n",
- WorkingPtr->keyname, WorkingPtr->fullname);
- shouldnt_have_source = 0;
- /* ignore .o and .a files */
- c = WorkingPtr->keyname + WorkingPtr->keylen - 2;
- if (WorkingPtr->keylen >= 2) {
- if (!strcmp(c, ".o")) {
- (void) shouldnt_have_source++;
- if (!CloneDotO) {
- if (Debug > 1)
- (void) fprintf(stderr, ">> .o -- ignored\n");
- continue;
- }
- }
- if (!strcmp(c, ".a")) {
- (void) shouldnt_have_source++;
- if (!CloneDotA) {
- if (Debug > 1)
- (void) fprintf(stderr, ">> .a -- ignored\n");
- continue;
- }
- }
- }
- if (!strncmp(WorkingPtr->keyname, Makefile, strlen(Makefile))) {
- (void) shouldnt_have_source++;
- if (!CloneMakefile) {
- if (Debug > 1)
- (void) fprintf(stderr, ">> Makefile* -- ignored\n");
- continue;
- }
- }
- /* ignore RCS as well */
- if (!strcmp(WorkingPtr->keyname, "RCS")) {
- if (Debug > 1)
- (void) fprintf(stderr, ">> RCS -- ignored\n");
- continue;
- }
- /* ignore SCCS as well */
- if (!(ProcessSCCSdirs)) {
- if (!strcmp(WorkingPtr->keyname, "SCCS")) {
- if (Debug > 1)
- (void) fprintf(stderr, ">> SCCS -- ignored\n");
- continue;
- }
- }
- /* ignore regular files with x mode */
- if (!CloneExecutables && WorkingPtr->st_valid &&
- (S_ISREG(WorkingPtr->st.st_mode)) &&
- (0111 == (WorkingPtr->st.st_mode & 0111))) {
- if (Debug > 1)
- (void) fprintf(stderr, ">> executable -- ignored\n");
- continue;
- }
- /* find corresponding sourcefile */
- for (SourcePtr = SourceHead; SourcePtr; SourcePtr = SourcePtr->next) {
- if ((WorkingPtr->keylen == SourcePtr->keylen) &&
- !strcmp(WorkingPtr->keyname, SourcePtr->keyname)) {
- /* mark it as used */
- (void) SourcePtr->used++;
- break;
- }
- }
-
- if (Debug > 1)
- if (SourcePtr)
- (void) fprintf(stderr,
- " source: keyname=\"%s\" fullname=\"%s\"\n",
- SourcePtr->keyname, SourcePtr->fullname);
- else
- (void) fprintf(stderr, " no source file\n");
- /* is the working file actually a directory? */
- if (WorkingPtr->st_valid &&
- (S_ISDIR(WorkingPtr->st.st_mode))) {
- /* yes, go recursive... */
- if (FollowDirLinks ||
- !WorkingPtr->lst_valid ||
- !S_ISLNK(WorkingPtr->lst.st_mode))
- {
- if (Debug > 1)
- (void) fprintf(stderr, ">> directory\n");
- (void) GetNew(WorkingPtr->fullname,
- SourcePtr ? SourcePtr->fullname : WorkingPtr->fullname,
- same);
- }
- } else {
- /* find corresponding RCS file */
- for (RcsPtr = RcsHead; RcsPtr; RcsPtr = RcsPtr->next) {
- if ((WorkingPtr->keylen == RcsPtr->keylen) &&
- !strcmp(WorkingPtr->keyname, RcsPtr->keyname)) {
- /* mark it as used */
- (void) RcsPtr->used++;
- break;
- }
- }
- if (Debug > 1)
- if (RcsPtr)
- (void) fprintf(stderr,
- " rcs: keyname=\"%s\" fullname=\"%s\"\n",
- RcsPtr->keyname, RcsPtr->fullname);
- else
- (void) fprintf(stderr, " no rcs file\n");
- /* print a message if there is no corresponding source */
- if (!RcsPtr && !SourcePtr) {
- /* don't print a message for .snf files */
- if ((WorkingPtr->keylen > 4) && !strcmp(WorkingPtr->keyname +
- WorkingPtr->keylen - 4, ".snf"))
- (void) shouldnt_have_source++;
- if (Verbose && !shouldnt_have_source)
- (void) fprintf(stderr, "%s: no source or RCS file\n",
- WorkingPtr->fullname + WorkingLen);
- }
- if (!RcsPtr || !RcsPtr->st_valid ||
- (SourcePtr &&
- (SourcePtr->st.st_mtime >= RcsPtr->st.st_mtime)) ||
- (SourcePriority && SourcePtr)) {
- /* no RCS file, or source newer than RCS, or source
- ** exists and has priority
- */
- if (Debug > 1)
- (void) fprintf(stderr, ">> source newer than rcs\n");
- if (SourcePtr &&
- (WorkingPtr->st.st_mtime < SourcePtr->st.st_mtime)) {
- if (Debug > 1)
- (void) fprintf(stderr,
- ">> source newer than working\n");
- /* does the WorkingFile have any write mode bits
- ** set?
- */
- if (WorkingPtr->st.st_mode & 0222) {
- if (!Quiet)
- (void) fprintf(stderr,
- "%s: writable -- not updated\n",
- WorkingPtr->fullname + WorkingLen);
- continue;
- }
- if (!Quiet)
- (void) fprintf(stderr, "%s: newer file\n",
- WorkingPtr->fullname + WorkingLen);
- /* check to see if file symlinks should resolve */
- if (ResolveFileLinks)
- if (SourcePtr->lst_valid &&
- S_ISLNK(SourcePtr->lst.st_mode)) {
- SourceFile = ResolveLink(SourcePtr->fullname, 0);
- FreeSourceFile = 1;
- }
- else {
- SourceFile = SourcePtr->fullname;
- }
- else {
- SourceFile = SourcePtr->fullname;
- }
- /* do we need to do a diff? */
- if (DoDiffs) {
- if (DoExecute)
- {
- do_diff(NULL,
- DiffCommand,
- WorkingPtr->fullname,
- SourceFile,
- OutFile);
- }
- else
- {
- if (strncmp(SourceFile, SourceDirCmp, SourceLen))
- /* not in SourceDir... */
- (void) printf("%s ${w}/%s %s >>%s 2>&1\n",
- DiffCommand,
- WorkingPtr->fullname + WorkingLen,
- SourceFile, OutFile);
- else
- /* in SourceDir... */
- (void) printf("%s ${w}/%s ${s}/%s >>%s 2>&1\n",
- DiffCommand,
- WorkingPtr->fullname + WorkingLen,
- SourceFile + SourceLen, OutFile);
- }
- }
- if (DoExecute)
- {
- do_rm_f(WorkingPtr->fullname);
- if (LinkFiles)
- do_ln_s(SourceFile, WorkingPtr->fullname);
- else
- do_cp(SourceFile, WorkingPtr->fullname);
- }
- else
- {
- if (strncmp(SourceFile, SourceDirCmp, SourceLen)) {
- /* not in SourceDir... */
- (void) printf("rm -f ${w}/%s\n",
- WorkingPtr->fullname + WorkingLen);
- (void) printf("\t%s %s ${w}/%s\n",
- LinkFiles ? "ln -s" : "cp",
- SourceFile,
- WorkingPtr->fullname + WorkingLen);
- } else {
- /* in SourceDir... */
- (void) printf("rm -f ${w}/%s\n",
- WorkingPtr->fullname + WorkingLen);
- (void) printf("\t%s ${s}/%s ${w}/%s\n",
- LinkFiles ? "ln -s" : "cp",
- SourceFile + SourceLen,
- WorkingPtr->fullname + WorkingLen);
- }
- }
- if (!LinkFiles)
- {
- /* don't chmod the file if we did a link... */
- if (DoExecute)
- {
- do_chmod(WorkingPtr->fullname,
- (SourcePtr->st.st_mode & 07777 & ~0222) | 0444);
- }
- else
- (void) printf("\tchmod 0%03o ${w}/%s\n",
- (SourcePtr->st.st_mode & 07777 & ~0222) | 0444,
- WorkingPtr->fullname + WorkingLen);
- }
- if (FreeSourceFile)
- (void) free(SourceFile);
- } else {
- if (Debug > 1)
- (void) fprintf(stderr,
- ">> source older than working\n");
- }
- } else {
- /* RCS file is the newest */
- if (Debug > 1)
- (void) fprintf(stderr, ">> rcs newer than source\n");
- if (RcsPtr && (WorkingPtr->st.st_mtime < RcsPtr->st.st_mtime)) {
- if (Debug > 1)
- (void) fprintf(stderr,
- ">> rcs newer than working\n");
- /* does the WorkingFile have any write mode bits
- ** set?
- */
- if (WorkingPtr->st.st_mode & 0222) {
- if (!Quiet)
- (void) fprintf(stderr,
- "%s: writable -- not updated\n",
- WorkingPtr->fullname + WorkingLen);
- continue;
- }
- if (!Quiet)
- (void) fprintf(stderr, "%s: newer RCS file\n",
- WorkingPtr->fullname + WorkingLen);
- if (DoExecute)
- {
- do_diff(RcsDir, DiffCommand,
- RcsPtr->keyname,
- WorkingPtr->fullname,
- OutFile);
- if (! NoRealFiles)
- {
- do_co_q(RcsDir, WorkingPtr->fullname);
- }
- }
- else
- {
- if (strncmp(RcsDir, SourceDir, SourceLen) ||
- (RcsDir[SourceLen] != '/')) {
- /* RcsDir is not in SourceDir */
- if (DoDiffs) {
- /* diff the file */
- (void) printf("\t (cd %s; %s %s ${w}/%s >>%s 2>&1)\n",
- RcsDir,
- DiffCommand,
- RcsPtr->keyname,
- WorkingPtr->fullname + WorkingLen,
- OutFile);
- }
- if (! NoRealFiles)
- {
- /* check out the file */
- (void) printf("(cd %s; co -q ${w}/%s) \n",
- RcsDir, WorkingPtr->fullname + WorkingLen);
- }
- } else {
- /* RcsDir is in SourceDir */
- if (DoDiffs) {
- /* diff the file */
- (void) printf("\t (cd ${s}/%s; %s %s ${w}/%s >>%s 2>&1)\n",
- RcsDir + SourceLen,
- DiffCommand,
- RcsPtr->keyname,
- WorkingPtr->fullname + WorkingLen,
- OutFile);
- }
- if (! NoRealFiles)
- {
- /* check out the file */
- (void) printf("(cd ${s}/%s; co -q ${w}/%s) \n",
- RcsDir + SourceLen, WorkingPtr->fullname + WorkingLen);
- }
- }
- }
- } else {
- if (Debug > 1)
- (void) fprintf(stderr,
- ">> source older than working\n");
- }
- }
- }
- }
- /*
- ** PASS 2:
- ** Check all the files in the source (checked out) dir.
- */
- if (Debug)
- (void) fprintf(stderr, ">> Pass 2: scanning SourceDir \"%s\"\n",
- SourceDir);
- for (SourcePtr = SourceHead; SourcePtr; SourcePtr = SourcePtr->next) {
- /* did we get this one already? */
- if (SourcePtr->used)
- continue;
- /* ignore "RCS" */
- if (!strcmp(SourcePtr->keyname, "RCS"))
- continue;
- /* ignore SCCS as well */
- if (!(ProcessSCCSdirs)) {
- if (!strcmp(SourcePtr->keyname, "SCCS")) {
- if (Debug > 1)
- (void) fprintf(stderr, ">> SCCS -- ignored\n");
- continue;
- }
- }
- /* find corresponding RCS file */
- for (RcsPtr = RcsHead; RcsPtr; RcsPtr = RcsPtr->next) {
- if ((SourcePtr->keylen == RcsPtr->keylen) &&
- !strcmp(SourcePtr->keyname, RcsPtr->keyname)) {
- /* mark it as used */
- break;
- }
- }
- /* which one do we use, RCS or source? */
- if (RcsPtr) {
- if (!SourcePriority &&
- (SourcePtr->st.st_mtime < RcsPtr->st.st_mtime)) {
- /* we'll catch this on pass 3 */
- continue;
- } else {
- /* mark the RCS file as used */
- (void) RcsPtr->used++;
- }
- }
- /* ignore .o and .a files */
- c = SourcePtr->keyname + SourcePtr->keylen - 2;
- if (SourcePtr->keylen >= 2) {
- if (!strcmp(c, ".o")) {
- (void) shouldnt_have_source++;
- if (!CloneDotO)
- continue;
- }
- if (!strcmp(c, ".a")) {
- (void) shouldnt_have_source++;
- if (!CloneDotA)
- continue;
- }
- }
- /* the files might be Makefile's */
- if (!CloneMakefile && !strncmp(SourcePtr->keyname, Makefile,
- strlen(Makefile)))
- continue;
- WorkingFile = malloc((unsigned) strlen(WorkingDir) +
- SourcePtr->keylen + 2);
- (void) strcpy(WorkingFile, WorkingDir);
- (void) strcat(WorkingFile, "/");
- (void) strcat(WorkingFile, SourcePtr->keyname);
- if (S_ISDIR(SourcePtr->st.st_mode)) {
- /* check for directories present in the source tree,
- ** but not in this tree. Don't bother if the SourceDir
- ** is the same as WorkingDir. If the directory exists
- ** in the working tree, we already set the used flag
- ** and never got here in the first place.
- */
- if (!same) {
- if (MakeDirs) {
- if (!Quiet)
- (void) fprintf(stderr, "%s: building directory\n",
- WorkingFile + WorkingLen);
- if (!FollowDirLinks &&
- SourcePtr->lst_valid &&
- S_ISLNK(SourcePtr->lst.st_mode))
- {
- /* check to see if file symlinks should resolve */
- if (ResolveFileLinks)
- SourceFile = ResolveLink(SourcePtr->fullname, 0);
- else
- SourceFile = SourcePtr->fullname;
- if (DoExecute)
- do_ln_s(SourceFile, WorkingFile);
- else
- {
- if (strncmp(SourceFile, SourceDir, SourceLen))
- (void) printf("ln -s %s ${w}/%s\n",
- SourceFile,
- WorkingFile + WorkingLen);
- else
- (void) printf("ln -s ${s}/%s ${w}/%s\n",
- SourceFile + SourceLen,
- WorkingFile + WorkingLen);
- }
- free(SourceFile);
- }
- else
- {
- if (DoExecute)
- {
- do_rm_rf(WorkingFile);
- do_mkdir(WorkingFile);
- do_chmod(WorkingFile, 0755);
- /* bad for other architectures */
- /* do_chgrp(WorkingFile, "users"); */
- }
- else
- {
- (void) printf("rm -rf ${w}/%s\n",
- WorkingFile + WorkingLen);
- (void) printf("\tmkdir ${w}/%s\n",
- WorkingFile + WorkingLen);
- (void) printf("\tchmod 0755 ${w}/%s\n",
- WorkingFile + WorkingLen);
- /* bad for other architectures */
- /*(void) printf("\tchgrp users ${w}/%s\n",
- WorkingFile + WorkingLen); */
- }
- (void) GetNew(WorkingFile, SourcePtr->fullname, same);
- }
-
- } else {
- if (!Quiet)
- (void) fprintf(stderr, "%s: missing directory\n",
- WorkingFile + WorkingLen);
- }
- }
- } else {
- /* regular file (probably)... */
- /* check to see if file symlinks should resolve */
- if (ResolveFileLinks)
- if (SourcePtr->lst_valid && S_ISLNK(SourcePtr->lst.st_mode)) {
- SourceFile = ResolveLink(SourcePtr->fullname, 0);
- FreeSourceFile = 1;
- }
- else {
- SourceFile = SourcePtr->fullname;
- FreeSourceFile = 0;
- }
- else {
- SourceFile = SourcePtr->fullname;
- FreeSourceFile = 0;
- }
- if (!Quiet)
- (void) fprintf(stderr, "%s: new file\n",
- WorkingFile + WorkingLen);
- if (DoExecute)
- {
- if (LinkFiles)
- do_ln_s(SourceFile, WorkingFile);
- else
- do_cp(SourceFile, WorkingFile);
- }
- else
- {
- if (strncmp(SourceFile, SourceDir, SourceLen)) {
- (void) printf("%s %s ${w}/%s\n",
- LinkFiles ? "ln -s" : "cp",
- SourceFile,
- WorkingFile + WorkingLen);
- } else {
- (void) printf("%s ${s}/%s ${w}/%s\n",
- LinkFiles ? "ln -s" : "cp",
- SourceFile + SourceLen,
- WorkingFile + WorkingLen);
- }
- }
- if (!LinkFiles)
- {
- if (DoExecute)
- do_chmod(WorkingFile,
- (SourcePtr->st.st_mode & 07777 & ~0222) | 0444);
- else
- (void) printf("\tchmod 0%03o ${w}/%s\n",
- (SourcePtr->st.st_mode & 07777 & ~0222) | 0444,
- WorkingFile + WorkingLen);
- }
- if (FreeSourceFile)
- (void) free(SourceFile);
- }
- (void) free(WorkingFile);
- }
- /*
- ** PASS 3:
- **
- ** Check all the files in the RCS dir.
- */
- if (Debug)
- (void) fprintf(stderr, ">> scanning RcsDir \"%s\"\n", RcsDir);
- for (RcsPtr = RcsHead; RcsPtr; RcsPtr = RcsPtr->next) {
- /* did we get this one already? */
- if (RcsPtr->used)
- continue;
- /* build the WorkingFile */
- WorkingFile = malloc((unsigned) strlen(WorkingDir) +
- RcsPtr->keylen + 2);
- (void) strcpy(WorkingFile, WorkingDir);
- (void) strcat(WorkingFile, "/");
- (void) strcat(WorkingFile, RcsPtr->keyname);
- /* New RCS file */
- if (!Quiet)
- (void) fprintf(stderr, "%s: new RCS file\n",
- WorkingFile + WorkingLen);
- if (DoExecute)
- {
- if (! NoRealFiles)
- {
- do_co_q(RcsDir, WorkingFile);
- }
- }
- else
- {
- if (strncmp(RcsDir, SourceDir, SourceLen) ||
- (RcsDir[SourceLen] != '/')) {
- /* RcsDir is not in SourceDir */
- if (! NoRealFiles)
- {
- /* check it out... */
- (void) printf("(cd %s; co -q ${w}/%s)\n",
- RcsDir,
- WorkingFile + WorkingLen);
- }
- } else {
- /* RcsDir is in SourceDir */
- if (! NoRealFiles)
- {
- /* check it out... */
- (void) printf("(cd %s; co -q ${w}/%s)\n",
- RcsDir + SourceLen,
- WorkingFile + WorkingLen);
- }
- }
- }
- (void) free(WorkingFile);
- }
- /* free storage */
- while (WorkingHead) {
- WorkingPtr = WorkingHead;
- WorkingHead = WorkingPtr->next;
- (void) free(WorkingPtr->fullname);
- (void) free(WorkingPtr->keyname);
- (void) free((char *) WorkingPtr);
- }
- while (SourceHead) {
- SourcePtr = SourceHead;
- SourceHead = SourcePtr->next;
- (void) free(SourcePtr->fullname);
- (void) free(SourcePtr->keyname);
- (void) free((char *) SourcePtr);
- }
- while (RcsHead) {
- RcsPtr = RcsHead;
- RcsHead = RcsPtr->next;
- (void) free(RcsPtr->fullname);
- (void) free(RcsPtr->keyname);
- (void) free((char *) RcsPtr);
- }
- (void) free(RcsDir);
- return;
- }
- char
- *ResolveLink(filename, freeit)
- char *filename;
- int freeit;
- {
- int len;
- int try;
- char *c;
- char *tname;
- tname = filename;
- if (Debug) {
- (void) fprintf(stderr, "ResolveLink %s->", tname);
- (void) fflush(stderr);
- }
- for (try = 0; try < 10; try++) {
- if ((len = readlink(tname, Buffer, sizeof(Buffer))) < 0) {
- break;
- } else {
- Buffer[len] = '\0';
- if ('/' != *Buffer) {
- if (c = strrchr(tname, '/')) {
- *c = '\0';
- c = malloc((unsigned) (strlen(tname) +
- strlen(Buffer) + 2));
- (void) sprintf(c, "%s/%s", tname, Buffer);
- } else {
- c = malloc((unsigned) (strlen(Buffer) + 1));
- (void) strcpy(c, Buffer);
- }
- } else {
- c = malloc((unsigned) (strlen(Buffer) + 1));
- (void) strcpy(c, Buffer);
- }
- if (freeit++)
- (void) free(tname);
- tname = c;
- }
- }
- if (!freeit) {
- c = malloc((unsigned) (strlen(tname) + 1));
- (void) strcpy(c, tname);
- tname = c;
- }
- if (Debug) {
- (void) fprintf(stderr, "%s\n", tname);
- (void) fflush(stderr);
- }
- return(tname);
- }
- /* New code for -X option */
- static void do_rm_rf(target)
- char *target;
- {
- char *malloc(), *temp;
- struct stat buf;
- if (lstat(target, &buf) != -1)
- {
- if (S_ISDIR(buf.st_mode))
- {
- DIR *thisdir;
- #ifdef apollo
- struct direct *thisent;
- #else
- struct dirent *thisent;
- #endif
- thisdir = opendir(target);
- if (thisdir != NULL)
- {
- while (thisent = readdir(thisdir))
- {
- if (strcmp(thisent->d_name, ".") &&
- strcmp(thisent->d_name, ".."))
- {
- temp = malloc(strlen(target) +
- strlen(thisent->d_name) + 2);
- if (temp != NULL)
- {
- (void)strcpy(temp, target);
- (void)strcat(temp, "/");
- (void)strcat(temp, thisent->d_name);
- do_rm_rf(temp);
- free(temp);
- }
- }
- }
- closedir(thisdir);
- (void)rmdir(target);
- }
- }
- else
- (void)unlink(target);
- }
- }
- static void do_touch(filename)
- char *filename;
- {
- #ifdef apollo
- struct timeval tvp[2];
- struct timezone tzp;
- gettimeofday(tvp, &tzp);
- tvp[1] = tvp[0];
- if (utimes(filename, tvp) == -1 &&
- errno == ENOENT)
- #else
- if (utime(filename, (struct utimbuf *)NULL) == -1 &&
- errno == ENOENT)
- #endif
- (void)creat(filename, 0777);
- }
- static void do_ln_s(src, dest)
- char *src, *dest;
- {
- if (symlink(src, dest) == -1)
- perror(dest);
- }
- static void do_diff(dirname, diffcmd, file1, file2, outfile)
- char *dirname, *diffcmd, *file1, *file2, *outfile;
- {
- pid_t pid, res, fork();
- pid = fork();
- if (pid == -1)
- perror("fork() failed");
- else
- {
- if (pid == 0)
- {
- if (dirname != NULL && chdir(dirname) == -1)
- perror("dirname");
- else
- {
- int des;
- des = open(outfile, O_WRONLY | O_APPEND | O_CREAT, 0777);
- if (des == -1)
- {
- perror(outfile);
- exit(1);
- }
- (void)dup2(des, fileno(stdout));
- (void)dup2(des, fileno(stderr));
- execlp(diffcmd, diffcmd, file1, file2, NULL);
- perror(diffcmd);
- }
- exit(1);
- }
- while ((res = wait(NULL)) != pid && res != -1);
- }
- }
- static void do_rm_f(target)
- char *target;
- {
- struct stat buf;
- if (lstat(target, &buf) != -1 &&
- !(S_ISDIR(buf.st_mode)))
- (void)unlink(target);
- }
- static void do_cp(src, dest)
- char *src, *dest;
- {
- int res1, res2, fd1, fd2;
- char buf[BUFSIZ];
- fd1 = open(src, O_RDONLY);
- if (fd1 == -1)
- {
- perror(src);
- return;
- }
- fd2 = open(dest, O_WRONLY | O_CREAT, 0777);
- if (fd2 == -1)
- {
- perror(dest);
- close(fd1);
- return;
- }
- while ((res1 = read(fd1, buf, BUFSIZ)) > 0)
- {
- while ((res2 = write(fd2, buf, res1)) > 0 && (res1 -= res2));
- if (res2 == -1) break;
- }
- if (res1 == -1)
- perror(src);
- else if (res2 == -1)
- perror(dest);
- close(fd1);
- close(fd2);
- }
- static void do_chmod(filename, newmode)
- char *filename;
- int newmode;
- {
- if (chmod(filename, newmode) == -1)
- perror(filename);
- }
- static void do_co_q(dirname, targetname)
- char *dirname, *targetname;
- {
- pid_t pid, res, fork();
- pid = fork();
- if (pid == -1)
- perror("fork() failed");
- else
- {
- if (pid == 0)
- {
- if (chdir(dirname) == -1)
- perror("dirname");
- else
- {
- execlp("co", "co", "-q", targetname, NULL);
- perror("failed to exec co(1)");
- }
- exit(1);
- }
- while ((res = wait(NULL)) != pid && res != -1);
- }
- }
- static void do_mkdir(dirname)
- char *dirname;
- {
- if (mkdir(dirname, 0777) == -1)
- perror(dirname);
- }
- static void do_chgrp(filename, newgroup)
- char *filename, *newgroup;
- {
- struct group *group, *getgrnam();
- group = getgrnam(newgroup);
- if (group == NULL)
- fprintf(stderr, "%s: no such group\n", newgroup);
- else
- chown(filename, UID_NO_CHANGE, group->gr_gid);
- }
|