home *** CD-ROM | disk | FTP | other *** search
- static char RcsId[] = "$Header: /wrld/6e50/cecil/tools/RCS/lktree.c,v 1.2 89/08/04 10:40:32 cecil Exp Locker: cecil $";
- /*
- $Log: lktree.c,v $
- * Revision 1.2 89/08/04 10:40:32 cecil
- * adding lktree to RCS control.
- *
- * Revision 1.1 89/08/04 08:50:07 cecil
- * Initial revision
- *
- */
-
- #include <stdio.h>
- #include <ftw.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <string.h>
-
- FILE *fp;
-
- int debug = 0; /* TRUE to debug */
- #define DEBUG(x) {if(debug)fprintf(stderr, "%s:%d:%s\n", __FILE__,__LINE__,x);}
-
- int dir_ignore = 0; /* option -d == ignore directories */
- int link_ignore = 0; /* option -l == ignore links */
-
- char *head; /* the requested root head */
- char head_buf[512]; /* work buffer for environmental variable */
-
- FILE *out_fp; /* temp file for fgrep's */
- char *temp_fn; /* return from mktemp() */
-
- FILE *incl_fp = 0, *excl_fp = 0; /* include and exclude file ptrs */
- char *incl_fn, *excl_fn; /* include and exclude file names */
-
- char *rcs_root_fn; /* name of root directory to start link */
-
- /* strdup - duplicate a string */
- char *strdup(s)
- char *s;
- {
- char *cp;
-
- cp = (char *)malloc(strlen(s)+1);
- strcpy(cp, s);
- return cp;
- }
-
- /*==================================================================*/
- /* strsearch - search string for sub_string, return ptr to start of */
- /* sub_string within string, NULL if not within. */
- /*==================================================================*/
-
- char *strsearch(string, sub_string)
- char *string, *sub_string;
- {
- for(;string = (char *)index(string, *sub_string);++string){
- /* found first char of substring in string */
- if(strcmp(string, sub_string) == 0)
- return string;
- }
- /* substring is not within string, return NULL */
- return (char *)0;
- }
-
- int print_file(fn, sbuf, ftype)
- char *fn; /* name of file */
- struct stat *sbuf;
- int ftype;
- {
- register char *name;
- char buf[BUFSIZ];
- char *temp;
- int status;
-
- DEBUG(fn);
- /* If this file is a symbolic link, then absolutely */
- /* ignore this reference! */
- /* This call succeeds only if fn IS a link. */
- if((status = readlink(fn, buf, BUFSIZ)) != -1){
- DEBUG("ignoring symbolic link file");
- return 0;
- }
-
- /* Never descend into RCS directories, as the intent */
- /* is to link an RCS directory instead ths individual*/
- /* files in the directory. */
- if(re_exec(fn) != 0) {
- DEBUG("NOT descending into RCS dir");
- return 0;
- }
-
- /* must run lstat on the file */
- lstat(fn, sbuf);
-
- if ((sbuf->st_mode & S_IFMT) == S_IFBLK)
- return 0;
- if ((sbuf->st_mode & S_IFMT) == S_IFSOCK)
- return 0;
- if ((sbuf->st_mode & S_IFMT) == S_IFIFO)
- return 0;
- if ((sbuf->st_mode & S_IFMT) == S_IFCHR)
- return 0;
- if ((sbuf->st_mode & S_IFMT) == S_IFDIR) {
- struct stat xbuf;
-
- if (dir_ignore)
- return 0;
-
- stat(fn, &xbuf);
- /* if this is a link to a directory, ignore */
- if ((xbuf.st_mode & S_IFMT) == S_IFLNK) {
- return 0;
- }
- }
- if ((sbuf->st_mode & S_IFMT) == S_IFLNK) {
- if (link_ignore)
- return 0;
- }
-
- if ((sbuf->st_mode & S_IFMT) == S_IFDIR)
- name = fn + strlen(head);
- else
- name = fn + strlen(head) + 1;
-
- if(strlen(name) == 0)
- return 0; /* original dir call, ignore */
-
- switch (ftype) {
- default:
- fprintf(out_fp, "echo Unknown");
- fprintf(out_fp, "\t%s", fn);
- fprintf(out_fp, "\t%s", name);
- fprintf(out_fp, "\n");
- break;
- case FTW_F:
- if ((sbuf->st_mode & S_IFMT) == S_IFLNK) {
- fprintf(out_fp, "ln -s");
- fprintf(out_fp, "\t%s", fn);
- fprintf(out_fp, "\t%s", name);
- fprintf(out_fp, "\n");
- } else {
- fprintf(out_fp, "ln -s ");
- fprintf(out_fp, "\t%s", fn);
- fprintf(out_fp, "\t%s", name);
- fprintf(out_fp, "\n");
- }
- if(debug)fprintf(stderr, "ln -s\t%s\t%s\n", fn, name);
- break;
- case FTW_D:
- /* RCS is always a link to the real base system */
- /* have to look at the LAST 4 char of name for RCS directory */
- /* The RCS directory will be linked rather than mkdir'ed */
- temp = name + strlen(name) - 4;
- if(strcmp(temp, "/RCS") == 0){
- /* if this link already exists, do NOT do it again, */
- /* an other link will lead to a loop in the master */
- /* tree. */
- char lbuf[BUFSIZ];
- if((status = readlink(name+1, lbuf, BUFSIZ)) >= 0)
- return 0;
-
- sprintf(buf, "ln -s %s %s", fn, name + 1);
- if(debug)
- fprintf(stderr, "%s\n", buf);
-
- if ((sbuf->st_mode & S_IFMT) == S_IFDIR) {
- struct stat xbuf;
-
- stat(fn, &xbuf);
- /* if this is a link to a directory, ignore */
- if ((xbuf.st_mode & S_IFMT) == S_IFLNK) {
- fprintf("%d:link to existing directory ignored:%s\n",
- __FILE__, buf);
- return 0;
- }
- }
- }
- else{
- char xbuf[512];
- strcpy(xbuf, name+1);
- sprintf(buf, "mkdir %s", xbuf);
- if(debug)fprintf(stderr, "%s\n", xbuf);
- }
-
- #define FOR_REAL 1
- #if FOR_REAL
- /* NEVER create a loop by linking with a file containing RCS/RCS */
- if(strsearch(buf, "RCS/RCS") == 0)
- system(buf);
- #else
- fprintf(out_fp, "%s\n", buf);
- #endif
- break;
- case FTW_NS:
- fprintf(stderr, "stat_failed");
- fprintf(stderr, "\t%s", fn);
- fprintf(stderr, "\t%s", name);
- fprintf(stderr, "\n");
- break;
- }
- return 0;
- }
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- int save_argc;
- int status;
- char *prog_name;
- char *s;
- char buf[BUFSIZ];
- char sys_cmd[BUFSIZ];
- char *rcs_base_fn;
-
- /* parse the necessary options */
- save_argc = argc;
- prog_name = *argv;
- while (--argc > 0 && (*++argv)[0] == '-') {
- for (s = argv[0] + 1; *s != '\0'; s++) {
- switch (*s) {
- default:
- case '?':
- fprintf(stderr, "usage: %s base_dir\n", prog_name);
- fprintf(stderr, "\t-Ifile = use \"file\" as an include in fgrep\n");
- fprintf(stderr, "\t-Xfile = use \"file\" as an exlcude in fgrep\n");
- exit(1);
- case 'd':
- debug = 1;
- break;
- case 'I':
- incl_fn = ++s;
- while (*++s); /* to end of string */
- --s; /* but not too far */
- break;
- case 'X':
- excl_fn = ++s;
- while (*++s); /* to end of string */
- --s; /* but not too far */
- break;
- }
- }
- }
-
- /* compile regular expression to prevent descent into */
- /* an RCS linked subdirectory. */
- if(head = (char *)re_comp("\/RCS\/")){
- printf(head);
- exit(1);
- }
-
- temp_fn = (char *) mktemp("TTXXXXXX");
- out_fp = fopen(temp_fn, "w");
-
- /* this may or may not exist */
- if(argc == 0) {
- head = rcs_root_fn = (char *)getenv("ROOT_TREE");
- }
- else
- head = *argv; /* get the head */
-
-
- {
- int i;
-
- /* move the environmental varialbe to a work area */
- for(i = 0; i < sizeof(head_buf); head_buf[i++] = '\0');
- strcpy(head_buf, head);
- head = head_buf;
- }
-
- /* prove existence/readability of RCS root file */
- if ((fp = fopen(rcs_root_fn, "r")) == (FILE *) 0) {
- fprintf(stderr, "Cannot open $ROOT_TREE %s\n", rcs_base_fn);
- exit(1);
- }
- fclose(fp);
-
- /* open the exclusion file, if none check under the ROOT_TREE dir */
- if ((excl_fp = fopen(excl_fn, "r")) == (FILE *) 0) {
- sprintf(excl_fn = sys_cmd, "%s/excl_file", rcs_root_fn);
- excl_fn = strdup(sys_cmd); /* save this string */
- if ((excl_fp = fopen(sys_cmd, "r")) == (FILE *) 0) {
- fprintf(stderr, "Cannot read file exclusion list: %s\n",
- excl_fn);
- exit(1);
- }
- }
-
- /* open the inclusion file, if none check under the ROOT_TREE dir */
- if ((incl_fp = fopen(incl_fn, "r")) == (FILE *) 0) {
- sprintf(sys_cmd, "%s/incl_file", rcs_root_fn);
- incl_fn = strdup(sys_cmd); /* save this string */
- if ((incl_fp = fopen(sys_cmd, "r")) == (FILE *) 0) {
- fprintf(stderr, "Cannot read file inclusion list: %s\n",
- incl_fn);
- exit(1);
- }
- }
-
- ftw(rcs_root_fn, print_file, 20);
-
- rewind(out_fp);
- sprintf(sys_cmd, "cat %s", temp_fn);
- if (incl_fp) {
- sprintf(buf, "| fgrep -f %s ", incl_fn);
- strcat(sys_cmd, buf);
- }
- if (excl_fp) {
- sprintf(buf, "| fgrep -v -f %s ", excl_fn);
- strcat(sys_cmd, buf);
- }
- strcat(sys_cmd, " | /bin/csh ");
- /* Do not remove temp file if debugging */
- if(!debug) {
- strcat(sys_cmd, "; rm ");
- strcat(sys_cmd, temp_fn);
- }
- printf("%s\n", sys_cmd);
- exit(system(sys_cmd));
- }
-