int diff (int argc, char **argv) { char tmp[50]; int c, err = 0; int local = 0; int which; int option_index; is_rcs = (strcmp (command_name, "rcsfile") == 0); if (argc == -1) usage (diff_usage); have_rev1_label = have_rev2_label = 0; /* * Note that we catch all the valid arguments here, so that we can * intercept the -r arguments for doing revision diffs; and -l/-R for a * non-recursive/recursive diff. */ /* Clean out our global variables (multiroot can call us multiple times and the server can too, if the client sends several diff commands). */ if (opts == NULL) { opts_allocated = 1; opts = (char*)xmalloc (opts_allocated); } opts[0] = '\0'; diff_rev1 = NULL; diff_rev2 = NULL; diff_date1 = NULL; diff_date2 = NULL; optind = 0; while ((c = getopt_long (argc, argv, "+abcdefhilnpstuwy0123456789BHNRTC:D:F:I:L:U:V:W:k:r:", longopts, &option_index)) != -1) { switch (c) { case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'h': case 'i': case 'n': case 'p': case 's': case 't': case 'u': case 'w': case 'y': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case 'B': case 'H': case 'T': (void) sprintf (tmp, " -%c", (char) c); allocate_and_strcat (&opts, &opts_allocated, tmp); break; case 'L': if (have_rev1_label++) if (have_rev2_label++) { error (0, 0, "extra -L arguments ignored"); break; } allocate_and_strcat (&opts, &opts_allocated, " -L"); allocate_and_strcat (&opts, &opts_allocated, optarg); break; case 'C': case 'F': case 'I': case 'U': case 'V': case 'W': (void) sprintf (tmp, " -%c", (char) c); allocate_and_strcat (&opts, &opts_allocated, tmp); allocate_and_strcat (&opts, &opts_allocated, optarg); break; case 131: /* --ifdef. */ allocate_and_strcat (&opts, &opts_allocated, " --ifdef="); allocate_and_strcat (&opts, &opts_allocated, optarg); break; case 129: case 130: case 132: case 133: case 134: case 135: case 136: case 137: case 138: case 139: case 140: case 141: case 142: case 143: case 144: case 145: case 146: allocate_and_strcat (&opts, &opts_allocated, " --"); allocate_and_strcat (&opts, &opts_allocated, longopts[option_index].name); if (longopts[option_index].has_arg == 1 || (longopts[option_index].has_arg == 2 && optarg != NULL)) { allocate_and_strcat (&opts, &opts_allocated, "="); allocate_and_strcat (&opts, &opts_allocated, optarg); } break; case 'R': local = 0; break; case 'l': local = 1; break; case 'k': if (options) xfree (options); options = RCS_check_kflag (optarg,true,true); break; case 'r': if (diff_rev2 != NULL || diff_date2 != NULL) error (1, 0, "no more than two revisions/dates can be specified"); if (diff_rev1 != NULL || diff_date1 != NULL) diff_rev2 = optarg; else diff_rev1 = optarg; break; case 'D': if (diff_rev2 != NULL || diff_date2 != NULL) error (1, 0, "no more than two revisions/dates can be specified"); if (diff_rev1 != NULL || diff_date1 != NULL) diff_date2 = Make_Date (optarg); else diff_date1 = Make_Date (optarg); break; case 'N': empty_files = 1; break; case '?': default: usage (diff_usage); break; } } argc -= optind; argv += optind; /* make sure options is non-null */ if (!options) options = xstrdup (""); if (!is_rcs && current_parsed_root->isremote) { if (local) send_arg("-l"); if (empty_files) send_arg("-N"); send_option_string (opts); if (options[0] != '\0') option_with_arg ("-k", options); if (diff_rev1) option_with_arg ("-r", diff_rev1); if (diff_date1) client_senddate (diff_date1); if (diff_rev2) option_with_arg ("-r", diff_rev2); if (diff_date2) client_senddate (diff_date2); send_arg("--"); /* Send the current files unless diffing two revs from the archive */ if (diff_rev2 == NULL && diff_date2 == NULL) send_files (argc, argv, local, 0, 0); else send_files (argc, argv, local, 0, SEND_NO_CONTENTS); send_file_names (argc, argv, SEND_EXPAND_WILD); send_to_server ("diff\n", 0); err = get_responses_and_close (); xfree (options); options = NULL; return (err); } if(is_rcs) { int n; if(!argc) usage(diff_usage); for(n=0; n<argc; n++) { struct file_info finfo = {0}; const char *name; char *tmp = find_rcs_filename(argv[n]); if(!tmp) error(1,ENOENT,"%s",argv[n]); finfo.fullname=fullpathname(tmp, &name); finfo.file = xstrdup(name); char *ff = xstrdup(finfo.fullname); finfo.update_dir = ff; ff[(name-finfo.fullname)-1]='\0'; finfo.rcs = RCS_fopen(finfo.fullname); if(finfo.rcs) { ff = (char*)finfo.fullname; ff[strlen(finfo.fullname)-2]='\0'; ff = (char*)finfo.file; ff[strlen(finfo.file)-2]='\0'; err+=diff_fileproc(NULL,&finfo); freercsnode(&finfo.rcs); } else { error(1,ENOENT,"%s",tmp); err++; } xfree(finfo.fullname); xfree(finfo.file); xfree(finfo.update_dir); xfree(tmp); } } else { if (diff_rev1 != NULL) tag_check_valid (diff_rev1, argc, argv, local, 0, ""); if (diff_rev2 != NULL) tag_check_valid (diff_rev2, argc, argv, local, 0, ""); which = W_LOCAL; if (diff_rev1 != NULL || diff_date1 != NULL) which |= W_REPOS; /* start the recursion processor */ err = start_recursion (diff_fileproc, diff_filesdoneproc, (PREDIRENTPROC) NULL, diff_dirproc, diff_dirleaveproc, NULL, argc, argv, local, which, 0, 1, (char *) NULL, NULL, 1, verify_read, diff_rev1); } /* clean up */ xfree (options); options = NULL; if (diff_date1 != NULL) xfree (diff_date1); if (diff_date2 != NULL) xfree (diff_date2); return (err); }
static int ls_proc (int argc, char **argv, char *xwhere, char *mwhere, char *mfile, int shorten, int local, char *mname, char *msg) { char *repository; int err = 0; int which; char *where; int i; if (is_rls) { char *myargv[2]; if (!quiet) error (0, 0, "Listing module: `%s'", strcmp (mname, "") ? mname : "."); repository = xmalloc (strlen (current_parsed_root->directory) + strlen (argv[0]) + (mfile == NULL ? 0 : strlen (mfile) + 1) + 2); (void)sprintf (repository, "%s/%s", current_parsed_root->directory, argv[0]); where = xmalloc (strlen (argv[0]) + (mfile == NULL ? 0 : strlen (mfile) + 1) + 1); (void)strcpy (where, argv[0]); /* If mfile isn't null, we need to set up to do only part of the * module. */ if (mfile != NULL) { char *cp; char *path; /* If the portion of the module is a path, put the dir part on * repos. */ if ((cp = strrchr (mfile, '/')) != NULL) { *cp = '\0'; (void)strcat (repository, "/"); (void)strcat (repository, mfile); (void)strcat (where, "/"); (void)strcat (where, mfile); mfile = cp + 1; } /* take care of the rest */ path = Xasprintf ("%s/%s", repository, mfile); if (isdir (path)) { /* directory means repository gets the dir tacked on */ (void)strcpy (repository, path); (void)strcat (where, "/"); (void)strcat (where, mfile); } else { myargv[1] = mfile; argc = 2; argv = myargv; } free (path); } /* cd to the starting repository */ if (CVS_CHDIR (repository) < 0) { error (0, errno, "cannot chdir to %s", repository); free (repository); free (where); return 1; } which = W_REPOS; } else /* !is_rls */ { repository = NULL; where = NULL; which = W_LOCAL | W_REPOS; } if (show_tag || show_date || show_dead_revs) which |= W_ATTIC; if (show_tag != NULL && !tag_validated) { tag_check_valid (show_tag, argc - 1, argv + 1, local, 0, repository, false); tag_validated = true; } /* Loop on argc so that we are guaranteed that any directory passed to * ls_direntproc should be processed if its parent is not yet in DIRS. */ if (argc == 1) { List *dirs = getlist (); err = start_recursion (ls_fileproc, NULL, ls_direntproc, ls_dirleaveproc, dirs, 0, NULL, local, which, 0, CVS_LOCK_READ, where, 1, repository); walklist (dirs, ls_print_dir, NULL); dellist (&dirs); } else { for (i = 1; i < argc; i++) { List *dirs = getlist (); err = start_recursion (ls_fileproc, NULL, ls_direntproc, NULL, dirs, 1, argv + i, local, which, 0, CVS_LOCK_READ, where, 1, repository); walklist (dirs, ls_print_dir, NULL); dellist (&dirs); } } if (!(which & W_LOCAL)) free (repository); if (where) free (where); return err; }