version 1.23, 2005/10/25 17:27:54 |
version 1.24, 2005/11/02 20:32:45 |
|
|
#include "rcs.h" |
#include "rcs.h" |
#include "rcsprog.h" |
#include "rcsprog.h" |
|
|
#define LOCK_LOCK 1 |
static int checkout_state(RCSFILE *, RCSNUM *, const char *, int, |
#define LOCK_UNLOCK 2 |
const char *, const char *); |
|
|
int |
int |
checkout_main(int argc, char **argv) |
checkout_main(int argc, char **argv) |
{ |
{ |
int i, ch; |
int i, ch; |
int fflag, lock; |
int flags; |
RCSNUM *frev, *rev; |
RCSNUM *frev, *rev; |
RCSFILE *file; |
RCSFILE *file; |
char fpath[MAXPATHLEN], buf[16]; |
char fpath[MAXPATHLEN], buf[16]; |
char *username; |
char *username; |
|
const char *state = NULL; |
|
|
fflag = lock = 0; |
flags = 0; |
rev = RCS_HEAD_REV; |
rev = RCS_HEAD_REV; |
frev = NULL; |
frev = NULL; |
|
|
|
|
exit (1); |
exit (1); |
} |
} |
|
|
while ((ch = rcs_getopt(argc, argv, "f::l::p::qr::u::V")) != -1) { |
while ((ch = rcs_getopt(argc, argv, "f::l::p::qr::s:u::V")) != -1) { |
switch (ch) { |
switch (ch) { |
case 'f': |
case 'f': |
rcs_set_rev(rcs_optarg, &rev); |
rcs_set_rev(rcs_optarg, &rev); |
fflag = 1; |
flags |= FORCE; |
break; |
break; |
case 'l': |
case 'l': |
rcs_set_rev(rcs_optarg, &rev); |
rcs_set_rev(rcs_optarg, &rev); |
lock = LOCK_LOCK; |
flags |= CO_LOCK; |
break; |
break; |
case 'p': |
case 'p': |
rcs_set_rev(rcs_optarg, &rev); |
rcs_set_rev(rcs_optarg, &rev); |
|
|
case 'r': |
case 'r': |
rcs_set_rev(rcs_optarg, &rev); |
rcs_set_rev(rcs_optarg, &rev); |
break; |
break; |
|
case 's': |
|
if ((state = strdup(rcs_optarg)) == NULL) { |
|
cvs_log(LP_ERRNO, "out of memory"); |
|
exit(1); |
|
} |
|
flags |= CO_STATE; |
|
break; |
case 'u': |
case 'u': |
rcs_set_rev(rcs_optarg, &rev); |
rcs_set_rev(rcs_optarg, &rev); |
lock = LOCK_UNLOCK; |
flags |= CO_UNLOCK; |
break; |
break; |
case 'V': |
case 'V': |
printf("%s\n", rcs_version); |
printf("%s\n", rcs_version); |
|
|
|
|
rcsnum_tostr(frev, buf, sizeof(buf)); |
rcsnum_tostr(frev, buf, sizeof(buf)); |
|
|
if (checkout_rev(file, frev, argv[i], lock, |
if (flags & CO_STATE) { |
username, fflag) < 0) { |
if (checkout_state(file, frev, argv[i], flags, |
rcs_close(file); |
username, state) < 0) { |
continue; |
rcs_close(file); |
|
continue; |
|
} |
} |
} |
|
else { |
|
if (checkout_rev(file, frev, argv[i], flags, |
|
username) < 0) { |
|
rcs_close(file); |
|
continue; |
|
} |
|
} |
|
|
rcs_close(file); |
rcs_close(file); |
} |
} |
|
|
checkout_usage(void) |
checkout_usage(void) |
{ |
{ |
fprintf(stderr, |
fprintf(stderr, |
"usage: co [-qV] [-l[rev]] [-r[rev]] [-u[rev]] file ...\n"); |
"usage: co [-qV] [-l[rev]] [-p[rev]] [-r[rev]] [-sstate]\n" |
|
" [-u[rev]] file ...\n"); |
} |
} |
|
|
/* |
/* |
|
|
* Returns 0 on success, -1 on failure. |
* Returns 0 on success, -1 on failure. |
*/ |
*/ |
int |
int |
checkout_rev(RCSFILE *file, RCSNUM *frev, const char *dst, int lkmode, |
checkout_rev(RCSFILE *file, RCSNUM *frev, const char *dst, int flags, |
const char *username, int force) |
const char *username) |
{ |
{ |
char buf[16], yn; |
char buf[16], yn; |
mode_t mode = 0444; |
mode_t mode = 0444; |
|
|
return (-1); |
return (-1); |
} |
} |
|
|
if (lkmode == LOCK_LOCK) { |
if (flags & CO_LOCK) { |
if ((username != NULL) |
if ((username != NULL) |
&& (rcs_lock_add(file, username, frev) < 0)) { |
&& (rcs_lock_add(file, username, frev) < 0)) { |
if ((rcs_errno != RCS_ERR_DUPENT) && (verbose == 1)) |
if ((rcs_errno != RCS_ERR_DUPENT) && (verbose == 1)) |
|
|
mode = 0644; |
mode = 0644; |
if (verbose == 1) |
if (verbose == 1) |
printf(" (locked)"); |
printf(" (locked)"); |
} else if (lkmode == LOCK_UNLOCK) { |
} else if (flags & CO_UNLOCK) { |
if (rcs_lock_remove(file, frev) < 0) { |
if (rcs_lock_remove(file, frev) < 0) { |
if (rcs_errno != RCS_ERR_NOENT) |
if (rcs_errno != RCS_ERR_NOENT) |
cvs_log(LP_ERR, |
cvs_log(LP_ERR, |
|
|
if (verbose == 1) |
if (verbose == 1) |
printf("\n"); |
printf("\n"); |
|
|
if ((stat(dst, &st) != -1) && force == 0) { |
if ((stat(dst, &st) != -1) && !(flags & FORCE)) { |
if (st.st_mode & S_IWUSR) { |
if (st.st_mode & S_IWUSR) { |
yn = 0; |
yn = 0; |
if (verbose == 0) { |
if (verbose == 0) { |
|
|
return (-1); |
return (-1); |
} |
} |
cvs_buf_free(bp); |
cvs_buf_free(bp); |
|
if (flags & CO_REVDATE) { |
|
struct timeval tv[2]; |
|
bzero(&tv, sizeof(tv)); |
|
tv[0].tv_sec = (long)rcs_rev_getdate(file, frev); |
|
tv[1].tv_sec = tv[0].tv_sec; |
|
if (utimes(dst, (const struct timeval *)&tv) < 0) |
|
cvs_log(LP_ERRNO, "error setting utimes"); |
|
} |
|
|
if (verbose == 1) |
if (verbose == 1) |
printf("done\n"); |
printf("done\n"); |
|
|
return (0); |
return (0); |
} |
} |
|
|
|
/* |
|
* checkout_state() |
|
* |
|
* Search from supplied revision backwards until we find one |
|
* with state <state> and check that out. |
|
* |
|
* Returns 0 on success, -1 on checkout_rev failure and -2 if there is no |
|
* such state. |
|
*/ |
|
static int |
|
checkout_state(RCSFILE *rfp, RCSNUM *rev, const char *dst, int flags, |
|
const char *username, const char *state) |
|
{ |
|
const char *tstate; |
|
|
|
if (rev == NULL) { |
|
cvs_log(LP_ERR, "%s: No revision on branch has state %s", |
|
rfp->rf_path, state); |
|
return (-1); |
|
} |
|
else { |
|
if (((tstate = rcs_state_get(rfp, rev)) != NULL) |
|
&& (strcmp(state, tstate) == 0)) |
|
return (checkout_rev(rfp, rev, dst, flags, username)); |
|
else |
|
rev = rcsnum_dec(rev); |
|
return (checkout_state(rfp, rev, dst, flags, username, state)); |
|
} |
|
} |