version 1.99, 2006/11/09 21:47:52 |
version 1.100, 2006/11/10 16:31:29 |
|
|
#include "includes.h" |
#include "includes.h" |
|
|
#include "rcsprog.h" |
#include "rcsprog.h" |
|
#include "diff.h" |
|
|
#define CO_OPTSTRING "d:f::I::k:l::M::p::q::r::s:Tu::Vw::x::z::" |
#define CO_OPTSTRING "d:f::I::k:l::M::p::q::r::s:Tu::Vw::x::z::" |
|
|
static void checkout_err_nobranch(RCSFILE *, const char *, const char *, |
static void checkout_err_nobranch(RCSFILE *, const char *, const char *, |
const char *, int); |
const char *, int); |
|
static int checkout_file_has_diffs(RCSFILE *, RCSNUM *, const char *); |
|
|
int |
int |
checkout_main(int argc, char **argv) |
checkout_main(int argc, char **argv) |
|
|
struct rcs_delta *rdp; |
struct rcs_delta *rdp; |
struct rcs_lock *lkp; |
struct rcs_lock *lkp; |
char *fdate; |
char *fdate; |
|
const char *fstatus; |
time_t rcsdate, givendate; |
time_t rcsdate, givendate; |
RCSNUM *rev; |
RCSNUM *rev; |
|
|
|
|
file->rf_path, lcount); |
file->rf_path, lcount); |
} |
} |
|
|
if (!(flags & PIPEOUT) && stat(dst, &st) != -1 && !(flags & FORCE)) { |
if ((flags & (PIPEOUT|FORCE)) == 0 && stat(dst, &st) != -1) { |
/* |
/* |
* XXX - Not sure what is "right". If we go according |
* Prompt the user if the file is writable or the file is |
* to GNU's behavior, an existing file with no writable |
* not writable but is different from the RCS head version. |
* bits is overwritten without prompting the user. |
* This is different from GNU which will silently overwrite |
* |
* the file regardless of its contents so long as it is |
* This is dangerous, so we always prompt. |
* read-only. |
* Unfortunately this interferes with an unlocked |
|
* checkout followed by a locked checkout, which should |
|
* not prompt. One (unimplemented) solution is to check |
|
* if the existing file is the same as the checked out |
|
* revision, and prompt if there are differences. |
|
*/ |
*/ |
if (st.st_mode & (S_IWUSR|S_IWGRP|S_IWOTH)) |
if (st.st_mode & (S_IWUSR|S_IWGRP|S_IWOTH)) |
(void)fprintf(stderr, "writable "); |
fstatus = "writable"; |
(void)fprintf(stderr, "%s exists%s; ", dst, |
else if (checkout_file_has_diffs(file, frev, dst) != D_SAME) |
(getuid() == st.st_uid) ? "" : |
fstatus = "modified"; |
", and you do not own it"); |
else |
(void)fprintf(stderr, "remove it? [ny](n): "); |
fstatus = NULL; |
if (rcs_yesno('n') == 'n') { |
if (fstatus) { |
if (!(flags & QUIET) && isatty(STDIN_FILENO)) |
(void)fprintf(stderr, "%s %s exists%s; ", fstatus, dst, |
warnx("%s%s exists; checkout aborted", |
(getuid() == st.st_uid) ? "" : |
(st.st_mode & (S_IWUSR|S_IWGRP|S_IWOTH)) ? |
", and you do not own it"); |
"writable " : "", dst); |
(void)fprintf(stderr, "remove it? [ny](n): "); |
else |
if (rcs_yesno('n') == 'n') { |
warnx("checkout aborted"); |
if (!(flags & QUIET) && isatty(STDIN_FILENO)) |
return (-1); |
warnx("%s %s exists; checkout aborted", |
|
fstatus, dst); |
|
else |
|
warnx("checkout aborted"); |
|
return (-1); |
|
} |
} |
} |
} |
} |
|
|
|
|
author ? author : "", |
author ? author : "", |
state ? " and state " + (date || author ? 0:4) : "", |
state ? " and state " + (date || author ? 0:4) : "", |
state ? state : ""); |
state ? state : ""); |
|
} |
|
|
|
/* |
|
* checkout_file_has_diffs() |
|
* |
|
* Check for diffs between the working file and its current revision. |
|
* Same return values as rcs_diffreg() |
|
*/ |
|
static int |
|
checkout_file_has_diffs(RCSFILE *rfp, RCSNUM *frev, const char *dst) |
|
{ |
|
char *tempfile; |
|
BUF *bp; |
|
int ret; |
|
|
|
tempfile = NULL; |
|
|
|
if ((bp = rcs_getrev(rfp, frev)) == NULL) { |
|
warnx("failed to load revision"); |
|
return (D_ERROR); |
|
} |
|
|
|
(void)xasprintf(&tempfile, "%s/diff.XXXXXXXXXX", rcs_tmpdir); |
|
rcs_buf_write_stmp(bp, tempfile); |
|
rcs_buf_empty(bp); |
|
|
|
diff_format = D_RCSDIFF; |
|
ret = rcs_diffreg(dst, tempfile, bp, 0); |
|
|
|
rcs_buf_free(bp); |
|
unlink(tempfile); |
|
xfree(tempfile); |
|
|
|
return (ret); |
} |
} |