Пример #1
0
int passwd (int argc, char **argv)
{
    int    c;
    int    err = 0;
    char   *typed_password = NULL, *typed_password2 = NULL;
    const char   *username, *user;
	passwd_entry *passnode;
    char   *linebuf = NULL;
	char *real_user = NULL;
	char *password_domain = NULL;
	int adduser=0,deluser=0,disableuser=0,realuser=0,remove_realuser=0,use_domain=0;
	int arg_specified = 0;

    if (argc == -1)
	usage (passwd_usage);

    optind = 0;
    while ((c = getopt (argc, argv, "axXr:RD:")) != -1)
    {
	switch (c)
	{
	case 'a':
		if(arg_specified)
			usage (passwd_usage);
		arg_specified = 1;
	    adduser = 1;
	    break;
	case 'x':
		if(arg_specified)
			usage (passwd_usage);
		arg_specified = 1;
		disableuser = 1;
		break;
	case 'X':
		if(arg_specified)
			usage (passwd_usage);
		arg_specified = 1;
		deluser = 1;
		break;
	case 'r':
		realuser = 1;
		real_user = xstrdup(optarg);
		break;
	case 'R':
		remove_realuser = 1;
		break;
	case 'D':
		use_domain = 1;
		password_domain = xstrdup(optarg);
		break;
	case '?':
	default:
	    usage (passwd_usage);
	    break;
	}
    }
    argc -= optind;
    argv += optind;

	if(!argc)
		user = NULL;
	else
		user=argv[0];

#ifdef CLIENT_SUPPORT
    if (current_parsed_root->isremote)
    {
	if (argc > 1)
	    usage (passwd_usage);

	if (!supported_request ("passwd"))
	    error (1, 0, "server does not support passwd");

	if(!user && adduser)
	{
		error(1,0,"You cannot add yourself");
	}
	if(!user && deluser)
	{
		error(1,0,"You cannot delete yourself");
	}

	if(user || current_parsed_root->username || current_parsed_root->hostname)
	{
		printf ("%s %s@%s\n",
			(adduser) ? "Adding user" : (deluser) ? "Deleting user" : "Changing repository password for",
			user?user:current_parsed_root->username?current_parsed_root->username:getcaller(),current_parsed_root->hostname);
	}
	else
	{
		printf ("Changing repository password for %s\n",getcaller());
	}
	fflush (stdout);

	if(!use_domain && !deluser && !disableuser)
	{
		typed_password = getpass ("New password: "******"Verify password: "******"Passwords do not match, try again");
		}
		memset (typed_password2, 0, strlen (typed_password2));
		typed_password = xrealloc(typed_password, strlen(typed_password) +32);
		if(strlen(typed_password))
			crypt_password(typed_password);
	}

	if (adduser)
	    send_arg ("-a");
	if (disableuser)
		send_arg ("-x");
	if (deluser)
		send_arg ("-X");
	if (realuser)
	{
		send_arg ("-r");
	 	send_arg (real_user);
	}
	if (remove_realuser)
		send_arg ("-R");
	if(use_domain)
	{
		send_arg ("-D");
		send_arg (password_domain);
	}

	if (argc == 1)
	    send_arg(user);
	else
		send_arg("*");

	if(typed_password)
	{
		send_arg (typed_password); /* Send the new password */
		memset (typed_password, 0, strlen (typed_password));
		xfree (typed_password);
	}

	send_to_server ("passwd\012", 0);
	return get_responses_and_close ();
    }
	if(!server_active)
#endif
	{
		if(argc!=0 && argc!=1)
			usage (passwd_usage);

		if(!user && adduser)
		{
			error(1,0,"You cannot add yourself");
		}
		if(!user && deluser)
		{
			error(1,0,"You cannot delete yourself");
		}

		if(user || current_parsed_root->username)
		{
			printf ("%s %s\n",
				(adduser) ? "Adding user" : (deluser) ? "Deleting user" : "Changing password for",
				user?user:current_parsed_root->username);
		}
		else
		{
			printf ("Changing repository password for %s\n",getcaller());
		}
		fflush (stdout);

  		if (argc == 0)
			username = CVS_Username;
		else
		{
			username = user;
		}

		if(!use_domain && !deluser && !disableuser)
		{
			typed_password = getpass ("New password: "******"Verify password: "******"Passwords do not match, try again");
			}
			memset (typed_password2, 0, strlen (typed_password2));
			typed_password = xrealloc(typed_password, strlen(typed_password) +32);
			if(strlen(typed_password))
				crypt_password(typed_password);
		}
	} 
#ifdef SERVER_SUPPORT
	if(server_active)
	{
		if ((argc != 1) && (argc != 2))
			usage (passwd_usage);

		if(!strcmp(user,"*"))
			username = CVS_Username;
		else
		{
			username = user;
#if defined(_WIN32)
#ifdef SJIS
			if(_mbschr(username,'\\') && !isDomainMember())
#else
			if(strchr(username,'\\') && !isDomainMember())
#endif
			{
				error(1,0,"CVS server is not acting as a domain member - cannot specify domains");
			}
#endif
		}

		if(argc==2)
			typed_password = argv[1];
	}
#endif

    if (typed_password && 
	(strcmp(username, CVS_Username) != 0) && 
	(! verify_admin ()))
		error (1, 0, "Only administrators can add or change another's password");

	read_passwd_list();
	passnode = find_passwd_entry(username);
	if (passnode == NULL)
	{
	    if (!adduser)
			error (1, 0, "Could not find %s in password file", username);

	    if (! verify_admin())
		{
			error (1, 0, "Only administrators can add users" );
	    }

		passnode = new_passwd_entry();
		passnode->username=xstrdup(username);
		passnode->password=xstrdup(typed_password);
		passnode->real_username=NULL;
	}

	if(deluser)
	{
	    if (! verify_admin())
		{
			error (1, 0, "Only administrators can delete users" );
	    }
		xfree(passnode->username);
		passnode->username = NULL;
	}
	else if(disableuser)
	{
	    if (! verify_admin())
		{
			error (1, 0, "Only administrators can disable users" );
	    }
		xfree(passnode->password);
		passnode->password=xstrdup("#DISABLED#");
	}
	else
	{
		xfree(passnode->password);
#ifdef _WIN32 /* Unix servers can't make any sense of this */
		if(use_domain)
		{
			passnode->password = xmalloc(strlen(password_domain)+2);
			strcpy(passnode->password,"!");
			strcat(passnode->password,password_domain);
		}
		else
#endif
			passnode->password = xstrdup(typed_password);

		if(realuser)
		{
			if(!getpwnam(real_user))
				error(1, 0, "User '%s' is not a real user on the system.",real_user);

			xfree(passnode->real_username);
			passnode->real_username = xstrdup(real_user);
		}
		else if (remove_realuser)
		{
			xfree(passnode->real_username);
			passnode->real_username=NULL;
		}

		if((passnode->real_username && !getpwnam(passnode->real_username)) || (!passnode->real_username && passnode->username && !getpwnam(passnode->username)))
		{
			error(0,0,"*WARNING* CVS user '%s' will not be able to log in until they are aliased to a valid system user.",username);
		}
	}

	write_passwd_list();
	free_passwd_list();
	xfree(real_user);
	xfree(password_domain);

    return (err);
}
Пример #2
0
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);
}
Пример #3
0
int
history (int argc, char **argv)
{
    int i, c;
    const char *fname = NULL;
    List *flist;

    if (argc == -1)
	usage (history_usg);

    since_rev = xstrdup ("");
    since_tag = xstrdup ("");
    backto = xstrdup ("");
    rec_types = xstrdup ("");
    getoptreset ();
    while ((c = getopt (argc, argv, "+Tacelow?D:b:f:m:n:p:r:t:u:x:X:z:")) != -1)
    {
	switch (c)
	{
	    case 'T':			/* Tag list */
		report_count++;
		tag_report++;
		break;
	    case 'a':			/* For all usernames */
		all_users++;
		break;
	    case 'c':
		report_count++;
		modified = 1;
		break;
	    case 'e':
		report_count++;
		extract_all++;
		free (rec_types);
		rec_types = xstrdup (ALL_HISTORY_REC_TYPES);
		break;
	    case 'l':			/* Find Last file record */
		last_entry = 1;
		break;
	    case 'o':
		report_count++;
		v_checkout = 1;
		break;
	    case 'w':			/* Match Working Dir (CurDir) fields */
		working = 1;
		break;
	    case 'X':			/* Undocumented debugging flag */
#ifdef DEBUG
		fname = optarg;
#endif
		break;

	    case 'D':			/* Since specified date */
		if (*since_rev || *since_tag || *backto)
		{
		    error (0, 0, "date overriding rev/tag/backto");
		    *since_rev = *since_tag = *backto = '\0';
		}
		since_date = Make_Date (optarg);
		break;
	    case 'b':			/* Since specified file/Repos */
		if (since_date || *since_rev || *since_tag)
		{
		    error (0, 0, "backto overriding date/rev/tag");
		    *since_rev = *since_tag = '\0';
		    if (since_date != NULL)
			free (since_date);
		    since_date = NULL;
		}
		free (backto);
		backto = xstrdup (optarg);
		break;
	    case 'f':			/* For specified file */
		save_file (NULL, optarg, NULL);
		break;
	    case 'm':			/* Full module report */
		if (!module_report++) report_count++;
		/* fall through */
	    case 'n':			/* Look for specified module */
		save_module (optarg);
		break;
	    case 'p':			/* For specified directory */
		save_file (optarg, NULL, NULL);
		break;
	    case 'r':			/* Since specified Tag/Rev */
		if (since_date || *since_tag || *backto)
		{
		    error (0, 0, "rev overriding date/tag/backto");
		    *since_tag = *backto = '\0';
		    if (since_date != NULL)
			free (since_date);
		    since_date = NULL;
		}
		free (since_rev);
		since_rev = xstrdup (optarg);
		break;
	    case 't':			/* Since specified Tag/Rev */
		if (since_date || *since_rev || *backto)
		{
		    error (0, 0, "tag overriding date/marker/file/repos");
		    *since_rev = *backto = '\0';
		    if (since_date != NULL)
			free (since_date);
		    since_date = NULL;
		}
		free (since_tag);
		since_tag = xstrdup (optarg);
		break;
	    case 'u':			/* For specified username */
		save_user (optarg);
		break;
	    case 'x':
		report_count++;
		extract++;
		{
		    char *cp;

		    for (cp = optarg; *cp; cp++)
			if (!strchr (ALL_HISTORY_REC_TYPES, *cp))
			    error (1, 0, "%c is not a valid report type", *cp);
		}
		free (rec_types);
		rec_types = xstrdup (optarg);
		break;
	    case 'z':
		tz_local = 
		    (optarg[0] == 'l' || optarg[0] == 'L')
		    && (optarg[1] == 't' || optarg[1] == 'T')
		    && !optarg[2];
		if (tz_local)
		    tz_name = optarg;
		else
		{
		    /*
		     * Convert a known time with the given timezone to time_t.
		     * Use the epoch + 23 hours, so timezones east of GMT work.
		     */
		    struct timespec t;
		    char *buf = Xasprintf ("1/1/1970 23:00 %s", optarg);
		    if (get_date (&t, buf, NULL))
		    {
			/*
			 * Convert to seconds east of GMT, removing the
			 * 23-hour offset mentioned above.
			 */
			tz_seconds_east_of_GMT = (time_t)23 * 60 * 60
						 - t.tv_sec;
			tz_name = optarg;
		    }
		    else
			error (0, 0, "%s is not a known time zone", optarg);
		    free (buf);
		}
		break;
	    case '?':
	    default:
		usage (history_usg);
		break;
	}
    }
    argc -= optind;
    argv += optind;
    for (i = 0; i < argc; i++)
	save_file (NULL, argv[i], NULL);


    /* ================ Now analyze the arguments a bit */
    if (!report_count)
	v_checkout++;
    else if (report_count > 1)
	error (1, 0, "Only one report type allowed from: \"-Tcomxe\".");

#ifdef CLIENT_SUPPORT
    if (current_parsed_root->isremote)
    {
	struct file_list_str *f1;
	char **mod;

	/* We're the client side.  Fire up the remote server.  */
	start_server ();
	
	ign_setup ();

	if (tag_report)
	    send_arg ("-T");
	if (all_users)
	    send_arg ("-a");
	if (modified)
	    send_arg ("-c");
	if (last_entry)
	    send_arg ("-l");
	if (v_checkout)
	    send_arg ("-o");
	if (working)
	    send_arg ("-w");
	if (fname)
	    option_with_arg ("-X", fname);
	if (since_date)
	    client_senddate (since_date);
	if (backto[0] != '\0')
	    option_with_arg ("-b", backto);
	for (f1 = file_list; f1 < &file_list[file_count]; ++f1)
	{
	    if (f1->l_file[0] == '*')
		option_with_arg ("-p", f1->l_file + 1);
	    else
		option_with_arg ("-f", f1->l_file);
	}
	if (module_report)
	    send_arg ("-m");
	for (mod = mod_list; mod < &mod_list[mod_count]; ++mod)
	    option_with_arg ("-n", *mod);
	if (*since_rev)
	    option_with_arg ("-r", since_rev);
	if (*since_tag)
	    option_with_arg ("-t", since_tag);
	for (mod = user_list; mod < &user_list[user_count]; ++mod)
	    option_with_arg ("-u", *mod);
	if (extract_all)
	    send_arg ("-e");
	if (extract)
	    option_with_arg ("-x", rec_types);
	option_with_arg ("-z", tz_name);

	send_to_server ("history\012", 0);
        return get_responses_and_close ();
    }
#endif

    if (all_users)
	save_user ("");

    if (mod_list)
	expand_modules ();

    if (tag_report)
    {
	if (!strchr (rec_types, 'T'))
	{
	    rec_types = xrealloc (rec_types, strlen (rec_types) + 5);
	    (void) strcat (rec_types, "T");
	}
    }
    else if (extract || extract_all)
    {
	if (user_list)
	    user_sort++;
    }
    else if (modified)
    {
	free (rec_types);
	rec_types = xstrdup ("MAR");
	/*
	 * If the user has not specified a date oriented flag ("Since"), sort
	 * by Repository/file before date.  Default is "just" date.
	 */
	if (last_entry
	    || (!since_date && !*since_rev && !*since_tag && !*backto))
	{
	    repos_sort++;
	    file_sort++;
	    /*
	     * If we are not looking for last_modified and the user specified
	     * one or more users to look at, sort by user before filename.
	     */
	    if (!last_entry && user_list)
		user_sort++;
	}
    }
    else if (module_report)
    {
	free (rec_types);
	rec_types = xstrdup (last_entry ? "OMAR" : ALL_HISTORY_REC_TYPES);
	module_sort++;
	repos_sort++;
	file_sort++;
	working = 0;			/* User's workdir doesn't count here */
    }
    else
	/* Must be "checkout" or default */
    {
	free (rec_types);
	rec_types = xstrdup ("OF");
	/* See comments in "modified" above */
	if (!last_entry && user_list)
	    user_sort++;
	if (last_entry
	    || (!since_date && !*since_rev && !*since_tag && !*backto))
	    file_sort++;
    }

    /* If no users were specified, use self (-a saves a universal ("") user) */
    if (!user_list)
	save_user (getcaller ());

    /* If we're looking back to a Tag value, must consider "Tag" records */
    if (*since_tag && !strchr (rec_types, 'T'))
    {
	rec_types = xrealloc (rec_types, strlen (rec_types) + 5);
	(void) strcat (rec_types, "T");
    }

    if (fname)
    {
	Node *p;

	flist = getlist ();
	p = getnode ();
	p->type = FILES;
	p->key = Xasprintf ("%s/%s/%s",
			    current_parsed_root->directory, CVSROOTADM, fname);
	addnode (flist, p);
    }
    else
    {
	char *pat;

	if (config->HistorySearchPath)
	    pat = config->HistorySearchPath;
	else
	    pat = Xasprintf ("%s/%s/%s",
			     current_parsed_root->directory, CVSROOTADM,
			     CVSROOTADM_HISTORY);

	flist = find_files (NULL, pat);
	if (pat != config->HistorySearchPath) free (pat);
    }

    read_hrecs (flist);
    if (hrec_count > 0)
	qsort (hrec_head, hrec_count, sizeof (struct hrec), sort_order);
    report_hrecs ();
    if (since_date != NULL)
	free (since_date);
    free (since_rev);
    free (since_tag);
    free (backto);
    free (rec_types);

    return 0;
}
Пример #4
0
int cvsstatus (int argc, char **argv)
{
    int c;
    int err = 0;

	supress_extra_fields = compat[compat_level].hide_extended_status;

    if (argc == -1)
	usage (status_usage);

    optind = 0;
    while ((c = getopt (argc, argv, "+vlRqxX")) != -1)
    {
	switch (c)
	{
	    case 'v':
		long_format = 1;
		break;
	    case 'l':
		local = 1;
		break;
	    case 'R':
		local = 0;
		break;
		case 'q':
		quick++;
		break;
		case 'x':
			supress_extra_fields = 0;
			break;
		case 'X':
			supress_extra_fields = 1;
			break;
	    case '?':
	    default:
		usage (status_usage);
		break;
	}
    }
    argc -= optind;
    argv += optind;

    if (current_parsed_root->isremote)
    {
	if (long_format)
	    send_arg("-v");
	if (local)
	    send_arg("-l");
	if (supress_extra_fields)
		send_arg("-X");
	for(c=0; c<quick; c++)
		send_arg("-q");
	send_arg("--");

	/* For a while, we tried setting SEND_NO_CONTENTS here so this
	   could be a fast operation.  That prevents the
	   server from updating our timestamp if the timestamp is
	   changed but the file is unmodified.  Worse, it is user-visible
	   (shows "locally modified" instead of "up to date" if
	   timestamp is changed but file is not).  And there is no good
	   workaround (you might not want to run "cvs update"; "cvs -n
	   update" doesn't update CVS/Entries; "cvs diff --brief" or
	   something perhaps could be made to work but somehow that
	   seems nonintuitive to me even if so).  Given that timestamps
	   seem to have the potential to get munged for any number of
	   reasons, it seems better to not rely too much on them.  */

	send_files (argc, argv, local, 0, 0);

	send_file_names (argc, argv, SEND_EXPAND_WILD);

	send_to_server ("status\n", 0);
	err = get_responses_and_close ();

	return err;
    }

    /* start the recursion processor */
    err = start_recursion (status_fileproc, (FILESDONEPROC) NULL,
			   (PREDIRENTPROC) NULL, status_dirproc, (DIRLEAVEPROC) NULL, NULL,
			   argc, argv, local,
			   W_LOCAL, 0, 1, (char *) NULL, NULL, 1, verify_read);

    return (err);
}
Пример #5
0
int lsacl (int argc, char **argv)
{
	int c;
	int err = 0;
	int local = 1;
	int directories_only = 0;

	is_rlsacl = !strcmp(command_name,"rlsacl");

	if (argc == -1)
		usage (is_rlsacl?rlsacl_usage:lsacl_usage);

	optind = 0;
	while ((c = getopt(argc, argv, "+dR")) != -1)
	{
		switch (c)
		{
		case 'd':
			directories_only = 1;
			break;
		case 'R':
			local = 0;
			break;
		case '?':
		default:
		usage (lsacl_usage);
		break;
		}
	}
	argc -= optind;
	argv += optind;

	if (argc < 0)
		usage (is_rlsacl?rlsacl_usage:lsacl_usage);

	if (current_parsed_root->isremote)
	{
		if(is_rlsacl)
		{
			if (!supported_request ("rlsacl"))
				error (1, 0, "server does not support rlsacl");
		}
		else
		{
			if (!supported_request ("lsacl"))
				error (1, 0, "server does not support lsacl");
		}

		if(!local)
			send_arg("-R");

		if(directories_only)
			send_arg("-d");

		send_arg("--");
		if (is_rlsacl)
		{
			int i;
			for (i = 0; i < argc; i++)
			send_arg (argv[i]);
			send_to_server ("rlsacl\n", 0);
		}
		else
		{
			send_file_names (argc, argv, SEND_EXPAND_WILD);
			send_files (argc, argv, local, 0, SEND_NO_CONTENTS);
			send_to_server ("lsacl\n", 0);
		}
		return get_responses_and_close ();
   }

	if(!acl_mode)
		error(1,0,"Access control is disabled on this repository.");
    
	if (is_rlsacl)
	{
		DBM *db;
		int i;
		db = open_module ();
		if(!argc)
		{
				err += do_module (db, ".", MISC, "Listing", rlsacl_proc,
						(char *) NULL, 0, local, 0, 0, (char *) NULL);
		}
		else
		{
			for (i = 0; i < argc; i++)
			{
				err += do_module (db, argv[i], MISC, "Listing", rlsacl_proc,
						(char *) NULL, 0, local, 0, 0, (char *) NULL);
			}
		}
		close_module (db);
	}
	else
	{
		/* start the recursion processor */
		err = start_recursion (directories_only?NULL:lsacl_fileproc, (FILESDONEPROC) NULL,
					(PREDIRENTPROC) NULL, lsacl_dirproc, (DIRLEAVEPROC) NULL, NULL,
					argc, argv, local,
					W_LOCAL, 0, 1, (char *) NULL, NULL, 1, NULL);
	}

    return (err);

}
Пример #6
0
int
ls (int argc, char **argv)
{
    int c;
    int err = 0;

    is_rls = strcmp (cvs_cmd_name, "rls") == 0;

    if (argc == -1)
	usage (ls_usage);

    entries_format = false;
    long_format = false;
    show_tag = NULL;
    show_date = NULL;
    tag_validated = false;
    recurse = false;
    ls_prune_dirs = false;
    show_dead_revs = false;

    getoptreset ();

    while ((c = getopt (argc, argv,
#ifdef SERVER_SUPPORT
           server_active ? "qdelr:D:PR" :
#endif /* SERVER_SUPPORT */
           "delr:D:RP"
           )) != -1)
    {
	switch (c)
	{
#ifdef SERVER_SUPPORT
	    case 'q':
		if (server_active)
		{
		    error (0, 0,
"`%s ls -q' is deprecated.  Please use the global `-q' option instead.",
                           program_name);
		    quiet = true;
		}
		else
		    usage (ls_usage);
		break;
#endif /* SERVER_SUPPORT */
	    case 'd':
		show_dead_revs = true;
		break;
	    case 'e':
		entries_format = true;
		break;
	    case 'l':
		long_format = true;
		break;
	    case 'r':
		parse_tagdate (&show_tag, &show_date, optarg);
		break;
	    case 'D':
		if (show_date) free (show_date);
		show_date = Make_Date (optarg);
		break;
	    case 'P':
		ls_prune_dirs = true;
		break;
	    case 'R':
		recurse = true;
		break;
	    case '?':
	    default:
		usage (ls_usage);
		break;
	}
    }
    argc -= optind;
    argv += optind;

    if (entries_format && long_format)
    {
        error (0, 0, "`-e' & `-l' are mutually exclusive.");
        usage (ls_usage);
    }

    wrap_setup ();

#ifdef CLIENT_SUPPORT
    if (current_parsed_root->isremote)
    {
	/* We're the local client.  Fire up the remote server.	*/
	start_server ();

	ign_setup ();

	if (is_rls ? !(supported_request ("rlist") || supported_request ("ls"))
                   : !supported_request ("list"))
	    error (1, 0, "server does not support %s", cvs_cmd_name);

	if (quiet && !supported_request ("global-list-quiet"))
	    send_arg ("-q");
	if (entries_format)
	    send_arg ("-e");
	if (long_format)
	    send_arg ("-l");
	if (ls_prune_dirs)
	    send_arg ("-P");
	if (recurse)
	    send_arg ("-R");
	if (show_dead_revs)
	    send_arg ("-d");
	if (show_tag)
	    option_with_arg ("-r", show_tag);
	if (show_date)
	    client_senddate (show_date);

	send_arg ("--");

	if (is_rls)
	{
	    int i;
	    for (i = 0; i < argc; i++)
		send_arg (argv[i]);
            if (supported_request ("rlist"))
		send_to_server ("rlist\012", 0);
	    else
		/* For backwards compatibility with CVSNT...  */
		send_to_server ("ls\012", 0);
	}
	else
	{
	    /* Setting this means, I think, that any empty directories created
	     * by the server will be deleted by the client.  Since any dirs
	     * created at all by ls should remain empty, this should cause any
	     * dirs created by the server for the ls command to be deleted.
	     */
	    client_prune_dirs = 1;

	    /* I explicitly decide not to send contents here.  We *could* let
	     * the user pull status information with this command, but why
	     * don't they just use update or status?
	     */
	    send_files (argc, argv, !recurse, 0, SEND_NO_CONTENTS);
	    send_file_names (argc, argv, SEND_EXPAND_WILD);
	    send_to_server ("list\012", 0);
	}

	err = get_responses_and_close ();
	return err;
    }
#endif

    if (is_rls)
    {
	DBM *db;
	int i;
	db = open_module ();
	if (argc)
	{
	    for (i = 0; i < argc; i++)
	    {
		char *mod = xstrdup (argv[i]);
		char *p;

		for (p=strchr (mod,'\\'); p; p=strchr (p,'\\'))
		    *p='/';

		p = strrchr (mod,'/');
		if (p && (strchr (p,'?') || strchr (p,'*')))
		{
		    *p='\0';
		    regexp_match = p+1;
		}
		else
		    regexp_match = NULL;

		/* Frontends like to do 'ls -q /', so we support it explicitly.
                 */
		if (!strcmp (mod,"/"))
		{
		    *mod='\0';
		}

		err += do_module (db, mod, MISC, "Listing",
				  ls_proc, NULL, 0, 0, 0, 0, NULL);

		free (mod);
	    }
	}
	else
	{
	    /* should be ".", but do_recursion() 
	       fails this: assert ( strstr ( repository, "/./" ) == NULL ); */
	    char *topmod = xstrdup ("");
	    err += do_module (db, topmod, MISC, "Listing",
			      ls_proc, NULL, 0, 0, 0, 0, NULL);
	    free (topmod);
	}
	close_module (db);
    }
    else
	ls_proc (argc + 1, argv - 1, NULL, NULL, NULL, 0, 0, NULL, NULL);

    return err;
}
Пример #7
0
int chacl (int argc, char **argv)
{
	int c;
	int local = 1;
	int err = 0;
	int is_rchacl = !strcmp(command_name,"rchacl");

	if (argc == 1 || argc == -1)
		usage (is_rchacl?rchacl_usage:chacl_usage);

	memset(&parms,0,sizeof(parms));
	optind = 0;
	while ((c = getopt (argc, argv, "+a:dnRr:u:m:j:p:")) != -1)
	{
		switch (c)
		{
		case 'a':
			if(parms.del)
				error(1,0,"Cannot combine -a and -d");
			parms.access = xstrdup(optarg);
			break;
		case 'd':
			if(parms.access)
				error(1,0,"Cannot combine -a and -d");
			parms.del = 1;
			break;
		case 'j':
			parms.merge=xstrdup(optarg);
			break;
		case 'm':
			parms.message=xstrdup(optarg);
			break;
		case 'n':
			parms.noinherit=1;
			break;
		case 'p':
			parms.priority=xstrdup(optarg);
			break;
		case 'r':
			if(parms.branch)
				error(1,0,"Cannot have multiple -r options");
			parms.branch = xstrdup(optarg);
			break;
		case 'R':
			local = 0;
			break;
		case 'u':
			if(parms.user)
				error(1,0,"Cannot have multiple -u options");
			parms.user = xstrdup(optarg);
			break;
		case '?':
		default:
			usage (chacl_usage);
			break;
		}
	}
	argc -= optind;
	argv += optind;

	if (argc < 0)
		usage (is_rchacl?rchacl_usage:chacl_usage);

	if (current_parsed_root->isremote)
	{
		if(is_rchacl)
		{
			if (!supported_request ("rchacl2"))
				error (1, 0, "server does not support rchacl");
		}
		else
		{
			if (!supported_request ("chacl2"))
				error (1, 0, "server does not support v2 chacl");
		}

		if(parms.branch)
		{
			send_arg("-r");
			send_arg(parms.branch);
		}
		if(parms.user)
		{
			send_arg("-u");
			send_arg(parms.user);
		}
		if(parms.del)
			send_arg("-d");
		if(parms.noinherit)
			send_arg("-n");
		if(parms.access)
		{
			send_arg("-a");
			send_arg(parms.access);
		}
		if(parms.message)
		{
			send_arg("-m");
			send_arg(parms.message);
		}
		if(parms.merge)
		{
			send_arg("-j");
			send_arg(parms.merge);
		}
		if(parms.priority)
		{
			send_arg("-p");
			send_arg(parms.priority);
		}
		if(!local)
		{
			send_arg("-R");
		}
		send_arg("--");
		if (is_rchacl)
		{
			int i;
			for (i = 0; i < argc; i++)
			send_arg (argv[i]);
			send_to_server ("rchacl2\n", 0);
		}
		else
		{
			send_file_names (argc, argv, SEND_EXPAND_WILD);
			send_files (argc, argv, local, 0, SEND_NO_CONTENTS);
			send_to_server ("chacl2\n", 0);
		}
		return get_responses_and_close ();
	}

	if(!acl_mode)
		error(1,0,"Access control is disabled on this repository.");

	if (is_rchacl)
	{
		DBM *db;
		int i;
		db = open_module ();
		for (i = 0; i < argc; i++)
		{
			err += do_module (db, argv[i], MISC, "Changing", rchacl_proc,
					(char *) NULL, 0, local, 0, 0, (char *) NULL);
		}
		close_module (db);
	}
	else
	{
		current_date = date_from_time_t(global_session_time_t);
		err = start_recursion(chacl_fileproc, NULL, (PREDIRENTPROC) NULL, chacl_dirproc, chacl_dirleaveproc, (void*)NULL,
			argc, argv, local, W_LOCAL, 0, 0, (char*)NULL, NULL, 1, verify_control, parms.branch);
		xfree(current_date);
	}

	return (err);
}
Пример #8
0
int cvsremove (int argc, char **argv)
{
    int c, err;

    if (argc == -1)
	usage (remove_usage);

    optind = 0;
    while ((c = getopt (argc, argv, "+flR")) != -1)
    {
	switch (c)
	{
	    case 'f':
		force = 1;
		break;
	    case 'l':
		local = 1;
		break;
	    case 'R':
		local = 0;
		break;
	    case '?':
	    default:
		usage (remove_usage);
		break;
	}
    }
    argc -= optind;
    argv += optind;

    if (current_parsed_root->isremote) {
	/* Call expand_wild so that the local removal of files will
           work.  It's ok to do it always because we have to send the
           file names expanded anyway.  */
	expand_wild (argc, argv, &argc, &argv);
	
	if (force)
	{
	    if (!noexec)
	    {
		start_recursion (remove_force_fileproc, (FILESDONEPROC) NULL,
				 (PREDIRENTPROC) NULL, (DIRENTPROC) NULL, (DIRLEAVEPROC) NULL,
				 (void *) NULL, argc, argv, local, W_LOCAL,
				 0, 0, (char *) NULL, NULL, 0, NULL, NULL);
	    }
	    /* else FIXME should probably act as if the file doesn't exist
	       in doing the following checks.  */
	}

	if (local)
	    send_arg("-l");
	send_arg("--");
	/* FIXME: Can't we set SEND_NO_CONTENTS here?  Needs investigation.  */
	send_files (argc, argv, local, 0, 0);
	send_file_names (argc, argv, 0);
	free_names (&argc, argv);
	send_to_server ("remove\n", 0);
        return get_responses_and_close ();
    }

    /* start the recursion processor */
    err = start_recursion (remove_fileproc, (FILESDONEPROC) NULL,
                           (PREDIRENTPROC) NULL, remove_dirproc, (DIRLEAVEPROC) NULL, NULL,
			   argc, argv,
                           local, W_LOCAL, 0, 1, (char *) NULL, NULL, 1,
			   verify_create, NULL);

    if (removed_files && !really_quiet)
		error (0, 0, "use '%s commit' to remove %s permanently", program_name,
	       (removed_files == 1) ? "this file" : "these files");

    if (existing_files)
	{
		error (0, 0,
	       ((existing_files == 1) ? "%d file exists; remove it first" :	"%d files exist; remove them first"),
	       existing_files);
		err=1;
	}

	if(bad_files)
		err=1;

    return (err);
}