version 1.3, 2005/09/30 17:39:48 |
version 1.4, 2005/10/07 23:59:56 |
|
|
|
|
#include "log.h" |
#include "log.h" |
#include "rcs.h" |
#include "rcs.h" |
|
#include "diff.h" |
#include "rcsprog.h" |
#include "rcsprog.h" |
|
|
extern char *__progname; |
extern char *__progname; |
|
|
|
static char * checkin_diff_file(RCSFILE *, RCSNUM *, const char *); |
|
|
void |
void |
checkin_usage(void) |
checkin_usage(void) |
{ |
{ |
|
|
int i, ch, dflag, flags, lkmode; |
int i, ch, dflag, flags, lkmode; |
mode_t fmode; |
mode_t fmode; |
RCSFILE *file; |
RCSFILE *file; |
|
RCSNUM *frev; |
char fpath[MAXPATHLEN]; |
char fpath[MAXPATHLEN]; |
char *rcs_msg, *rev; |
char *rcs_msg, *rev, *filec, *deltatext; |
|
BUF *bp; |
|
|
lkmode = -1; |
lkmode = -1; |
flags = RCS_RDWR; |
flags = RCS_RDWR; |
file = NULL; |
file = NULL; |
rev = rcs_msg = NULL; |
rcs_msg = rev = NULL; |
fmode = dflag = 0; |
fmode = dflag = 0; |
|
|
while ((ch = getopt(argc, argv, "j:l:M:N:qu:d:r::m:k:V")) != -1) { |
while ((ch = getopt(argc, argv, "j:l:M:N:qu:d:r::m:k:V")) != -1) { |
|
|
case 'h': |
case 'h': |
(usage)(); |
(usage)(); |
exit(0); |
exit(0); |
case 'l': |
|
lkmode = RCS_LOCK_STRICT; |
|
break; |
|
case 'm': |
case 'm': |
rcs_msg = optarg; |
rcs_msg = optarg; |
break; |
break; |
case 'q': |
case 'q': |
verbose = 0; |
verbose = 0; |
break; |
break; |
case 'r': |
|
rev = optarg; |
|
break; |
|
case 'V': |
case 'V': |
printf("%s\n", rcs_version); |
printf("%s\n", rcs_version); |
exit(0); |
exit(0); |
|
|
if (rcs_statfile(argv[i], fpath, sizeof(fpath)) < 0) |
if (rcs_statfile(argv[i], fpath, sizeof(fpath)) < 0) |
continue; |
continue; |
|
|
flags = RCS_RDWR; |
file = rcs_open(fpath, RCS_RDWR, fmode); |
file = rcs_open(fpath, flags, fmode); |
|
if (file == NULL) { |
if (file == NULL) { |
|
cvs_log(LP_ERR, "failed to open rcsfile '%s'", fpath); |
exit(1); |
exit(1); |
} |
} |
|
|
if (rcs_msg == NULL) { |
if (rcs_msg == NULL) { |
cvs_log(LP_ERR, "no log message"); |
cvs_log(LP_ERR, "no log message"); |
exit(1); |
exit(1); |
} |
} |
if (rev != NULL ) { |
|
/* XXX */ |
if (dflag) { |
} else { |
|
if (dflag) { |
|
/* XXX */ |
/* XXX */ |
} else { |
|
if (rcs_rev_add(file, RCS_HEAD_REV, rcs_msg, -1) |
|
!= 0) { |
|
cvs_log(LP_ERR, |
|
"rcs_rev_add() failure"); |
|
exit(1); |
|
} |
|
} |
|
} |
} |
|
|
|
if (rev == NULL) |
|
frev = file->rf_head; |
|
|
|
/* |
|
* Load file contents |
|
*/ |
|
if ((bp = cvs_buf_load(argv[i], BUF_AUTOEXT)) == NULL) { |
|
cvs_log(LP_ERR, "failed to load '%s'", argv[i]); |
|
exit(1); |
|
} |
|
|
|
if (cvs_buf_putc(bp, '\0') < 0) |
|
exit(1); |
|
|
|
filec = cvs_buf_release(bp); |
|
|
|
/* |
|
* Remove the lock |
|
*/ |
|
if (rcs_lock_remove(file, frev) < 0) { |
|
if (rcs_errno != RCS_ERR_NOENT) |
|
cvs_log(LP_WARN, "failed to remove lock"); |
|
} |
|
|
|
/* |
|
* Get RCS patch |
|
*/ |
|
if ((deltatext = checkin_diff_file(file, frev, argv[i])) == NULL) { |
|
cvs_log(LP_ERR, "failed to get diff"); |
|
exit(1); |
|
} |
|
|
|
/* |
|
* Current head revision gets the RCS patch as rd_text |
|
*/ |
|
if (rcs_deltatext_set(file, file->rf_head, deltatext) == -1) { |
|
cvs_log(LP_ERR, "failed to set new rd_text for head rev"); |
|
exit (1); |
|
} |
|
|
|
/* |
|
* Now add our new revision |
|
*/ |
|
if (rcs_rev_add(file, RCS_HEAD_REV, rcs_msg, -1) != 0) { |
|
cvs_log(LP_ERR, "failed to add new revision"); |
|
exit(1); |
|
} |
|
|
|
/* |
|
* New head revision has to contain entire file; |
|
*/ |
|
if (rcs_deltatext_set(file, frev, filec) == -1) { |
|
cvs_log(LP_ERR, "failed to set new head revision"); |
|
exit(1); |
|
} |
|
|
|
free(deltatext); |
|
free(filec); |
|
|
|
/* File will NOW be synced */ |
rcs_close(file); |
rcs_close(file); |
|
|
|
/* XXX: |
|
* Delete the working file - we do not support -u/-l just yet |
|
*/ |
|
(void)unlink(argv[i]); |
} |
} |
|
|
exit(0); |
return (0); |
|
} |
|
|
|
static char * |
|
checkin_diff_file(RCSFILE *rfp, RCSNUM *rev, const char *filename) |
|
{ |
|
char path1[MAXPATHLEN], path2[MAXPATHLEN]; |
|
BUF *b1, *b2, *b3; |
|
char rbuf[64], *deltatext; |
|
|
|
rcsnum_tostr(rev, rbuf, sizeof(rbuf)); |
|
if (verbose) |
|
printf("retrieving revision %s\n", rbuf); |
|
|
|
if ((b1 = cvs_buf_load(filename, BUF_AUTOEXT)) == NULL) { |
|
cvs_log(LP_ERR, "failed to load file: '%s'", filename); |
|
return (NULL); |
|
} |
|
|
|
if ((b2 = rcs_getrev(rfp, rev)) == NULL) { |
|
cvs_log(LP_ERR, "failed to load revision"); |
|
cvs_buf_free(b1); |
|
return (NULL); |
|
} |
|
|
|
if ((b3 = cvs_buf_alloc(128, BUF_AUTOEXT)) == NULL) { |
|
cvs_log(LP_ERR, "failed to allocated buffer for diff"); |
|
cvs_buf_free(b1); |
|
cvs_buf_free(b2); |
|
return (NULL); |
|
} |
|
|
|
strlcpy(path1, "/tmp/diff1.XXXXXXXXXX", sizeof(path1)); |
|
if (cvs_buf_write_stmp(b1, path1, 0600) == -1) { |
|
cvs_log(LP_ERRNO, "could not write temporary file"); |
|
cvs_buf_free(b1); |
|
cvs_buf_free(b2); |
|
return (NULL); |
|
} |
|
cvs_buf_free(b1); |
|
|
|
strlcpy(path2, "/tmp/diff2.XXXXXXXXXX", sizeof(path2)); |
|
if (cvs_buf_write_stmp(b2, path2, 0600) == -1) { |
|
cvs_buf_free(b2); |
|
(void)unlink(path1); |
|
return (NULL); |
|
} |
|
cvs_buf_free(b2); |
|
|
|
diff_format = D_RCSDIFF; |
|
cvs_diffreg(path1, path2, b3); |
|
(void)unlink(path1); |
|
(void)unlink(path2); |
|
|
|
cvs_buf_putc(b3, '\0'); |
|
deltatext = (char *)cvs_buf_release(b3); |
|
|
|
return (deltatext); |
} |
} |