#include "cvs.h"
#include "savecwd.h"
#include "getline.h"
static const char *const release_usage[] =
{
"Usage: %s %s [-d] directories...\n",
"\t-d\tDelete the given directory.\n",
"(Specify the --help global option for a list of other help options)\n",
NULL
};
#ifdef SERVER_SUPPORT
static int release_server PROTO ((int argc, char **argv));
static int
release_server (argc, argv)
int argc;
char **argv;
{
int i;
for (i = 1; i < argc; ++i)
history_write ('F', argv[i], "", argv[i], "");
return 0;
}
#endif
int
release (argc, argv)
int argc;
char **argv;
{
FILE *fp;
int i, c;
char *line = NULL;
size_t line_allocated = 0;
char *update_cmd;
char *thisarg;
int arg_start_idx;
int err = 0;
short delete_flag = 0;
struct saved_cwd cwd;
#ifdef SERVER_SUPPORT
if (server_active)
return release_server (argc, argv);
#endif
if (argc == -1)
usage (release_usage);
optind = 0;
while ((c = getopt (argc, argv, "+Qdq")) != -1)
{
switch (c)
{
case 'Q':
case 'q':
error (1, 0,
"-q or -Q must be specified before \"%s\"",
cvs_cmd_name);
break;
case 'd':
delete_flag++;
break;
case '?':
default:
usage (release_usage);
break;
}
}
argc -= optind;
argv += optind;
update_cmd = xmalloc (strlen (program_path)
+ strlen (current_parsed_root->original)
+ 1 + 3 + 3 + 16 + 1);
sprintf (update_cmd, "%s %s%s-n -q -d %s update",
program_path,
#if defined (CLIENT_SUPPORT) || defined (SERVER_SUPPORT)
cvsauthenticate ? "-a " : "",
cvsencrypt ? "-x " : "",
#else
"", "",
#endif
current_parsed_root->original);
#ifdef CLIENT_SUPPORT
if (current_parsed_root->isremote)
{
start_server ();
ign_setup ();
}
#endif
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;
}
if (!really_quiet)
{
int line_length;
fp = run_popen (update_cmd, "r");
if (fp == NULL)
error (1, 0, "cannot run command %s", update_cmd);
c = 0;
while ((line_length = getline (&line, &line_allocated, fp)) >= 0)
{
if (strchr ("MARCZ", *line))
c++;
(void) fputs (line, stdout);
}
if (line_length < 0 && !feof (fp))
error (0, errno, "cannot read from subprocess");
if ((pclose (fp)) != 0)
{
error (0, 0, "unable to release `%s'", thisarg);
if (restore_cwd (&cwd, NULL))
error_exit ();
continue;
}
printf ("You have [%d] altered files in this repository.\n",
c);
printf ("Are you sure you want to release %sdirectory `%s': ",
delete_flag ? "(and delete) " : "", thisarg);
c = !yesno ();
if (c)
{
(void) fprintf (stderr, "** `%s' aborted by user choice.\n",
cvs_cmd_name);
if (restore_cwd (&cwd, NULL))
error_exit ();
continue;
}
}
if (restore_cwd (&cwd, NULL))
exit (EXIT_FAILURE);
if (1
#ifdef CLIENT_SUPPORT
&& !(current_parsed_root->isremote
&& (!supported_request ("noop")
|| !supported_request ("Notify")))
#endif
)
{
int argc = 2;
char *argv[3];
argv[0] = "dummy";
argv[1] = thisarg;
argv[2] = NULL;
err += unedit (argc, argv);
if (restore_cwd (&cwd, NULL))
exit (EXIT_FAILURE);
}
#ifdef CLIENT_SUPPORT
if (current_parsed_root->isremote)
{
send_to_server ("Argument ", 0);
send_to_server (thisarg, 0);
send_to_server ("\012", 1);
send_to_server ("release\012", 0);
}
else
#endif
{
history_write ('F', thisarg, "", thisarg, "");
}
if (delete_flag)
{
if (unlink_file_dir (thisarg) < 0)
error (0, errno, "deletion of directory %s failed", thisarg);
}
#ifdef CLIENT_SUPPORT
if (current_parsed_root->isremote)
{
err += get_server_responses ();
if (restore_cwd (&cwd, NULL))
exit (EXIT_FAILURE);
}
#endif
}
if (restore_cwd (&cwd, NULL))
error_exit ();
free_cwd (&cwd);
#ifdef CLIENT_SUPPORT
if (current_parsed_root->isremote)
{
send_to_server ("noop\012", 0);
err += get_responses_and_close ();
}
#endif
free (update_cmd);
if (line != NULL)
free (line);
return err;
}