Add all our changes:
- our kerberos support - nolock - setuid support / setxid in child - avoid dangerous commands and only allow admin group to execute them - selectable CVS directory name - symlinked repository fixes - log admin commands in history - default to ssh instead of rsh - localid keyword - null revision on re-added files - umask fixes - t flag in log - don't recursively re-enter signal error handler - xasprintf in selected places - ipv6 support
This commit is contained in:
parent
56ece2a214
commit
2cd25f5744
185
gnu/dist/xcvs/src/admin.c
vendored
185
gnu/dist/xcvs/src/admin.c
vendored
@ -28,12 +28,16 @@ static int admin_fileproc PROTO ((void *callerdat, struct file_info *finfo));
|
||||
static const char *const admin_usage[] =
|
||||
{
|
||||
"Usage: %s %s [options] files...\n",
|
||||
#ifndef CVS_ADMIN_LIMITED
|
||||
"\t-a users Append (comma-separated) user names to access list.\n",
|
||||
"\t-A file Append another file's access list.\n",
|
||||
"\t-b[rev] Set default branch (highest branch on trunk if omitted).\n",
|
||||
#endif
|
||||
"\t-c string Set comment leader.\n",
|
||||
#ifndef CVS_ADMIN_LIMITED
|
||||
"\t-e[users] Remove (comma-separated) user names from access list\n",
|
||||
"\t (all names if omitted).\n",
|
||||
#endif
|
||||
"\t-I Run interactively.\n",
|
||||
"\t-k subst Set keyword substitution mode:\n",
|
||||
"\t kv (Default) Substitute keyword and value.\n",
|
||||
@ -42,10 +46,13 @@ static const char *const admin_usage[] =
|
||||
"\t o Preserve original string.\n",
|
||||
"\t b Like o, but mark file as binary.\n",
|
||||
"\t v Substitute value only.\n",
|
||||
#ifndef CVS_ADMIN_LIMITED
|
||||
"\t-l[rev] Lock revision (latest revision on branch,\n",
|
||||
"\t latest revision on trunk if omitted).\n",
|
||||
"\t-L Set strict locking.\n",
|
||||
#endif
|
||||
"\t-m rev:msg Replace revision's log message.\n",
|
||||
#ifndef CVS_ADMIN_LIMITED
|
||||
"\t-n tag[:[rev]] Tag branch or revision. If :rev is omitted,\n",
|
||||
"\t delete the tag; if rev is omitted, tag the latest\n",
|
||||
"\t revision on the default branch.\n",
|
||||
@ -58,14 +65,19 @@ static const char *const admin_usage[] =
|
||||
"\t :rev rev and previous revisions on the same branch.\n",
|
||||
"\t ::rev Before rev on the same branch.\n",
|
||||
"\t rev Just rev.\n",
|
||||
#endif
|
||||
"\t-q Run quietly.\n",
|
||||
#ifndef CVS_ADMIN_LIMITED
|
||||
"\t-s state[:rev] Set revision state (latest revision on branch,\n",
|
||||
"\t latest revision on trunk if omitted).\n",
|
||||
#endif
|
||||
"\t-t[file] Get descriptive text from file (stdin if omitted).\n",
|
||||
"\t-t-string Set descriptive text.\n",
|
||||
#ifndef CVS_ADMIN_LIMITED
|
||||
"\t-u[rev] Unlock the revision (latest revision on branch,\n",
|
||||
"\t latest revision on trunk if omitted).\n",
|
||||
"\t-U Unset strict locking.\n",
|
||||
#endif
|
||||
"(Specify the --help global option for a list of other help options)\n",
|
||||
NULL
|
||||
};
|
||||
@ -110,6 +122,11 @@ struct admin_data
|
||||
int ac;
|
||||
char **av;
|
||||
int av_alloc;
|
||||
|
||||
/* This contains a printable version of the command line used
|
||||
* for logging
|
||||
*/
|
||||
char *cmdline;
|
||||
};
|
||||
|
||||
/* Add an argument. OPT is the option letter, e.g. 'a'. ARG is the
|
||||
@ -144,20 +161,113 @@ arg_add (dat, opt, arg)
|
||||
dat->av[dat->ac++] = newelt;
|
||||
}
|
||||
|
||||
static size_t
|
||||
wescape(dst, src)
|
||||
char *dst;
|
||||
const char *src;
|
||||
{
|
||||
const unsigned char *s = src;
|
||||
char *d = dst;
|
||||
for (; *s; s++) {
|
||||
if (!isprint(*s) || isspace(*s) || *s == '|') {
|
||||
*d++ = '\\';
|
||||
*d++ = ((*s >> 6) & 3) + '0';
|
||||
*d++ = ((*s >> 3) & 7) + '0';
|
||||
*d++ = ((*s >> 0) & 7) + '0';
|
||||
} else {
|
||||
*d++ = *s;
|
||||
}
|
||||
}
|
||||
*d = '\0';
|
||||
return d - dst;
|
||||
}
|
||||
|
||||
static char *
|
||||
makecmdline(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
size_t clen = 1024, wlen = 1024, len, cpos = 0, i;
|
||||
char *cmd = xmalloc(clen);
|
||||
char *word = xmalloc(wlen);
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
char *arg = (strncmp(argv[i], "cvs ", 4) == 0) ? argv[i] + 4 : argv[i];
|
||||
len = strlen(arg);
|
||||
if (len * 4 < wlen) {
|
||||
wlen += len * 4;
|
||||
word = xrealloc(word, wlen);
|
||||
}
|
||||
len = wescape(word, arg);
|
||||
if (clen - cpos < len + 2) {
|
||||
clen += len + 2;
|
||||
cmd = xrealloc(cmd, clen);
|
||||
}
|
||||
memcpy(&cmd[cpos], word, len);
|
||||
cpos += len;
|
||||
cmd[cpos++] = ' ';
|
||||
}
|
||||
if (cpos != 0)
|
||||
cmd[cpos - 1] = '\0';
|
||||
else
|
||||
cmd[cpos] = '\0';
|
||||
free(word);
|
||||
return cmd;
|
||||
}
|
||||
|
||||
int
|
||||
admin_group_member()
|
||||
{
|
||||
struct group *grp;
|
||||
struct group *getgrnam();
|
||||
int i;
|
||||
|
||||
if (CVS_admin_group == NULL)
|
||||
return 1;
|
||||
|
||||
if ((grp = getgrnam(CVS_admin_group)) == NULL)
|
||||
return 0;
|
||||
|
||||
{
|
||||
#ifdef HAVE_GETGROUPS
|
||||
gid_t *grps;
|
||||
int n;
|
||||
|
||||
/* get number of auxiliary groups */
|
||||
n = getgroups (0, NULL);
|
||||
if (n < 0)
|
||||
error (1, errno, "unable to get number of auxiliary groups");
|
||||
grps = (gid_t *) xmalloc((n + 1) * sizeof *grps);
|
||||
n = getgroups (n, grps);
|
||||
if (n < 0)
|
||||
error (1, errno, "unable to get list of auxiliary groups");
|
||||
grps[n] = getgid();
|
||||
for (i = 0; i <= n; i++)
|
||||
if (grps[i] == grp->gr_gid) break;
|
||||
free (grps);
|
||||
if (i > n)
|
||||
return 0;
|
||||
#else
|
||||
char *me = getcaller();
|
||||
char **grnam;
|
||||
|
||||
for (grnam = grp->gr_mem; *grnam; grnam++)
|
||||
if (strcmp (*grnam, me) == 0) break;
|
||||
if (!*grnam && getgid() != grp->gr_gid)
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
int
|
||||
admin (argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
int err;
|
||||
#ifdef CVS_ADMIN_GROUP
|
||||
struct group *grp;
|
||||
struct group *getgrnam();
|
||||
#endif
|
||||
struct admin_data admin_data;
|
||||
int c;
|
||||
int i;
|
||||
int only_k_option;
|
||||
int only_limited_options = 1;
|
||||
|
||||
if (argc <= 1)
|
||||
usage (admin_usage);
|
||||
@ -165,17 +275,17 @@ admin (argc, argv)
|
||||
wrap_setup ();
|
||||
|
||||
memset (&admin_data, 0, sizeof admin_data);
|
||||
admin_data.cmdline = makecmdline (argc, argv);
|
||||
|
||||
/* TODO: get rid of `-' switch notation in admin_data. For
|
||||
example, admin_data->branch should be not `-bfoo' but simply `foo'. */
|
||||
|
||||
optind = 0;
|
||||
only_k_option = 1;
|
||||
while ((c = getopt (argc, argv,
|
||||
"+ib::c:a:A:e::l::u::LUn:N:m:o:s:t::IqxV:k:")) != -1)
|
||||
{
|
||||
if (c != 'k' && c != 'q')
|
||||
only_k_option = 0;
|
||||
if (CVS_admin_options == NULL || strchr(CVS_admin_options, c) == NULL)
|
||||
only_limited_options = 0;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
@ -188,6 +298,7 @@ admin (argc, argv)
|
||||
goto usage_error;
|
||||
|
||||
case 'b':
|
||||
|
||||
if (admin_data.branch != NULL)
|
||||
{
|
||||
error (0, 0, "duplicate 'b' option");
|
||||
@ -380,49 +491,17 @@ admin (argc, argv)
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
#ifdef CVS_ADMIN_GROUP
|
||||
/* The use of `cvs admin -k' is unrestricted. However, any other
|
||||
option is restricted if the group CVS_ADMIN_GROUP exists on the
|
||||
server. */
|
||||
/* This is only "secure" on the server, since the user could edit the
|
||||
* RCS file on a local host, but some people like this kind of
|
||||
* check anyhow. The alternative would be to check only when
|
||||
* (server_active) rather than when not on the client.
|
||||
*/
|
||||
if (!current_parsed_root->isremote && !only_k_option &&
|
||||
(grp = getgrnam(CVS_ADMIN_GROUP)) != NULL)
|
||||
{
|
||||
#ifdef HAVE_GETGROUPS
|
||||
gid_t *grps;
|
||||
int n;
|
||||
|
||||
/* get number of auxiliary groups */
|
||||
n = getgroups (0, NULL);
|
||||
if (n < 0)
|
||||
error (1, errno, "unable to get number of auxiliary groups");
|
||||
grps = (gid_t *) xmalloc((n + 1) * sizeof *grps);
|
||||
n = getgroups (n, grps);
|
||||
if (n < 0)
|
||||
error (1, errno, "unable to get list of auxiliary groups");
|
||||
grps[n] = getgid();
|
||||
for (i = 0; i <= n; i++)
|
||||
if (grps[i] == grp->gr_gid) break;
|
||||
free (grps);
|
||||
if (i > n)
|
||||
error (1, 0, "usage is restricted to members of the group %s",
|
||||
CVS_ADMIN_GROUP);
|
||||
#else
|
||||
char *me = getcaller();
|
||||
char **grnam;
|
||||
|
||||
for (grnam = grp->gr_mem; *grnam; grnam++)
|
||||
if (strcmp (*grnam, me) == 0) break;
|
||||
if (!*grnam && getgid() != grp->gr_gid)
|
||||
error (1, 0, "usage is restricted to members of the group %s",
|
||||
CVS_ADMIN_GROUP);
|
||||
#endif
|
||||
}
|
||||
#endif /* defined CVS_ADMIN_GROUP */
|
||||
if (
|
||||
/* This is only "secure" on the server, since the user could edit the
|
||||
* RCS file on a local host, but some people like this kind of
|
||||
* check anyhow. The alternative would be to check only when
|
||||
* (server_active) rather than when not on the client.
|
||||
*/
|
||||
!current_parsed_root->isremote &&
|
||||
!only_limited_options &&
|
||||
!admin_group_member())
|
||||
error (1, 0, "usage is restricted to members of the group %s",
|
||||
CVS_admin_group);
|
||||
|
||||
for (i = 0; i < admin_data.ac; ++i)
|
||||
{
|
||||
@ -526,6 +605,8 @@ admin (argc, argv)
|
||||
Lock_Cleanup ();
|
||||
|
||||
return_it:
|
||||
if (admin_data.cmdline != NULL)
|
||||
free (admin_data.cmdline);
|
||||
if (admin_data.branch != NULL)
|
||||
free (admin_data.branch);
|
||||
if (admin_data.comment != NULL)
|
||||
@ -570,6 +651,8 @@ admin_fileproc (callerdat, finfo)
|
||||
goto exitfunc;
|
||||
}
|
||||
|
||||
history_write ('X', finfo->update_dir, admin_data->cmdline, finfo->file,
|
||||
finfo->repository);
|
||||
rcs = vers->srcfile;
|
||||
if (rcs == NULL)
|
||||
{
|
||||
|
2
gnu/dist/xcvs/src/checkout.c
vendored
2
gnu/dist/xcvs/src/checkout.c
vendored
@ -194,7 +194,7 @@ checkout (argc, argv)
|
||||
case 'p':
|
||||
pipeout = 1;
|
||||
run_module_prog = 0; /* don't run module prog when piping */
|
||||
noexec = 1; /* so no locks will be created */
|
||||
noexec = nolock = 1; /* so no locks will be created */
|
||||
break;
|
||||
case 'c':
|
||||
cat = 1;
|
||||
|
118
gnu/dist/xcvs/src/client.c
vendored
118
gnu/dist/xcvs/src/client.c
vendored
@ -81,7 +81,7 @@ static Key_schedule sched;
|
||||
/* This is needed for GSSAPI encryption. */
|
||||
static gss_ctx_id_t gcontext;
|
||||
|
||||
static int connect_to_gserver PROTO((cvsroot_t *, int, struct hostent *));
|
||||
static int connect_to_gserver PROTO((cvsroot_t *, int, const char *));
|
||||
|
||||
# endif /* HAVE_GSSAPI */
|
||||
|
||||
@ -145,7 +145,7 @@ static void handle_notified PROTO((char *, int));
|
||||
static size_t try_read_from_server PROTO ((char *, size_t));
|
||||
|
||||
static void auth_server PROTO ((cvsroot_t *, struct buffer *, struct buffer *,
|
||||
int, int, struct hostent *));
|
||||
int, int));
|
||||
|
||||
/* We need to keep track of the list of directories we've sent to the
|
||||
server. This list, along with the current CVSROOT, will help us
|
||||
@ -1508,7 +1508,7 @@ handle_copy_file (args, len)
|
||||
}
|
||||
|
||||
|
||||
static void read_counted_file PROTO ((char *, char *));
|
||||
static void read_counted_file PROTO ((const char *, const char *));
|
||||
|
||||
/* Read from the server the count for the length of a file, then read
|
||||
the contents of that file and write them to FILENAME. FULLNAME is
|
||||
@ -1517,8 +1517,8 @@ static void read_counted_file PROTO ((char *, char *));
|
||||
use it. On error, gives a fatal error. */
|
||||
static void
|
||||
read_counted_file (filename, fullname)
|
||||
char *filename;
|
||||
char *fullname;
|
||||
const char *filename;
|
||||
const char *fullname;
|
||||
{
|
||||
char *size_string;
|
||||
size_t size;
|
||||
@ -3800,33 +3800,50 @@ connect_to_pserver (root, to_server_p, from_server_p, verify_only, do_gssapi)
|
||||
{
|
||||
int sock;
|
||||
int port_number;
|
||||
struct sockaddr_in client_sai;
|
||||
struct hostent *hostinfo;
|
||||
char no_passwd = 0; /* gets set if no password found */
|
||||
struct addrinfo hints, *res, *res0 = NULL;
|
||||
char pbuf[10];
|
||||
int e;
|
||||
struct buffer *to_server, *from_server;
|
||||
|
||||
sock = socket (AF_INET, SOCK_STREAM, 0);
|
||||
if (sock == -1)
|
||||
{
|
||||
error (1, 0, "cannot create socket: %s", SOCK_STRERROR (SOCK_ERRNO));
|
||||
}
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = PF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_flags = AI_CANONNAME;
|
||||
port_number = get_cvs_port_number (root);
|
||||
hostinfo = init_sockaddr (&client_sai, root->hostname, port_number);
|
||||
if (trace)
|
||||
snprintf(pbuf, sizeof(pbuf), "%d", port_number);
|
||||
e = getaddrinfo(root->hostname, pbuf, &hints, &res0);
|
||||
if (e)
|
||||
{
|
||||
fprintf (stderr, " -> Connecting to %s(%s):%d\n",
|
||||
root->hostname,
|
||||
inet_ntoa (client_sai.sin_addr), port_number);
|
||||
error (1, 0, "%s", gai_strerror(e));
|
||||
}
|
||||
sock = -1;
|
||||
for (res = res0; res; res = res->ai_next) {
|
||||
sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
|
||||
if (sock < 0)
|
||||
continue;
|
||||
|
||||
if (trace)
|
||||
{
|
||||
fprintf (stderr, " -> Connecting to %s\n", root->hostname);
|
||||
}
|
||||
if (connect(sock, res->ai_addr, res->ai_addrlen) < 0) {
|
||||
close(sock);
|
||||
sock = -1;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
freeaddrinfo(res0);
|
||||
if (sock < 0)
|
||||
{
|
||||
error (1, 0, "connect to %s:%s failed: %s", root->hostname,
|
||||
pbuf, SOCK_STRERROR (SOCK_ERRNO));
|
||||
}
|
||||
if (connect (sock, (struct sockaddr *) &client_sai, sizeof (client_sai))
|
||||
< 0)
|
||||
error (1, 0, "connect to %s(%s):%d failed: %s",
|
||||
root->hostname,
|
||||
inet_ntoa (client_sai.sin_addr),
|
||||
port_number, SOCK_STRERROR (SOCK_ERRNO));
|
||||
|
||||
make_bufs_from_fds (sock, sock, 0, &to_server, &from_server, 1);
|
||||
|
||||
auth_server (root, to_server, from_server, verify_only, do_gssapi, hostinfo);
|
||||
auth_server (root, to_server, from_server, verify_only, do_gssapi);
|
||||
|
||||
if (verify_only)
|
||||
{
|
||||
@ -3860,13 +3877,12 @@ connect_to_pserver (root, to_server_p, from_server_p, verify_only, do_gssapi)
|
||||
|
||||
|
||||
static void
|
||||
auth_server (root, lto_server, lfrom_server, verify_only, do_gssapi, hostinfo)
|
||||
auth_server (root, lto_server, lfrom_server, verify_only, do_gssapi)
|
||||
cvsroot_t *root;
|
||||
struct buffer *lto_server;
|
||||
struct buffer *lfrom_server;
|
||||
int verify_only;
|
||||
int do_gssapi;
|
||||
struct hostent *hostinfo;
|
||||
{
|
||||
char *username; /* the username we use to connect */
|
||||
char no_passwd = 0; /* gets set if no password found */
|
||||
@ -3896,7 +3912,7 @@ auth_server (root, lto_server, lfrom_server, verify_only, do_gssapi, hostinfo)
|
||||
error (1, 0, "gserver currently only enabled for socket connections");
|
||||
}
|
||||
|
||||
if (! connect_to_gserver (root, fd, hostinfo))
|
||||
if (! connect_to_gserver (root, fd, root->hostname))
|
||||
{
|
||||
error (1, 0,
|
||||
"authorization failed: server %s rejected access to %s",
|
||||
@ -4137,7 +4153,8 @@ start_tcp_server (root, to_server, from_server)
|
||||
|
||||
/* We don't care about the checksum, and pass it as zero. */
|
||||
status = krb_sendauth (KOPT_DO_MUTUAL, s, &ticket, "rcmd",
|
||||
hname, realm, (unsigned long) 0, &msg_data,
|
||||
hname, (char *)realm, (unsigned long) 0,
|
||||
&msg_data,
|
||||
&cred, sched, &laddr, &sin, "KCVSV1.0");
|
||||
if (status != KSUCCESS)
|
||||
error (1, 0, "kerberos authentication failed: %s",
|
||||
@ -4197,10 +4214,10 @@ recv_bytes (sock, buf, need)
|
||||
*/
|
||||
#define BUFSIZE 1024
|
||||
static int
|
||||
connect_to_gserver (root, sock, hostinfo)
|
||||
connect_to_gserver (root, sock, hostname)
|
||||
cvsroot_t *root;
|
||||
int sock;
|
||||
struct hostent *hostinfo;
|
||||
const char *hostname;
|
||||
{
|
||||
char *str;
|
||||
char buf[BUFSIZE];
|
||||
@ -4213,9 +4230,9 @@ connect_to_gserver (root, sock, hostinfo)
|
||||
if (send (sock, str, strlen (str), 0) < 0)
|
||||
error (1, 0, "cannot send: %s", SOCK_STRERROR (SOCK_ERRNO));
|
||||
|
||||
if (strlen (hostinfo->h_name) > BUFSIZE - 5)
|
||||
if (strlen (hostname) > BUFSIZE - 5)
|
||||
error (1, 0, "Internal error: hostname exceeds length of buffer");
|
||||
sprintf (buf, "cvs@%s", hostinfo->h_name);
|
||||
sprintf (buf, "cvs@%s", hostname);
|
||||
tok_in.length = strlen (buf);
|
||||
tok_in.value = buf;
|
||||
gss_import_name (&stat_min, &tok_in, GSS_C_NT_HOSTBASED_SERVICE,
|
||||
@ -4528,6 +4545,16 @@ start_server ()
|
||||
error (1, 0,
|
||||
"This server does not support the global -n option.");
|
||||
}
|
||||
if (nolock && !noexec)
|
||||
{
|
||||
if (have_global)
|
||||
{
|
||||
send_to_server ("Global_option -u\012", 0);
|
||||
}
|
||||
else
|
||||
error (1, 0,
|
||||
"This server does not support the global -u option.");
|
||||
}
|
||||
if (quiet)
|
||||
{
|
||||
if (have_global)
|
||||
@ -4759,27 +4786,7 @@ start_rsh_server (root, to_server, from_server)
|
||||
char *rsh_argv[10];
|
||||
|
||||
if (!cvs_rsh)
|
||||
/* People sometimes suggest or assume that this should default
|
||||
to "remsh" on systems like HPUX in which that is the
|
||||
system-supplied name for the rsh program. However, that
|
||||
causes various problems (keep in mind that systems such as
|
||||
HPUX might have non-system-supplied versions of "rsh", like
|
||||
a Kerberized one, which one might want to use). If we
|
||||
based the name on what is found in the PATH of the person
|
||||
who runs configure, that would make it harder to
|
||||
consistently produce the same result in the face of
|
||||
different people producing binary distributions. If we
|
||||
based it on "remsh" always being the default for HPUX
|
||||
(e.g. based on uname), that might be slightly better but
|
||||
would require us to keep track of what the defaults are for
|
||||
each system type, and probably would cope poorly if the
|
||||
existence of remsh or rsh varies from OS version to OS
|
||||
version. Therefore, it seems best to have the default
|
||||
remain "rsh", and tell HPUX users to specify remsh, for
|
||||
example in CVS_RSH or other such mechanisms to be devised,
|
||||
if that is what they want (the manual already tells them
|
||||
that). */
|
||||
cvs_rsh = "rsh";
|
||||
cvs_rsh = "ssh";
|
||||
if (!cvs_server)
|
||||
cvs_server = "cvs";
|
||||
|
||||
@ -4840,7 +4847,7 @@ start_rsh_server (root, to_server, from_server)
|
||||
int child_pid;
|
||||
|
||||
if (!cvs_rsh)
|
||||
cvs_rsh = "rsh";
|
||||
cvs_rsh = "ssh";
|
||||
if (!cvs_server)
|
||||
cvs_server = "cvs";
|
||||
|
||||
@ -5332,8 +5339,7 @@ send_dirent_proc (callerdat, dir, repository, update_dir, entries)
|
||||
* This case will happen when checking out a module defined as
|
||||
* ``-a .''.
|
||||
*/
|
||||
cvsadm_name = xmalloc (strlen (dir) + sizeof (CVSADM) + 10);
|
||||
sprintf (cvsadm_name, "%s/%s", dir, CVSADM);
|
||||
xasprintf (&cvsadm_name, "%s/%s", dir, CVSADM);
|
||||
dir_exists = isdir (cvsadm_name);
|
||||
free (cvsadm_name);
|
||||
|
||||
|
21
gnu/dist/xcvs/src/commit.c
vendored
21
gnu/dist/xcvs/src/commit.c
vendored
@ -1024,7 +1024,9 @@ warning: file `%s' seems to still contain conflict indicators",
|
||||
xmalloc (sizeof (struct logfile_info)));
|
||||
li->type = status;
|
||||
li->tag = xstrdup (vers->tag);
|
||||
li->rev_old = xstrdup (vers->vn_rcs);
|
||||
/* If the file was re-added, we want the revision in the commitlog
|
||||
to be NONE, not the previous dead revision. */
|
||||
li->rev_old = status == T_ADDED ? NULL : xstrdup (vers->vn_rcs);
|
||||
li->rev_new = NULL;
|
||||
p->data = li;
|
||||
(void) addnode (ulist, p);
|
||||
@ -1176,7 +1178,8 @@ precommit_proc (repository, filter)
|
||||
run_setup (filter);
|
||||
run_arg (repository);
|
||||
(void) walklist (saved_ulist, precommit_list_proc, NULL);
|
||||
return run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL|RUN_REALLY);
|
||||
return run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL|RUN_REALLY|
|
||||
(server_active ? 0 : RUN_UNSETXID));
|
||||
}
|
||||
|
||||
|
||||
@ -1787,9 +1790,8 @@ finaladd (finfo, rev, tag, options)
|
||||
ret = Checkin ('A', finfo, rev, tag, options, saved_message);
|
||||
if (ret == 0)
|
||||
{
|
||||
char *tmp = xmalloc (strlen (finfo->file) + sizeof (CVSADM)
|
||||
+ sizeof (CVSEXT_LOG) + 10);
|
||||
(void) sprintf (tmp, "%s/%s%s", CVSADM, finfo->file, CVSEXT_LOG);
|
||||
char *tmp;
|
||||
(void) xasprintf (&tmp, "%s/%s%s", CVSADM, finfo->file, CVSEXT_LOG);
|
||||
if (unlink_file (tmp) < 0
|
||||
&& !existence_error (errno))
|
||||
error (0, errno, "cannot remove %s", tmp);
|
||||
@ -1970,9 +1972,8 @@ checkaddfile (file, repository, tag, options, rcsnode)
|
||||
|
||||
/* this is the first time we have ever seen this file; create
|
||||
an RCS file. */
|
||||
fname = xmalloc (strlen (file) + sizeof (CVSADM)
|
||||
+ sizeof (CVSEXT_LOG) + 10);
|
||||
(void) sprintf (fname, "%s/%s%s", CVSADM, file, CVSEXT_LOG);
|
||||
|
||||
(void) xasprintf (&fname, "%s/%s%s", CVSADM, file, CVSEXT_LOG);
|
||||
/* If the file does not exist, no big deal. In particular, the
|
||||
server does not (yet at least) create CVSEXT_LOG files. */
|
||||
if (isfile (fname))
|
||||
@ -2090,9 +2091,7 @@ checkaddfile (file, repository, tag, options, rcsnode)
|
||||
int retcode;
|
||||
|
||||
/* move the new file out of the way. */
|
||||
fname = xmalloc (strlen (file) + sizeof (CVSADM)
|
||||
+ sizeof (CVSPREFIX) + 10);
|
||||
(void) sprintf (fname, "%s/%s%s", CVSADM, CVSPREFIX, file);
|
||||
(void) xasprintf (&fname, "%s/%s%s", CVSADM, CVSPREFIX, file);
|
||||
rename_file (file, fname);
|
||||
|
||||
/* Create empty FILE. Can't use copy_file with a DEVNULL
|
||||
|
73
gnu/dist/xcvs/src/cvs.h
vendored
73
gnu/dist/xcvs/src/cvs.h
vendored
@ -130,38 +130,42 @@ extern int errno;
|
||||
Here as #define's to make changing the names a simple task. */
|
||||
|
||||
#ifdef USE_VMS_FILENAMES
|
||||
#define CVSADM "CVS"
|
||||
#define CVSADM_ENT "CVS/Entries."
|
||||
#define CVSADM_ENTBAK "CVS/Entries.Backup"
|
||||
#define CVSADM_ENTLOG "CVS/Entries.Log"
|
||||
#define CVSADM_ENTSTAT "CVS/Entries.Static"
|
||||
#define CVSADM_REP "CVS/Repository."
|
||||
#define CVSADM_ROOT "CVS/Root."
|
||||
#define CVSADM_TAG "CVS/Tag."
|
||||
#define CVSADM_NOTIFY "CVS/Notify."
|
||||
#define CVSADM_NOTIFYTMP "CVS/Notify.tmp"
|
||||
#define CVSADM_BASE "CVS/Base"
|
||||
#define CVSADM_BASEREV "CVS/Baserev."
|
||||
#define CVSADM_BASEREVTMP "CVS/Baserev.tmp"
|
||||
#define CVSADM_TEMPLATE "CVS/Template."
|
||||
#define CVSADM getCVSDir("")
|
||||
#define CVSADM_ENT getCVSDir("/Entries.")
|
||||
#define CVSADM_ENTBAK getCVSDir("/Entries.Backup")
|
||||
#define CVSADM_ENTLOG getCVSDir("/Entries.Log")
|
||||
#define CVSADM_ENTSTAT getCVSDir("/Entries.Static")
|
||||
#define CVSADM_REP getCVSDir("/Repository.")
|
||||
#define CVSADM_ROOT getCVSDir("/Root.")
|
||||
#define CVSADM_CIPROG getCVSDir("/Checkin.prog")
|
||||
#define CVSADM_UPROG getCVSDir("/Update.prog")
|
||||
#define CVSADM_TAG getCVSDir("/Tag.")
|
||||
#define CVSADM_NOTIFY getCVSDir("/Notify.")
|
||||
#define CVSADM_NOTIFYTMP getCVSDir("/Notify.tmp")
|
||||
#define CVSADM_BASE getCVSDir("/Base")
|
||||
#define CVSADM_BASEREV getCVSDir("/Baserev.")
|
||||
#define CVSADM_BASEREVTMP getCVSDir("/Baserev.tmp")
|
||||
#define CVSADM_TEMPLATE getCVSDir("/Template.")
|
||||
#else /* USE_VMS_FILENAMES */
|
||||
#define CVSADM "CVS"
|
||||
#define CVSADM_ENT "CVS/Entries"
|
||||
#define CVSADM_ENTBAK "CVS/Entries.Backup"
|
||||
#define CVSADM_ENTLOG "CVS/Entries.Log"
|
||||
#define CVSADM_ENTSTAT "CVS/Entries.Static"
|
||||
#define CVSADM_REP "CVS/Repository"
|
||||
#define CVSADM_ROOT "CVS/Root"
|
||||
#define CVSADM_TAG "CVS/Tag"
|
||||
#define CVSADM_NOTIFY "CVS/Notify"
|
||||
#define CVSADM_NOTIFYTMP "CVS/Notify.tmp"
|
||||
#define CVSADM getCVSDir("")
|
||||
#define CVSADM_ENT getCVSDir("/Entries")
|
||||
#define CVSADM_ENTBAK getCVSDir("/Entries.Backup")
|
||||
#define CVSADM_ENTLOG getCVSDir("/Entries.Log")
|
||||
#define CVSADM_ENTSTAT getCVSDir("/Entries.Static")
|
||||
#define CVSADM_REP getCVSDir("/Repository")
|
||||
#define CVSADM_ROOT getCVSDir("/Root")
|
||||
#define CVSADM_CIPROG getCVSDir("/Checkin.prog")
|
||||
#define CVSADM_UPROG getCVSDir("/Update.prog")
|
||||
#define CVSADM_TAG getCVSDir("/Tag")
|
||||
#define CVSADM_NOTIFY getCVSDir("/Notify")
|
||||
#define CVSADM_NOTIFYTMP getCVSDir("/Notify.tmp")
|
||||
/* A directory in which we store base versions of files we currently are
|
||||
editing with "cvs edit". */
|
||||
#define CVSADM_BASE "CVS/Base"
|
||||
#define CVSADM_BASEREV "CVS/Baserev"
|
||||
#define CVSADM_BASEREVTMP "CVS/Baserev.tmp"
|
||||
#define CVSADM_BASE getCVSDir("/Base")
|
||||
#define CVSADM_BASEREV getCVSDir("/Baserev")
|
||||
#define CVSADM_BASEREVTMP getCVSDir("/Baserev.tmp")
|
||||
/* File which contains the template for use in log messages. */
|
||||
#define CVSADM_TEMPLATE "CVS/Template"
|
||||
#define CVSADM_TEMPLATE getCVSDir("/Template")
|
||||
#endif /* USE_VMS_FILENAMES */
|
||||
|
||||
/* This is the special directory which we use to store various extra
|
||||
@ -172,7 +176,7 @@ extern int errno;
|
||||
|
||||
See fileattr.h for details about file attributes, the only thing stored
|
||||
in CVSREP currently. */
|
||||
#define CVSREP "CVS"
|
||||
#define CVSREP getCVSDir("")
|
||||
|
||||
/*
|
||||
* Definitions for the CVSROOT Administrative directory and the files it
|
||||
@ -382,8 +386,10 @@ extern int really_quiet, quiet;
|
||||
extern int use_editor;
|
||||
extern int cvswrite;
|
||||
extern mode_t cvsumask;
|
||||
|
||||
|
||||
extern char *RCS_citag;
|
||||
extern char *CVS_admin_group;
|
||||
extern char *CVS_admin_options;
|
||||
extern int admin_group_member PROTO((void));
|
||||
|
||||
/* This global variable holds the global -d option. It is NULL if -d
|
||||
was not used, which means that we must get the CVSroot information
|
||||
@ -400,6 +406,7 @@ extern int safe_location PROTO ((char *));
|
||||
|
||||
extern int trace; /* Show all commands */
|
||||
extern int noexec; /* Don't modify disk anywhere */
|
||||
extern int nolock; /* Don't create locks */
|
||||
extern int logoff; /* Don't write history entry */
|
||||
|
||||
extern int top_level_admin;
|
||||
@ -453,6 +460,7 @@ List *Entries_Open PROTO ((int aflag, char *update_dir));
|
||||
void Subdirs_Known PROTO((List *entries));
|
||||
void Subdir_Register PROTO((List *, const char *, const char *));
|
||||
void Subdir_Deregister PROTO((List *, const char *, const char *));
|
||||
const char *getCVSDir PROTO((const char *));
|
||||
|
||||
char *Make_Date PROTO((char *rawdate));
|
||||
char *date_from_time_t PROTO ((time_t));
|
||||
@ -475,6 +483,8 @@ void *xrealloc PROTO((void *ptr, size_t bytes));
|
||||
void expand_string PROTO ((char **, size_t *, size_t));
|
||||
void xrealloc_and_strcat PROTO ((char **, size_t *, const char *));
|
||||
char *xstrdup PROTO((const char *str));
|
||||
int xasprintf PROTO((char ** __restrict, const char * __restrict, ...))
|
||||
__attribute__((__format__(__printf__, 2, 3)));
|
||||
int strip_trailing_newlines PROTO((char *str));
|
||||
int pathname_levels PROTO ((const char *path));
|
||||
|
||||
@ -694,6 +704,7 @@ void sleep_past PROTO ((time_t desttime));
|
||||
#define RUN_STDOUT_APPEND 0x0004 /* append to stdout, don't truncate */
|
||||
#define RUN_STDERR_APPEND 0x0008 /* append to stderr, don't truncate */
|
||||
#define RUN_SIGIGNORE 0x0010 /* ignore interrupts for command */
|
||||
#define RUN_UNSETXID 0x0020 /* undo setxid in child */
|
||||
#define RUN_TTY (char *)0 /* for the benefit of lint */
|
||||
|
||||
void run_add_arg_p PROTO ((int *, size_t *, char ***, const char *s));
|
||||
|
6
gnu/dist/xcvs/src/diff.c
vendored
6
gnu/dist/xcvs/src/diff.c
vendored
@ -672,11 +672,7 @@ diff_fileproc (callerdat, finfo)
|
||||
if( tocvsPath != NULL )
|
||||
{
|
||||
/* Backup the current version of the file to CVS/,,filename */
|
||||
fname = xmalloc (strlen (finfo->file)
|
||||
+ sizeof CVSADM
|
||||
+ sizeof CVSPREFIX
|
||||
+ 10);
|
||||
sprintf(fname,"%s/%s%s",CVSADM, CVSPREFIX, finfo->file);
|
||||
xasprintf(&fname,"%s/%s%s",CVSADM, CVSPREFIX, finfo->file);
|
||||
if (unlink_file_dir (fname) < 0)
|
||||
if (! existence_error (errno))
|
||||
error (1, errno, "cannot remove %s", fname);
|
||||
|
10
gnu/dist/xcvs/src/edit.c
vendored
10
gnu/dist/xcvs/src/edit.c
vendored
@ -341,10 +341,7 @@ edit_fileproc (callerdat, finfo)
|
||||
trying to create the output file fails. But copy_file isn't
|
||||
set up to facilitate that. */
|
||||
mkdir_if_needed (CVSADM_BASE);
|
||||
basefilename = xmalloc (10 + sizeof CVSADM_BASE + strlen (finfo->file));
|
||||
strcpy (basefilename, CVSADM_BASE);
|
||||
strcat (basefilename, "/");
|
||||
strcat (basefilename, finfo->file);
|
||||
xasprintf(&basefilename, "%s/%s", CVSADM_BASE, finfo->file);
|
||||
copy_file (finfo->file, basefilename);
|
||||
free (basefilename);
|
||||
|
||||
@ -473,10 +470,7 @@ unedit_fileproc (callerdat, finfo)
|
||||
if (noexec)
|
||||
return 0;
|
||||
|
||||
basefilename = xmalloc (10 + sizeof CVSADM_BASE + strlen (finfo->file));
|
||||
strcpy (basefilename, CVSADM_BASE);
|
||||
strcat (basefilename, "/");
|
||||
strcat (basefilename, finfo->file);
|
||||
xasprintf(&basefilename, "%s/%s", CVSADM_BASE, finfo->file);
|
||||
if (!isfile (basefilename))
|
||||
{
|
||||
/* This file apparently was never cvs edit'd (e.g. we are uneditting
|
||||
|
46
gnu/dist/xcvs/src/entries.c
vendored
46
gnu/dist/xcvs/src/entries.c
vendored
@ -100,7 +100,7 @@ write_ent_proc (node, closure)
|
||||
Entnode *entnode = node->data;
|
||||
|
||||
if (closure != NULL && entnode->type != ENT_FILE)
|
||||
*(int *) closure = 1;
|
||||
closure = (void *)1;
|
||||
|
||||
if (fputentent(entfile, entnode))
|
||||
error (1, errno, "cannot write %s", entfilename);
|
||||
@ -121,7 +121,7 @@ write_entries (list)
|
||||
sawdir = 0;
|
||||
|
||||
/* open the new one and walk the list writing entries */
|
||||
entfilename = CVSADM_ENTBAK;
|
||||
entfilename = (char *)CVSADM_ENTBAK;
|
||||
entfile = CVS_FOPEN (entfilename, "w+");
|
||||
if (entfile == NULL)
|
||||
{
|
||||
@ -188,7 +188,7 @@ Scratch_Entry (list, fname)
|
||||
{
|
||||
if (!noexec)
|
||||
{
|
||||
entfilename = CVSADM_ENTLOG;
|
||||
entfilename = (char *)CVSADM_ENTLOG;
|
||||
entfile = open_file (entfilename, "a");
|
||||
|
||||
if (fprintf (entfile, "R ") < 0)
|
||||
@ -251,7 +251,7 @@ Register (list, fname, vn, ts, options, tag, date, ts_conflict)
|
||||
|
||||
if (!noexec)
|
||||
{
|
||||
entfilename = CVSADM_ENTLOG;
|
||||
entfilename = (char *)CVSADM_ENTLOG;
|
||||
entfile = CVS_FOPEN (entfilename, "a");
|
||||
|
||||
if (entfile == NULL)
|
||||
@ -659,13 +659,10 @@ WriteTag (dir, tag, date, nonbranch, update_dir, repository)
|
||||
if (noexec)
|
||||
return;
|
||||
|
||||
tmp = xmalloc ((dir ? strlen (dir) : 0)
|
||||
+ sizeof (CVSADM_TAG)
|
||||
+ 10);
|
||||
if (dir == NULL)
|
||||
(void) strcpy (tmp, CVSADM_TAG);
|
||||
tmp = xstrdup(CVSADM_TAG);
|
||||
else
|
||||
(void) sprintf (tmp, "%s/%s", dir, CVSADM_TAG);
|
||||
(void) xasprintf (&tmp, "%s/%s", dir, CVSADM_TAG);
|
||||
|
||||
if (tag || date)
|
||||
{
|
||||
@ -816,7 +813,7 @@ Subdirs_Known (entries)
|
||||
if (!noexec)
|
||||
{
|
||||
/* Create Entries.Log so that Entries_Close will do something. */
|
||||
entfilename = CVSADM_ENTLOG;
|
||||
entfilename = (char *)CVSADM_ENTLOG;
|
||||
fp = CVS_FOPEN (entfilename, "a");
|
||||
if (fp == NULL)
|
||||
{
|
||||
@ -856,14 +853,9 @@ subdir_record (cmd, parent, dir)
|
||||
if (!noexec)
|
||||
{
|
||||
if (parent == NULL)
|
||||
entfilename = CVSADM_ENTLOG;
|
||||
entfilename = (char *)CVSADM_ENTLOG;
|
||||
else
|
||||
{
|
||||
entfilename = xmalloc (strlen (parent)
|
||||
+ sizeof CVSADM_ENTLOG
|
||||
+ 10);
|
||||
sprintf (entfilename, "%s/%s", parent, CVSADM_ENTLOG);
|
||||
}
|
||||
xasprintf (&entfilename, "%s/%s", parent, CVSADM_ENTLOG);
|
||||
|
||||
entfile = CVS_FOPEN (entfilename, "a");
|
||||
if (entfile == NULL)
|
||||
@ -1030,23 +1022,15 @@ base_walk (code, finfo, rev)
|
||||
computation probably should be broken out into a separate function,
|
||||
as recurse.c does it too and places like Entries_Open should be
|
||||
doing it. */
|
||||
baserev_fullname = xmalloc (sizeof (CVSADM_BASEREV)
|
||||
+ strlen (finfo->update_dir)
|
||||
+ 2);
|
||||
baserev_fullname[0] = '\0';
|
||||
baserevtmp_fullname = xmalloc (sizeof (CVSADM_BASEREVTMP)
|
||||
+ strlen (finfo->update_dir)
|
||||
+ 2);
|
||||
baserevtmp_fullname[0] = '\0';
|
||||
if (finfo->update_dir[0] != '\0')
|
||||
{
|
||||
strcat (baserev_fullname, finfo->update_dir);
|
||||
strcat (baserev_fullname, "/");
|
||||
strcat (baserevtmp_fullname, finfo->update_dir);
|
||||
strcat (baserevtmp_fullname, "/");
|
||||
xasprintf(&baserev_fullname, "%s/%s", finfo->update_dir, CVSADM_BASEREV);
|
||||
xasprintf(&baserevtmp_fullname, "%s/%s",
|
||||
finfo->update_dir, CVSADM_BASEREVTMP);
|
||||
} else {
|
||||
baserev_fullname = xstrdup(CVSADM_BASEREV);
|
||||
baserevtmp_fullname = xstrdup(CVSADM_BASEREVTMP);
|
||||
}
|
||||
strcat (baserev_fullname, CVSADM_BASEREV);
|
||||
strcat (baserevtmp_fullname, CVSADM_BASEREVTMP);
|
||||
|
||||
fp = CVS_FOPEN (CVSADM_BASEREV, "r");
|
||||
if (fp == NULL)
|
||||
|
33
gnu/dist/xcvs/src/filesubr.c
vendored
33
gnu/dist/xcvs/src/filesubr.c
vendored
@ -203,6 +203,37 @@ iswritable (file)
|
||||
return isaccessible(file, W_OK);
|
||||
}
|
||||
|
||||
#ifdef SETXID_SUPPORT
|
||||
int
|
||||
ingroup(gid_t gid)
|
||||
{
|
||||
gid_t *gidp;
|
||||
int i, ngroups;
|
||||
|
||||
if (gid == getegid())
|
||||
return 1;
|
||||
|
||||
ngroups = getgroups(0, NULL);
|
||||
if (ngroups == -1)
|
||||
return 0;
|
||||
|
||||
if ((gidp = malloc(sizeof(gid_t) * ngroups)) == NULL)
|
||||
return 0;
|
||||
|
||||
if (getgroups(ngroups, gidp) == -1) {
|
||||
free(gidp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < ngroups; i++)
|
||||
if (gid == gidp[i])
|
||||
break;
|
||||
|
||||
free(gidp);
|
||||
return i != ngroups;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Returns non-zero if the argument file is accessable according to
|
||||
* mode. If compiled with SETXID_SUPPORT also works if cvs has setxid
|
||||
@ -254,7 +285,7 @@ isaccessible (file, mode)
|
||||
omask |= S_IXOTH;
|
||||
}
|
||||
|
||||
mask = sb.st_uid == uid ? umask : sb.st_gid == getegid() ? gmask : omask;
|
||||
mask = sb.st_uid == uid ? umask : ingroup(sb.st_gid) ? gmask : omask;
|
||||
if ((sb.st_mode & mask) == mask)
|
||||
return 1;
|
||||
errno = EACCES;
|
||||
|
6
gnu/dist/xcvs/src/find_names.c
vendored
6
gnu/dist/xcvs/src/find_names.c
vendored
@ -366,7 +366,7 @@ find_dirs (dir, list, checkadm, entries)
|
||||
expand_string (&tmp,
|
||||
&tmp_size,
|
||||
strlen (dir) + strlen (dp->d_name) + 10);
|
||||
sprintf (tmp, "%s/%s", dir, dp->d_name);
|
||||
snprintf (tmp, tmp_size, "%s/%s", dir, dp->d_name);
|
||||
if (!isdir (tmp))
|
||||
goto do_it_again;
|
||||
|
||||
@ -397,8 +397,8 @@ find_dirs (dir, list, checkadm, entries)
|
||||
expand_string (&tmp,
|
||||
&tmp_size,
|
||||
(strlen (dir) + strlen (dp->d_name)
|
||||
+ sizeof (CVSADM) + 10));
|
||||
(void) sprintf (tmp, "%s/%s/%s", dir, dp->d_name, CVSADM);
|
||||
+ strlen (CVSADM) + 10));
|
||||
(void) snprintf (tmp, tmp_size, "%s/%s/%s", dir, dp->d_name, CVSADM);
|
||||
if (!isdir (tmp))
|
||||
goto do_it_again;
|
||||
}
|
||||
|
3
gnu/dist/xcvs/src/history.c
vendored
3
gnu/dist/xcvs/src/history.c
vendored
@ -36,6 +36,7 @@
|
||||
* M "Commit" cmd - "Modified" file.
|
||||
* A "Commit" cmd - "Added" file.
|
||||
* R "Commit" cmd - "Removed" file.
|
||||
* X "Admin" cmd.
|
||||
*
|
||||
* date is a fixed length 8-char hex representation of a Unix time_t.
|
||||
* [Starting here, variable fields are delimited by '|' chars.]
|
||||
@ -760,7 +761,7 @@ history_write (type, update_dir, revs, name, repository)
|
||||
if (trace)
|
||||
fprintf (stderr, "%s-> fopen(%s,a)\n",
|
||||
CLIENT_SERVER_STR, fname);
|
||||
if (noexec)
|
||||
if (nolock)
|
||||
goto out;
|
||||
|
||||
if (!history_lock (current_parsed_root->directory))
|
||||
|
2
gnu/dist/xcvs/src/history.h
vendored
2
gnu/dist/xcvs/src/history.h
vendored
@ -12,4 +12,4 @@
|
||||
* with other portions of CVS.
|
||||
*/
|
||||
|
||||
#define ALL_HISTORY_REC_TYPES "TOEFWUPCGMAR"
|
||||
#define ALL_HISTORY_REC_TYPES "TOEFWUPCGMARX"
|
||||
|
12
gnu/dist/xcvs/src/ignore.c
vendored
12
gnu/dist/xcvs/src/ignore.c
vendored
@ -33,8 +33,9 @@ static int ign_size; /* This many slots available (plus
|
||||
static int ign_hold = -1; /* Index where first "temporary" item
|
||||
* is held */
|
||||
|
||||
extern const char *cvsDir;
|
||||
const char *ign_default = ". .. core RCSLOG tags TAGS RCS SCCS .make.state\
|
||||
.nse_depinfo #* .#* cvslog.* ,* CVS CVS.adm .del-* *.a *.olb *.o *.obj\
|
||||
.nse_depinfo #* .#* cvslog.* ,* CVS.adm .del-* *.a *.olb *.o *.obj\
|
||||
*.so *.Z *~ *.old *.elc *.ln *.bak *.BAK *.orig *.rej *.exe _$* *$";
|
||||
|
||||
#define IGN_GROW 16 /* grow the list by 16 elements at a
|
||||
@ -64,6 +65,9 @@ ign_setup ()
|
||||
tmp = xstrdup (ign_default);
|
||||
ign_add (tmp, 0);
|
||||
free (tmp);
|
||||
tmp = xstrdup(cvsDir);
|
||||
ign_add (tmp, 0);
|
||||
free (tmp);
|
||||
|
||||
/* The client handles another way, by (after it does its own ignore file
|
||||
processing, and only if !ign_inhibit_server), letting the server
|
||||
@ -428,8 +432,7 @@ ignore_files (ilist, entries, update_dir, proc)
|
||||
this directory if there is a CVS subdirectory.
|
||||
This will normally be the case, but the user may
|
||||
have messed up the working directory somehow. */
|
||||
p = xmalloc (strlen (file) + sizeof CVSADM + 10);
|
||||
sprintf (p, "%s/%s", file, CVSADM);
|
||||
xasprintf (&p, "%s/%s", file, CVSADM);
|
||||
dir = isdir (p);
|
||||
free (p);
|
||||
if (dir)
|
||||
@ -462,8 +465,7 @@ ignore_files (ilist, entries, update_dir, proc)
|
||||
{
|
||||
char *temp;
|
||||
|
||||
temp = xmalloc (strlen (file) + sizeof (CVSADM) + 10);
|
||||
(void) sprintf (temp, "%s/%s", file, CVSADM);
|
||||
(void) xasprintf (&temp, "%s/%s", file, CVSADM);
|
||||
if (isdir (temp))
|
||||
{
|
||||
free (temp);
|
||||
|
56
gnu/dist/xcvs/src/lock.c
vendored
56
gnu/dist/xcvs/src/lock.c
vendored
@ -113,6 +113,7 @@ static void clear_lock PROTO ((struct lock *lock));
|
||||
static void set_lockers_name PROTO((struct stat *statp));
|
||||
static int set_writelock_proc PROTO((Node * p, void *closure));
|
||||
static int unlock_proc PROTO((Node * p, void *closure));
|
||||
static int find_root PROTO((const char *repository, char *rootdir));
|
||||
static int write_lock PROTO ((struct lock *lock));
|
||||
static void lock_simple_remove PROTO ((struct lock *lock));
|
||||
static void lock_wait PROTO((char *repository));
|
||||
@ -187,14 +188,19 @@ lock_name (repository, name)
|
||||
{
|
||||
struct stat sb;
|
||||
mode_t new_mode = 0;
|
||||
int len;
|
||||
|
||||
/* The interesting part of the repository is the part relative
|
||||
to CVSROOT. */
|
||||
assert (current_parsed_root != NULL);
|
||||
assert (current_parsed_root->directory != NULL);
|
||||
assert (strncmp (repository, current_parsed_root->directory,
|
||||
strlen (current_parsed_root->directory)) == 0);
|
||||
short_repos = repository + strlen (current_parsed_root->directory) + 1;
|
||||
/*
|
||||
* Unfortunately, string comparisons are not enough because we
|
||||
* might have symlinks present
|
||||
*/
|
||||
len = find_root(repository, current_parsed_root->directory);
|
||||
assert(len != -1);
|
||||
short_repos = repository + len + 1;
|
||||
|
||||
if (strcmp (repository, current_parsed_root->directory) == 0)
|
||||
short_repos = ".";
|
||||
@ -297,6 +303,45 @@ lock_name (repository, name)
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the root directory in the repository directory
|
||||
*/
|
||||
static int
|
||||
find_root(repository, rootdir)
|
||||
const char *repository;
|
||||
char *rootdir;
|
||||
{
|
||||
struct stat strep, stroot;
|
||||
char *p = NULL, *q = NULL;
|
||||
size_t len;
|
||||
|
||||
if (stat(rootdir, &stroot) == -1)
|
||||
return -1;
|
||||
len = strlen(repository);
|
||||
do {
|
||||
if (p != NULL) {
|
||||
len = p - repository;
|
||||
*p = '\0';
|
||||
}
|
||||
if (q != NULL)
|
||||
*q = '/';
|
||||
if (stat(repository, &strep) == -1) {
|
||||
if (p != NULL)
|
||||
*p = '/';
|
||||
return -1;
|
||||
}
|
||||
if (strep.st_dev == stroot.st_dev && strep.st_ino == stroot.st_ino) {
|
||||
if (p != NULL)
|
||||
*p = '/';
|
||||
if (q != NULL)
|
||||
*q = '/';
|
||||
return len;
|
||||
}
|
||||
q = p;
|
||||
} while ((p = strrchr(repository, '/')) != NULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Clean up all outstanding locks
|
||||
*/
|
||||
@ -416,6 +461,9 @@ Reader_Lock (xrepository)
|
||||
FILE *fp;
|
||||
char *tmp;
|
||||
|
||||
if (nolock)
|
||||
return (0);
|
||||
|
||||
if (trace)
|
||||
(void) fprintf (stderr, "%s-> Reader_Lock(%s)\n", CLIENT_SERVER_STR,
|
||||
xrepository);
|
||||
@ -494,6 +542,8 @@ Writer_Lock (list)
|
||||
{
|
||||
char *wait_repos;
|
||||
|
||||
if (nolock)
|
||||
return (0);
|
||||
if (noexec)
|
||||
return 0;
|
||||
|
||||
|
13
gnu/dist/xcvs/src/logmsg.c
vendored
13
gnu/dist/xcvs/src/logmsg.c
vendored
@ -227,6 +227,8 @@ do_editor (dir, messagep, repository, changes)
|
||||
(*messagep)[strlen (*messagep) - 1] != '\n')
|
||||
(void) fprintf (fp, "\n");
|
||||
}
|
||||
else
|
||||
(void) fprintf (fp, "\n");
|
||||
|
||||
if (repository != NULL)
|
||||
/* tack templates on if necessary */
|
||||
@ -298,7 +300,7 @@ do_editor (dir, messagep, repository, changes)
|
||||
run_setup (editinfo_editor ? editinfo_editor : Editor);
|
||||
run_arg (fname);
|
||||
if ((retcode = run_exec (RUN_TTY, RUN_TTY, RUN_TTY,
|
||||
RUN_NORMAL | RUN_SIGIGNORE)) != 0)
|
||||
RUN_NORMAL | RUN_SIGIGNORE | RUN_UNSETXID)) != 0)
|
||||
error (editinfo_editor ? 1 : 0, retcode == -1 ? errno : 0,
|
||||
editinfo_editor ? "Logfile verification failed" :
|
||||
"warning: editor session failed");
|
||||
@ -679,6 +681,15 @@ title_proc (p, closure)
|
||||
strlen (str_list) + strlen (p->key) + 5);
|
||||
(void) strcat (str_list, p->key);
|
||||
break;
|
||||
case 't':
|
||||
str_list =
|
||||
xrealloc (str_list,
|
||||
(strlen (str_list)
|
||||
+ (li->tag ? strlen (li->tag) : 0)
|
||||
+ 10)
|
||||
);
|
||||
(void) strcat (str_list, (li->tag ? li->tag : ""));
|
||||
break;
|
||||
case 'V':
|
||||
str_list =
|
||||
xrealloc (str_list,
|
||||
|
43
gnu/dist/xcvs/src/main.c
vendored
43
gnu/dist/xcvs/src/main.c
vendored
@ -46,6 +46,7 @@ int really_quiet = 0;
|
||||
int quiet = 0;
|
||||
int trace = 0;
|
||||
int noexec = 0;
|
||||
int nolock = 0;
|
||||
int logoff = 0;
|
||||
|
||||
/* Set if we should be writing CVSADM directories at top level. At
|
||||
@ -54,6 +55,10 @@ int logoff = 0;
|
||||
int top_level_admin = 0;
|
||||
|
||||
mode_t cvsumask = UMASK_DFLT;
|
||||
char *RCS_citag = NULL;
|
||||
char *CVS_admin_group = NULL;
|
||||
char *CVS_admin_options = NULL;
|
||||
const char *cvsDir = "CVS";
|
||||
|
||||
char *CurDir;
|
||||
|
||||
@ -243,11 +248,13 @@ static const char *const opt_usage[] =
|
||||
" -r Make checked-out files read-only.\n",
|
||||
" -w Make checked-out files read-write (default).\n",
|
||||
" -n Do not execute anything that will change the disk.\n",
|
||||
" -u Don't create locks (implies -l).\n",
|
||||
" -t Show trace of program execution -- try with -n.\n",
|
||||
" -v CVS version and copyright.\n",
|
||||
" -T tmpdir Use 'tmpdir' for temporary files.\n",
|
||||
" -e editor Use 'editor' for editing log information.\n",
|
||||
" -d CVS_root Overrides $CVSROOT as the root of the CVS tree.\n",
|
||||
" -D dir use DIR as the bookkeeping directory instead of CVS.\n"
|
||||
" -f Do not use the ~/.cvsrc file.\n",
|
||||
#ifdef CLIENT_SUPPORT
|
||||
" -z # Use compression level '#' for net traffic.\n",
|
||||
@ -339,6 +346,10 @@ main_cleanup (sig)
|
||||
#ifndef DONT_USE_SIGNALS
|
||||
const char *name;
|
||||
char temp[10];
|
||||
static int reenter = 0;
|
||||
|
||||
if (reenter++)
|
||||
_exit(1);
|
||||
|
||||
switch (sig)
|
||||
{
|
||||
@ -401,7 +412,7 @@ main (argc, argv)
|
||||
int help = 0; /* Has the user asked for help? This
|
||||
lets us support the `cvs -H cmd'
|
||||
convention to give help for cmd. */
|
||||
static const char short_options[] = "+Qqrwtnvb:T:e:d:Hfz:s:xa";
|
||||
static const char short_options[] = "+Qqrwtnulvb:T:e:d:D:Hfz:s:xa";
|
||||
static struct option long_options[] =
|
||||
{
|
||||
{"help", 0, NULL, 'H'},
|
||||
@ -525,6 +536,9 @@ main (argc, argv)
|
||||
break;
|
||||
case 'n':
|
||||
noexec = 1;
|
||||
case 'u': /* Fall through */
|
||||
nolock = 1;
|
||||
case 'l': /* Fall through */
|
||||
logoff = 1;
|
||||
break;
|
||||
case 'v':
|
||||
@ -613,6 +627,11 @@ distribution kit for a complete list of contributors and copyrights.\n",
|
||||
We will issue an error later if stream
|
||||
authentication is not supported. */
|
||||
break;
|
||||
case 'D':
|
||||
cvsDir = xstrdup(optarg);
|
||||
if (strchr(cvsDir, '/') != NULL)
|
||||
error(1, 0, "cvsDir is not allowed to have slashes");
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
usage (usg);
|
||||
@ -887,7 +906,7 @@ distribution kit for a complete list of contributors and copyrights.\n",
|
||||
/*
|
||||
* Check to see if the repository exists.
|
||||
*/
|
||||
if (!current_parsed_root->isremote)
|
||||
if (!current_parsed_root->isremote && !nolock)
|
||||
{
|
||||
char *path;
|
||||
int save_errno;
|
||||
@ -1121,6 +1140,26 @@ tm_to_internet (dest, source)
|
||||
source->tm_year + 1900, source->tm_hour, source->tm_min, source->tm_sec);
|
||||
}
|
||||
|
||||
const char *
|
||||
getCVSDir(const char *suffix)
|
||||
{
|
||||
static const char *buf[20][2];
|
||||
size_t i, len;
|
||||
for (i = 0; i < 20; i++)
|
||||
{
|
||||
if (buf[i][0] == NULL)
|
||||
break;
|
||||
if (strcmp(buf[i][0], suffix) == 0)
|
||||
return buf[i][1];
|
||||
}
|
||||
if (i == 20)
|
||||
error(1, 0, "Out of static buffer space");
|
||||
buf[i][0] = suffix;
|
||||
buf[i][1] = xmalloc(len = strlen(cvsDir) + strlen(suffix) + 1);
|
||||
snprintf((char *)buf[i][1], len, "%s%s", cvsDir, suffix);
|
||||
return buf[i][1];
|
||||
}
|
||||
|
||||
void
|
||||
usage (cpp)
|
||||
register const char *const *cpp;
|
||||
|
7
gnu/dist/xcvs/src/mkmodules.c
vendored
7
gnu/dist/xcvs/src/mkmodules.c
vendored
@ -313,6 +313,9 @@ static const char *const config_contents[] = {
|
||||
"# repositories. Set it to `never' (the previous CVS behavior) to prevent\n",
|
||||
"# verifymsg scripts from changing the log message.\n",
|
||||
"#RereadLogAfterVerify=always\n",
|
||||
"\n",
|
||||
"# Set this to the name of a local tag to use in addition to Id\n",
|
||||
"#tag=OurTag\n",
|
||||
NULL
|
||||
};
|
||||
|
||||
@ -871,6 +874,10 @@ init (argc, argv)
|
||||
|
||||
umask (cvsumask);
|
||||
|
||||
if (!admin_group_member())
|
||||
error (1, 0, "usage is restricted to members of the group %s",
|
||||
CVS_admin_group);
|
||||
|
||||
if (argc == -1 || argc > 1)
|
||||
usage (init_usage);
|
||||
|
||||
|
3
gnu/dist/xcvs/src/modules.c
vendored
3
gnu/dist/xcvs/src/modules.c
vendored
@ -747,7 +747,8 @@ module `%s' is a request for a file in a module which is not a directory",
|
||||
cvs_output ("'\n", 0);
|
||||
cvs_flushout ();
|
||||
}
|
||||
err += run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL);
|
||||
err += run_exec (RUN_TTY, RUN_TTY, RUN_TTY,
|
||||
RUN_NORMAL | RUN_UNSETXID);
|
||||
free (expanded_path);
|
||||
}
|
||||
if (real_prog) free (real_prog);
|
||||
|
9
gnu/dist/xcvs/src/parseinfo.c
vendored
9
gnu/dist/xcvs/src/parseinfo.c
vendored
@ -357,6 +357,15 @@ parse_config (cvsroot)
|
||||
goto error_return;
|
||||
}
|
||||
}
|
||||
else if (strcmp (line, "tag") == 0) {
|
||||
RCS_citag = xstrdup(p);
|
||||
}
|
||||
else if (strcmp (line, "AdminGroup") == 0) {
|
||||
CVS_admin_group = xstrdup(p);
|
||||
}
|
||||
else if (strcmp (line, "AdminOptions") == 0) {
|
||||
CVS_admin_options = xstrdup(p);
|
||||
}
|
||||
else if (strcmp (line, "PreservePermissions") == 0)
|
||||
{
|
||||
if (strcmp (p, "no") == 0)
|
||||
|
5
gnu/dist/xcvs/src/patch.c
vendored
5
gnu/dist/xcvs/src/patch.c
vendored
@ -803,6 +803,11 @@ patch_dirproc (callerdat, dir, repos, update_dir, entries)
|
||||
static RETSIGTYPE
|
||||
patch_cleanup ()
|
||||
{
|
||||
static int reenter = 0;
|
||||
|
||||
if (reenter++)
|
||||
_exit(1);
|
||||
|
||||
/* Note that the checks for existence_error are because we are
|
||||
called from a signal handler, without SIG_begincrsect, so
|
||||
we don't know whether the files got created. */
|
||||
|
18
gnu/dist/xcvs/src/rcs.c
vendored
18
gnu/dist/xcvs/src/rcs.c
vendored
@ -3534,7 +3534,7 @@ struct rcs_keyword
|
||||
size_t len;
|
||||
};
|
||||
#define KEYWORD_INIT(s) (s), sizeof (s) - 1
|
||||
static const struct rcs_keyword keywords[] =
|
||||
static struct rcs_keyword keywords[] =
|
||||
{
|
||||
{ KEYWORD_INIT ("Author") },
|
||||
{ KEYWORD_INIT ("Date") },
|
||||
@ -3547,6 +3547,7 @@ static const struct rcs_keyword keywords[] =
|
||||
{ KEYWORD_INIT ("Revision") },
|
||||
{ KEYWORD_INIT ("Source") },
|
||||
{ KEYWORD_INIT ("State") },
|
||||
{ NULL, 0 },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
enum keyword
|
||||
@ -3561,7 +3562,8 @@ enum keyword
|
||||
KEYWORD_RCSFILE,
|
||||
KEYWORD_REVISION,
|
||||
KEYWORD_SOURCE,
|
||||
KEYWORD_STATE
|
||||
KEYWORD_STATE,
|
||||
KEYWORD_LOCALID
|
||||
};
|
||||
|
||||
/* Convert an RCS date string into a readable string. This is like
|
||||
@ -3698,6 +3700,11 @@ expand_keywords (rcs, ver, name, log, loglen, expand, buf, len, retbuf, retlen)
|
||||
return;
|
||||
}
|
||||
|
||||
if (RCS_citag != NULL) {
|
||||
keywords[KEYWORD_LOCALID].string = RCS_citag;
|
||||
keywords[KEYWORD_LOCALID].len = strlen(RCS_citag);
|
||||
}
|
||||
|
||||
/* If we are using -kkvl, dig out the locker information if any. */
|
||||
locker = NULL;
|
||||
if (expand == KFLAG_KVL)
|
||||
@ -3789,6 +3796,7 @@ expand_keywords (rcs, ver, name, log, loglen, expand, buf, len, retbuf, retlen)
|
||||
|
||||
case KEYWORD_HEADER:
|
||||
case KEYWORD_ID:
|
||||
case KEYWORD_LOCALID:
|
||||
{
|
||||
const char *path;
|
||||
int free_path;
|
||||
@ -4462,7 +4470,7 @@ RCS_checkout (rcs, workfile, rev, nametag, options, sout, pfn, callerdat)
|
||||
if (info != NULL)
|
||||
{
|
||||
/* If the size of `devtype' changes, fix the sscanf call also */
|
||||
char devtype[16];
|
||||
char devtype[16+1];
|
||||
|
||||
if (sscanf (info->data, "%15s %lu",
|
||||
devtype, &devnum_long) < 2)
|
||||
@ -8464,6 +8472,10 @@ count_delta_actions (np, ignore)
|
||||
RETSIGTYPE
|
||||
rcs_cleanup ()
|
||||
{
|
||||
static int reenter = 0;
|
||||
|
||||
if (reenter++)
|
||||
_exit(1);
|
||||
/* Note that the checks for existence_error are because we are
|
||||
called from a signal handler, so we don't know whether the
|
||||
files got created. */
|
||||
|
6
gnu/dist/xcvs/src/recurse.c
vendored
6
gnu/dist/xcvs/src/recurse.c
vendored
@ -551,7 +551,7 @@ do_recursion (frame)
|
||||
if (frame->flags == R_SKIP_ALL)
|
||||
return (0);
|
||||
|
||||
locktype = noexec ? CVS_LOCK_NONE : frame->locktype;
|
||||
locktype = nolock ? CVS_LOCK_NONE : frame->locktype;
|
||||
|
||||
/* The fact that locks are not active here is what makes us fail to have
|
||||
the
|
||||
@ -1009,8 +1009,8 @@ but CVS uses %s for its own purposes; skipping %s directory",
|
||||
char *cvsadmdir;
|
||||
|
||||
cvsadmdir = xmalloc (strlen (dir)
|
||||
+ sizeof (CVSADM_REP)
|
||||
+ sizeof (CVSADM_ENT)
|
||||
+ strlen (CVSADM_REP)
|
||||
+ strlen (CVSADM_ENT)
|
||||
+ 80);
|
||||
|
||||
strcpy (cvsadmdir, dir);
|
||||
|
6
gnu/dist/xcvs/src/remove.c
vendored
6
gnu/dist/xcvs/src/remove.c
vendored
@ -204,11 +204,7 @@ remove_fileproc (callerdat, finfo)
|
||||
* remove the ,t file for it and scratch it from the
|
||||
* entries file. */
|
||||
Scratch_Entry (finfo->entries, finfo->file);
|
||||
fname = xmalloc (strlen (finfo->file)
|
||||
+ sizeof (CVSADM)
|
||||
+ sizeof (CVSEXT_LOG)
|
||||
+ 10);
|
||||
(void) sprintf (fname, "%s/%s%s", CVSADM, finfo->file, CVSEXT_LOG);
|
||||
(void) xasprintf (&fname, "%s/%s%s", CVSADM, finfo->file, CVSEXT_LOG);
|
||||
if (unlink_file (fname) < 0
|
||||
&& !existence_error (errno))
|
||||
error (0, errno, "cannot remove %s", CVSEXT_LOG);
|
||||
|
10
gnu/dist/xcvs/src/repos.c
vendored
10
gnu/dist/xcvs/src/repos.c
vendored
@ -42,10 +42,7 @@ Name_Repository (dir, update_dir)
|
||||
xupdate_dir = ".";
|
||||
|
||||
if (dir != NULL)
|
||||
{
|
||||
tmp = xmalloc (strlen (dir) + sizeof (CVSADM_REP) + 10);
|
||||
(void) sprintf (tmp, "%s/%s", dir, CVSADM_REP);
|
||||
}
|
||||
(void) xasprintf (&tmp, "%s/%s", dir, CVSADM_REP);
|
||||
else
|
||||
tmp = xstrdup (CVSADM_REP);
|
||||
|
||||
@ -61,10 +58,7 @@ Name_Repository (dir, update_dir)
|
||||
char *cvsadm;
|
||||
|
||||
if (dir != NULL)
|
||||
{
|
||||
cvsadm = xmalloc (strlen (dir) + sizeof (CVSADM) + 10);
|
||||
(void) sprintf (cvsadm, "%s/%s", dir, CVSADM);
|
||||
}
|
||||
(void) xasprintf (&cvsadm, "%s/%s", dir, CVSADM);
|
||||
else
|
||||
cvsadm = xstrdup (CVSADM);
|
||||
|
||||
|
11
gnu/dist/xcvs/src/root.c
vendored
11
gnu/dist/xcvs/src/root.c
vendored
@ -50,10 +50,8 @@ Name_Root (dir, update_dir)
|
||||
|
||||
if (dir != NULL)
|
||||
{
|
||||
cvsadm = xmalloc (strlen (dir) + sizeof (CVSADM) + 10);
|
||||
(void) sprintf (cvsadm, "%s/%s", dir, CVSADM);
|
||||
tmp = xmalloc (strlen (dir) + sizeof (CVSADM_ROOT) + 10);
|
||||
(void) sprintf (tmp, "%s/%s", dir, CVSADM_ROOT);
|
||||
(void) xasprintf (&cvsadm, "%s/%s", dir, CVSADM);
|
||||
(void) xasprintf (&tmp, "%s/%s", dir, CVSADM_ROOT);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -155,10 +153,7 @@ Create_Root (dir, rootdir)
|
||||
if (rootdir != NULL)
|
||||
{
|
||||
if (dir != NULL)
|
||||
{
|
||||
tmp = xmalloc (strlen (dir) + sizeof (CVSADM_ROOT) + 10);
|
||||
(void) sprintf (tmp, "%s/%s", dir, CVSADM_ROOT);
|
||||
}
|
||||
(void) xasprintf (&tmp, "%s/%s", dir, CVSADM_ROOT);
|
||||
else
|
||||
tmp = xstrdup (CVSADM_ROOT);
|
||||
|
||||
|
7
gnu/dist/xcvs/src/run.c
vendored
7
gnu/dist/xcvs/src/run.c
vendored
@ -208,6 +208,13 @@ run_exec (stin, stout, sterr, flags)
|
||||
#endif
|
||||
if (pid == 0)
|
||||
{
|
||||
#ifdef SETXID_SUPPORT
|
||||
if (flags & RUN_UNSETXID) {
|
||||
(void) setgid (getgid ());
|
||||
(void) setuid (getuid ());
|
||||
}
|
||||
#endif
|
||||
|
||||
if (shin != 0)
|
||||
{
|
||||
(void) dup2 (shin, 0);
|
||||
|
37
gnu/dist/xcvs/src/server.c
vendored
37
gnu/dist/xcvs/src/server.c
vendored
@ -782,6 +782,7 @@ E Protocol error: Root says \"%s\" but pserver says \"%s\"",
|
||||
nothing. But for rsh, we need to do it now. */
|
||||
parse_config (current_parsed_root->directory);
|
||||
|
||||
if (!nolock) {
|
||||
path = xmalloc (strlen (current_parsed_root->directory)
|
||||
+ sizeof (CVSROOTADM)
|
||||
+ 2);
|
||||
@ -799,6 +800,7 @@ E Protocol error: Root says \"%s\" but pserver says \"%s\"",
|
||||
pending_error = save_errno;
|
||||
}
|
||||
free (path);
|
||||
}
|
||||
|
||||
#ifdef HAVE_PUTENV
|
||||
env = xmalloc (strlen (CVSROOT_ENV) + strlen (current_parsed_root->directory) + 2);
|
||||
@ -2285,6 +2287,9 @@ serve_global_option (arg)
|
||||
noexec = 1;
|
||||
logoff = 1;
|
||||
break;
|
||||
case 'u':
|
||||
nolock = 1;
|
||||
break;
|
||||
case 'q':
|
||||
quiet = 1;
|
||||
break;
|
||||
@ -4796,6 +4801,8 @@ struct request requests[] =
|
||||
REQ_LINE("Max-dotdot", serve_max_dotdot, 0),
|
||||
REQ_LINE("Static-directory", serve_static_directory, 0),
|
||||
REQ_LINE("Sticky", serve_sticky, 0),
|
||||
REQ_LINE("Checkin-prog", serve_noop, 0),
|
||||
REQ_LINE("Update-prog", serve_noop, 0),
|
||||
REQ_LINE("Entry", serve_entry, RQ_ESSENTIAL),
|
||||
REQ_LINE("Kopt", serve_kopt, 0),
|
||||
REQ_LINE("Checkin-time", serve_checkin_time, 0),
|
||||
@ -5306,6 +5313,7 @@ switch_to_user (cvs_username, username)
|
||||
const char *username;
|
||||
{
|
||||
struct passwd *pw;
|
||||
int rc;
|
||||
|
||||
pw = getpwnam (username);
|
||||
if (pw == NULL)
|
||||
@ -5384,7 +5392,14 @@ error 0 %s: no such system user\n", username);
|
||||
}
|
||||
}
|
||||
|
||||
if (setuid (pw->pw_uid) < 0)
|
||||
#ifdef SETXID_SUPPORT
|
||||
/* Honor the setuid bit iff set. */
|
||||
if (getuid() != geteuid())
|
||||
rc = setuid (geteuid ());
|
||||
else
|
||||
#endif
|
||||
rc = setuid (pw->pw_uid);
|
||||
if (rc < 0)
|
||||
{
|
||||
/* Note that this means that if run as a non-root user,
|
||||
CVSROOT/passwd must contain the user we are running as
|
||||
@ -5953,19 +5968,20 @@ kserver_authenticate_connection ()
|
||||
{
|
||||
int status;
|
||||
char instance[INST_SZ];
|
||||
struct sockaddr_in peer;
|
||||
struct sockaddr_in laddr;
|
||||
int len;
|
||||
struct sockaddr_storage peer;
|
||||
struct sockaddr_storage laddr;
|
||||
int plen, llen;
|
||||
KTEXT_ST ticket;
|
||||
AUTH_DAT auth;
|
||||
char version[KRB_SENDAUTH_VLEN];
|
||||
char user[ANAME_SZ];
|
||||
|
||||
strcpy (instance, "*");
|
||||
len = sizeof peer;
|
||||
if (getpeername (STDIN_FILENO, (struct sockaddr *) &peer, &len) < 0
|
||||
plen = sizeof peer;
|
||||
llen = sizeof laddr;
|
||||
if (getpeername (STDIN_FILENO, (struct sockaddr *) &peer, &plen) < 0
|
||||
|| getsockname (STDIN_FILENO, (struct sockaddr *) &laddr,
|
||||
&len) < 0)
|
||||
&llen) < 0)
|
||||
{
|
||||
printf ("E Fatal error, aborting.\n\
|
||||
error %s getpeername or getsockname failed\n", strerror (errno));
|
||||
@ -5990,7 +6006,8 @@ error %s getpeername or getsockname failed\n", strerror (errno));
|
||||
#endif
|
||||
|
||||
status = krb_recvauth (KOPT_DO_MUTUAL, STDIN_FILENO, &ticket, "rcmd",
|
||||
instance, &peer, &laddr, &auth, "", sched,
|
||||
instance, (struct sockaddr_in *)&peer,
|
||||
(struct sockaddr_in *)&laddr, &auth, "", sched,
|
||||
version);
|
||||
if (status != KSUCCESS)
|
||||
{
|
||||
@ -6342,7 +6359,7 @@ krb_encrypt_input (fnclosure, input, output, size)
|
||||
struct krb_encrypt_data *kd = (struct krb_encrypt_data *) fnclosure;
|
||||
int tcount;
|
||||
|
||||
des_cbc_encrypt ((C_Block *) input, (C_Block *) output,
|
||||
des_cbc_encrypt ((char *) input, (char *) output,
|
||||
size, kd->sched, &kd->block, 0);
|
||||
|
||||
/* SIZE is the size of the buffer, which is set by the encryption
|
||||
@ -6389,7 +6406,7 @@ krb_encrypt_output (fnclosure, input, output, size, translated)
|
||||
fail over a long network connection. We trust krb_recvauth to
|
||||
guard against a replay attack. */
|
||||
|
||||
des_cbc_encrypt ((C_Block *) input, (C_Block *) output, aligned,
|
||||
des_cbc_encrypt ((char *) input, (char *) output, aligned,
|
||||
kd->sched, &kd->block, 1);
|
||||
|
||||
*translated = aligned;
|
||||
|
16
gnu/dist/xcvs/src/subr.c
vendored
16
gnu/dist/xcvs/src/subr.c
vendored
@ -16,6 +16,7 @@
|
||||
#include <assert.h>
|
||||
#include "cvs.h"
|
||||
#include "getline.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef HAVE_NANOSLEEP
|
||||
# include "xtime.h"
|
||||
@ -81,6 +82,21 @@ xrealloc (ptr, bytes)
|
||||
return (cp);
|
||||
}
|
||||
|
||||
int
|
||||
xasprintf(char **buf, const char *fmt, ...)
|
||||
{
|
||||
int len;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
len = vasprintf(buf, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (len == -1)
|
||||
error(1, 0, "out of memory: xasprintf(..., \"%s\", ...) failed", fmt);
|
||||
return len;
|
||||
}
|
||||
|
||||
/* Two constants which tune expand_string. Having MIN_INCR as large
|
||||
as 1024 might waste a bit of memory, but it shouldn't be too bad
|
||||
(CVS used to allocate arrays of, say, 3000, PATH_MAX (8192, often),
|
||||
|
2
gnu/dist/xcvs/src/tag.c
vendored
2
gnu/dist/xcvs/src/tag.c
vendored
@ -1411,8 +1411,6 @@ Numeric tag %s contains characters other than digits and '.'", name);
|
||||
add_to_val_tags (name);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Check whether a join tag is valid. This is just like
|
||||
* tag_check_valid, but we must stop before the colon if there is one.
|
||||
|
36
gnu/dist/xcvs/src/update.c
vendored
36
gnu/dist/xcvs/src/update.c
vendored
@ -977,8 +977,7 @@ update_dirent_proc (callerdat, dir, repository, update_dir, entries)
|
||||
{
|
||||
char *tmp;
|
||||
|
||||
tmp = xmalloc (strlen (dir) + sizeof (CVSADM_ENTSTAT) + 10);
|
||||
(void) sprintf (tmp, "%s/%s", dir, CVSADM_ENTSTAT);
|
||||
(void) xasprintf (&tmp, "%s/%s", dir, CVSADM_ENTSTAT);
|
||||
if (unlink_file (tmp) < 0 && ! existence_error (errno))
|
||||
error (1, errno, "cannot remove file %s", tmp);
|
||||
#ifdef SERVER_SUPPORT
|
||||
@ -1234,11 +1233,7 @@ checkout_file (finfo, vers_ts, adding, merging, update_server)
|
||||
we are the server. */
|
||||
if (!pipeout && !server_active)
|
||||
{
|
||||
backup = xmalloc (strlen (finfo->file)
|
||||
+ sizeof (CVSADM)
|
||||
+ sizeof (CVSPREFIX)
|
||||
+ 10);
|
||||
(void) sprintf (backup, "%s/%s%s", CVSADM, CVSPREFIX, finfo->file);
|
||||
(void) xasprintf (&backup, "%s/%s%s", CVSADM, CVSPREFIX, finfo->file);
|
||||
if (isfile (finfo->file))
|
||||
rename_file (finfo->file, backup);
|
||||
else
|
||||
@ -1341,11 +1336,18 @@ VERS: ", 0);
|
||||
xchmod (finfo->file, 1);
|
||||
else
|
||||
{
|
||||
mode_t oumask, writeaccess;
|
||||
|
||||
/* We know that we are the server here, so
|
||||
although xchmod checks umask, we don't bother. */
|
||||
mode |= (((mode & S_IRUSR) ? S_IWUSR : 0)
|
||||
/* Not bothering with the umask makes the files
|
||||
mode 0777 on old clients, though. -chb */
|
||||
oumask = umask(0);
|
||||
(void) umask(oumask);
|
||||
writeaccess = (((mode & S_IRUSR) ? S_IWUSR : 0)
|
||||
| ((mode & S_IRGRP) ? S_IWGRP : 0)
|
||||
| ((mode & S_IROTH) ? S_IWOTH : 0));
|
||||
mode |= (~oumask) & writeaccess;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1605,11 +1607,7 @@ patch_file (finfo, vers_ts, docheckout, file_info, checksum)
|
||||
return 0;
|
||||
}
|
||||
|
||||
backup = xmalloc (strlen (finfo->file)
|
||||
+ sizeof (CVSADM)
|
||||
+ sizeof (CVSPREFIX)
|
||||
+ 10);
|
||||
(void) sprintf (backup, "%s/%s%s", CVSADM, CVSPREFIX, finfo->file);
|
||||
(void) xasprintf (&backup, "%s/%s%s", CVSADM, CVSPREFIX, finfo->file);
|
||||
if (isfile (finfo->file))
|
||||
rename_file (finfo->file, backup);
|
||||
else
|
||||
@ -1619,16 +1617,8 @@ patch_file (finfo, vers_ts, docheckout, file_info, checksum)
|
||||
error (0, errno, "cannot remove %s", backup);
|
||||
}
|
||||
|
||||
file1 = xmalloc (strlen (finfo->file)
|
||||
+ sizeof (CVSADM)
|
||||
+ sizeof (CVSPREFIX)
|
||||
+ 10);
|
||||
(void) sprintf (file1, "%s/%s%s-1", CVSADM, CVSPREFIX, finfo->file);
|
||||
file2 = xmalloc (strlen (finfo->file)
|
||||
+ sizeof (CVSADM)
|
||||
+ sizeof (CVSPREFIX)
|
||||
+ 10);
|
||||
(void) sprintf (file2, "%s/%s%s-2", CVSADM, CVSPREFIX, finfo->file);
|
||||
(void) xasprintf (&file1, "%s/%s%s-1", CVSADM, CVSPREFIX, finfo->file);
|
||||
(void) xasprintf (&file2, "%s/%s%s-2", CVSADM, CVSPREFIX, finfo->file);
|
||||
|
||||
fail = 0;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user