/* * 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; }
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); }
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; }
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); }
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); }
/* * 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 */ }
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; }
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); }
/* * 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; }