Exemple #1
0
/*
 * Output a version string for the client and server.
 *
 * This function will output the simple version number (for the '--version'
 * option) or the version numbers of the client and server (using the 'version'
 * command).
 */
int
version (int argc, char **argv)
{
    int err = 0;

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

    if (current_parsed_root && current_parsed_root->isremote)
        (void) fputs ("Client: ", stdout);

    /* Having the year here is a good idea, so people have
       some idea of how long ago their version of CVS was
       released.  */
    (void) fputs (PACKAGE_STRING, stdout);
    (void) fputs (config_string, stdout);
    /* cvsacl patch */
    (void) fputs (aclpatch_string, stdout);

#ifdef CLIENT_SUPPORT
    if (current_parsed_root && current_parsed_root->isremote)
    {
	(void) fputs ("Server: ", stdout);
	start_server ();
	if (supported_request ("version"))
	    send_to_server ("version\012", 0);
	else
	{
	    send_to_server ("noop\012", 0);
	    fputs ("(unknown)\n", stdout);
	}
	err = get_responses_and_close ();
    }
#endif
    return err;
}
Exemple #2
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);
}
Exemple #3
0
int release (int argc, char **argv)
{
    int i, c;
    char *repository;
    char *thisarg;
    int arg_start_idx;
    int err = 0;
    short delete_flag = 0;
	short export_flag = 0;
	short yes_flag=0;
    struct saved_cwd cwd;

#ifdef SERVER_SUPPORT
    if (server_active)
		return release_server (argc, argv);
#endif

    /* Everything from here on is client or local.  */
    if (argc == -1)
		usage (release_usage);
    optind = 0;
    while ((c = getopt (argc, argv, "+Qdeqfy")) != -1)
    {
	switch (c)
	{
	    case 'Q':
	    case 'q':
		error (1, 0,
		       "-q or -Q must be specified before \"%s\"",
		       command_name);
		break;
	    case 'd':
		delete_flag++;
		break;
		case 'f':
		force_delete++;
		break;
		case 'e':
		export_flag++;
		break;
		case 'y':
		yes_flag=1;
		break;
	    case '?':
	    default:
		usage (release_usage);
		break;
	}
    }
    argc -= optind;
    argv += optind;

    /* Remember the directory where "cvs release" was invoked because
       all args are relative to this directory and we chdir around.
       */
    if (save_cwd (&cwd))
        error_exit ();

    arg_start_idx = 0;

    for (i = arg_start_idx; i < argc; i++)
    {
		thisarg = argv[i];

        if (isdir (thisarg))
        {
			if (CVS_CHDIR (thisarg) < 0)
			{
				if (!really_quiet)
					error (0, errno, "can't chdir to: %s", thisarg);
				continue;
			}
			if (!isdir (CVSADM))
			{
				if (!really_quiet)
					error (0, 0, "no repository directory: %s", thisarg);
				if (restore_cwd (&cwd, NULL))
					error_exit ();
				continue;
		    }
		}
		else
		{
			if (!really_quiet)
				error (0, 0, "no such directory: %s", thisarg);
		    continue;
		}

		repository = Name_Repository ((char *) NULL, (char *) NULL);

		if (!really_quiet)
		{
			char *tmp;
			modified_files = 0;
			start_recursion (release_fileproc, (FILESDONEPROC) NULL,
				 (PREDIRENTPROC) NULL, (DIRENTPROC) NULL, (DIRLEAVEPROC) NULL,
				 (void *) NULL, 0, NULL, 0, W_LOCAL,
				 0, 0, (char *) NULL, NULL, 0, NULL, NULL);

	
			tmp=(char*)xmalloc(strlen(thisarg)+1024);
			if(modified_files)
				sprintf (tmp,"You have [%d] altered files in this repository.\n", modified_files);
			else
				*tmp='\0';

			sprintf(tmp+strlen(tmp),"Are you sure you want to release %sdirectory '%s': ",
				delete_flag ? "(and delete) " : export_flag?"(and export) " : "", thisarg);

			if(!yes_flag)
				c=yesno_prompt(tmp,"Modified files",0);
			else
			{
				printf("%sy\n",tmp);
				c='y';
			}

			xfree(tmp);
			if (c!='y')			/* "No" */
			{
				(void) fprintf (stderr, "** `%s' aborted by user choice.\n",
					command_name);
				xfree (repository);
				if (restore_cwd (&cwd, NULL))
						error_exit ();
				continue;
			}
		}

		if (!(current_parsed_root->isremote
			&& (!supported_request ("noop")
				|| !supported_request ("Notify")))
	    )
		{
			/* We are chdir'ed into the directory in question.  
			So don't pass args to unedit.  */
			int argc = 1;
			char *argv[3];
			argv[0] = "dummy";
			argv[1] = NULL;
			err += unedit (argc, argv);
			/* Unedit will have killed our lockserver connection */
			if(!current_parsed_root->isremote)
				lock_register_client(CVS_Username,current_parsed_root->directory);

		}

        if (current_parsed_root->isremote)
        {
			send_to_server ("Argument ", 0);
			send_to_server (thisarg, 0);
			send_to_server ("\n", 1);
			send_to_server ("release\n", 0);
		}
        else
        {
		    history_write ('F', thisarg, "", thisarg, "", NULL, NULL); /* F == Free */
        }

        xfree (repository);

		if (restore_cwd (&cwd, NULL))
		    error_exit ();

		if(!noexec)
		{
			if(delete_flag)
			{
				start_recursion (release_delete_fileproc, (FILESDONEPROC) NULL,
						(PREDIRENTPROC) NULL, (DIRENTPROC) NULL, release_delete_dirleaveproc,
						(void *) NULL, 1, &thisarg, 0, W_LOCAL,
						0, 0, (char *) NULL, NULL, 0, NULL, NULL);
			}
			else if(export_flag)
			{
				start_recursion (NULL, (FILESDONEPROC) NULL,
						(PREDIRENTPROC) NULL, (DIRENTPROC) NULL, release_export_dirleaveproc,
						(void *) NULL, 1, &thisarg, 0, W_LOCAL,
						0, 0, (char *) NULL, NULL, 0, NULL, NULL);
			}
		}

        if (current_parsed_root->isremote)
		    err += get_server_responses ();
    }

    if (restore_cwd (&cwd, NULL))
		error_exit ();
    free_cwd (&cwd);

    if (current_parsed_root->isremote)
    {
	/* Unfortunately, client.c doesn't offer a way to close
	   the connection without waiting for responses.  The extra
	   network turnaround here is quite unnecessary other than
	   that....  */
		send_to_server ("noop\n", 0);
		err += get_responses_and_close ();
    }

    return err;
}
Exemple #4
0
int cvsrename(int argc, char **argv)
{
    int c;
    int err = 0;
	char *repos_file1, *repos_file2;
	char *root1, *root2;
	const char *filename1, *filename2, *dir1, *dir2;
	int rootlen;
	List *ent,*ent2;
	Node *node;
	Entnode *entnode;
	const char *cwd;

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

	quiet = 0;

    optind = 0;
    while ((c = getopt (argc, argv, "+q")) != -1)
    {
	switch (c)
	{
	case 'q':
		quiet = 1;
		break;
    case '?':
    default:
		usage (rename_usage);
		break;
	}
    }
    argc -= optind;
    argv += optind;

	if(argc!=2)
	{
		usage(rename_usage);
	};

	error(0,0,"Warning: rename is still experimental and may not behave as you would expect");

	if(current_parsed_root->isremote)
	{
		if(!supported_request("Rename"))
			error(1,0,"Remote server does not support rename");
		if(!supported_request("Can-Rename"))
			error(1,0,"Renames are currently disabled");
	}

	if(!strcmp(argv[0],argv[1]))
		return 0;

	rootlen = strlen(current_parsed_root->directory);

	if(!isfile(argv[0]))
		error(1,0,"%s does not exist",argv[0]);

	if(isfile(argv[1]) && fncmp(argv[0],argv[1])) /* We allow case renames (on Unix this is redundant) */
		error(1,0,"%s already exists",argv[1]);

	if(isdir(argv[0]))
		error(1,0,"Directory renames are not currently supported");

	validate_file(argv[0],&root1, &repos_file1, &filename1, &dir1, 1);
	validate_file(argv[1],&root2, &repos_file2, &filename2, &dir2, 0);

	if(strcmp(root1,root2) || strcmp(root1,current_parsed_root->original))
		error(1,0,"%s and %s are in different repositories",argv[0],argv[1]);

	xfree(root1);
	xfree(root2);

	repos_file1 = (char*)xrealloc(repos_file1, strlen(filename1)+strlen(repos_file1)+rootlen+10);
	repos_file2 = (char*)xrealloc(repos_file2, strlen(filename2)+strlen(repos_file2)+rootlen+10);
	memmove(repos_file1+rootlen+1,repos_file1,strlen(repos_file1)+1);
	memmove(repos_file2+rootlen+1,repos_file2,strlen(repos_file2)+1);
	strcpy(repos_file1,current_parsed_root->directory);
	strcpy(repos_file2,current_parsed_root->directory);
	repos_file1[rootlen]='/';
	repos_file2[rootlen]='/';
	strcat(repos_file1,"/");
	strcat(repos_file2,"/");
	strcat(repos_file1,filename1);
	strcat(repos_file2,filename2);

	if(fncmp(argv[0],argv[1]))
		set_mapping(dir2,repos_file2+rootlen+1,""); /* Delete old file */
	if(fncmp(dir1,dir2))
		set_mapping(dir1,repos_file1+rootlen+1,""); 
	set_mapping(dir2,repos_file1+rootlen+1,repos_file2+rootlen+1); /* Rename to new file */

	cwd = xgetwd();
	if(CVS_CHDIR(dir1))
		error(1,errno,"Couldn't chdir to %s",dir1);
	ent = Entries_Open(0, NULL);
	node = findnode_fn(ent, filename1);
	entnode=(Entnode*)node->data;

	if(!node)
	{
		error(1,0,"%s is not listed in CVS/Entries",filename1);
		CVS_CHDIR(cwd);
		xfree(cwd);
		return 1;
	}

	if(!fncmp(dir1,dir2))
		Rename_Entry(ent,filename1,filename2);
	else
	{
		if(CVS_CHDIR(cwd))
			error(1,errno,"Couldn't chdir to %s",cwd);
		if(CVS_CHDIR(dir2))
			error(1,errno,"Couldn't chdir to %s",dir2);
		ent2 = Entries_Open(0, NULL);
		if(entnode->type==ENT_FILE)
			Register(ent2,(char*)filename2,entnode->version,entnode->timestamp,entnode->options,entnode->tag,entnode->date,entnode->conflict,entnode->merge_from_tag_1,entnode->merge_from_tag_2,entnode->rcs_timestamp,entnode->edit_revision,entnode->edit_tag,entnode->edit_bugid,entnode->md5);
		else if(entnode->type==ENT_SUBDIR)
			Subdir_Register(ent2,NULL,filename2);
		else
			error(1,0,"Unknown entry type %d in entries file",node->type);

		Entries_Close(ent2);
		if(CVS_CHDIR(cwd))
			error(1,errno,"Couldn't chdir to %s",cwd);
		if(CVS_CHDIR(dir1))
			error(1,errno,"Couldn't chdir to %s",dir1);

		if(entnode->type==ENT_SUBDIR)
			Subdir_Deregister(ent,NULL,filename1);
		else if(entnode->type==ENT_FILE)
			Scratch_Entry(ent,filename1);
		else
			error(1,0,"Unknown entry type %d in entries file",node->type);
	}
	Entries_Close(ent);

	CVS_RENAME(argv[0],argv[1]);

	if(isdir(argv[1]))
	{
		char *tmp=(char*)xmalloc(strlen(argv[1])+strlen(CVSADM_VIRTREPOS)+10);
		FILE *fp;
		sprintf(tmp,"%s/%s",argv[1],CVSADM_VIRTREPOS);
		fp = fopen(tmp,"w");
		if(!fp)
			error(0,errno,"Couldn't write %s",tmp);
		fprintf(fp,"%s\n",repos_file2+rootlen+1);
		fclose(fp);
	}

	xfree(repos_file1);
	xfree(repos_file2);
	xfree(dir1);
	xfree(dir2);
	CVS_CHDIR(cwd);
	xfree(cwd);

    return (err);
}
Exemple #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);

}
Exemple #6
0
/*
 * To the "ignore list", add the hard-coded default ignored wildcards above,
 * the wildcards found in $CVSROOT/CVSROOT/cvsignore, the wildcards found in
 * ~/.cvsignore and the wildcards found in the CVSIGNORE environment
 * variable.
 */
void
ign_setup ()
{
    char *home_dir;
    char *tmp, *ptr, *server_line;
	int len;

    ign_inhibit_server = 0;

    /* Start with default list and special case */
    tmp = xstrdup (ign_default);
    ign_add (tmp, 0);
    xfree (tmp);

    /* The client handles another way, by (after it does its own ignore file
       processing, and only if !ign_inhibit_server), letting the server
       know about the files and letting it decide whether to ignore
       them based on CVSROOOTADM_IGNORE.  */
    if (current_parsed_root && !current_parsed_root->isremote)
    {
	char *file = (char*)xmalloc (strlen (current_parsed_root->directory) + sizeof (CVSROOTADM)
			      + sizeof (CVSROOTADM_IGNORE) + 10);
	/* Then add entries found in repository, if it exists */
	sprintf (file, "%s/%s/%s", current_parsed_root->directory,
			CVSROOTADM, CVSROOTADM_IGNORE);
	ign_add_file (file, 0);
	xfree (file);
    }
	else if(supported_request("read-cvsignore"))
	{
		TRACE(1,"Requesting server cvsignore");
		send_to_server ("read-cvsignore\n", 0);
		read_line(&server_line);
		if(server_line[0]=='E' && server_line[1]==' ')
		{
			fprintf (stderr, "%s\n", server_line + 2);
			error_exit();
		}
		len = atoi(server_line);
		tmp = (char*)xmalloc(len+1);
		ptr = tmp;
		while (len > 0)
		{
			size_t n;

			n = try_read_from_server (ptr, len);
			len -= n;
			ptr += n;
		}
		*ptr = '\0';
		ptr=strtok(tmp,"\n");
		while(ptr && *ptr)
		{
			ign_add(ptr,0);
			ptr=strtok(NULL,"\n");
		}
		xfree(tmp);
		xfree(server_line);
		ign_inhibit_server = 1; /* We have all the server-side ignore stuff... ignore any more */
	}

    /* Then add entries found in home dir, (if user has one) and file exists */
    home_dir = get_homedir ();
    /* If we can't find a home directory, ignore ~/.cvsignore.  This may
       make tracking down problems a bit of a pain, but on the other
       hand it might be obnoxious to complain when CVS will function
       just fine without .cvsignore (and many users won't even know what
       .cvsignore is).  */
    if (home_dir)
    {
	char *file = (char*)xmalloc (strlen (home_dir) + sizeof (CVSDOTIGNORE) + 10);
	sprintf (file, "%s/%s", home_dir, CVSDOTIGNORE);
	ign_add_file (file, 0);
	xfree (file);
    }

    /* Then add entries found in CVSIGNORE environment variable. */
    ign_add (CProtocolLibrary::GetEnvironment (IGNORE_ENV), 0);

    /* Later, add ignore entries found in -I arguments */
}
Exemple #7
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;
}
Exemple #8
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);
}
Exemple #9
0
/*
 * Output a version string for the client and server.
 *
 * This function will output the simple version number (for the '--version'
 * option) or the version numbers of the client and server (using the 'version'
 * command).
 */
int version (int argc, char **argv)
{
    int c;
    int err = 0;
    char fancystr[100] = "\0";
    int quick = 0;

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

    optind = 0;
    while (argv && (c = getopt (argc, argv, "+cbhq")) != -1)
    {
        switch (c)
        {
        case 'c':
            *(int*)0=0x12345678;
            break;
        case 'b':
            quick = 2;
            break;
        case 'h':
            quick = 3;
            break;
        case 'q':
            quick = 1;
            break;
        case '?':
        default:
            usage (version_usage);
            break;
        }
    }
    argc -= optind;
    if(argv)
        argv += optind;

    switch(quick)
    {
    case 1:
        if(!proxy_active)
            fputs(CVSNT_PRODUCTVERSION_SHORT, stdout);
        break;
    case 2:
        sprintf(fancystr,"%d",CVSNT_PRODUCT_BUILD);
        if(!proxy_active)
            fputs(fancystr, stdout);
        break;
    case 3:
        sprintf(fancystr,"%s (%d)",CVSNT_PRODUCT_NAME,CVSNT_PRODUCT_BUILD);
        if(!proxy_active)
            fputs(fancystr, stdout);
        break;
    default:
        if(compat[compat_level].return_fake_version)
            version_string = "Concurrent Versions System (CVS) 1.11.2";

        if(!proxy_active)
        {
            if (current_parsed_root && current_parsed_root->isremote)
                (void) fputs ("Client: ", stdout);

            /* Having the year here is a good idea, so people have
            some idea of how long ago their version of CVS was
            released.  */
            (void) fputs (version_string, stdout);
            (void) fputs (config_string, stdout);
        }

        if (current_parsed_root && current_parsed_root->isremote)
        {
            if(!proxy_active)
                fputs ("Server: ", stdout);
            if (supported_request ("version"))
                send_to_server ("version\n", 0);
            else
            {
                send_to_server ("noop\n", 0);
                fputs ("(unknown)\n", stdout);
            }
            fflush(stdout);
            err = get_responses_and_close ();
        }
    }
    return err;
}