version 1.7, 2004/12/07 17:10:56 |
version 1.8, 2004/12/08 17:22:48 |
|
|
#define CVS_LOGMSG_BIGMSG 32000 |
#define CVS_LOGMSG_BIGMSG 32000 |
#define CVS_LOGMSG_FTMPL "/tmp/cvsXXXXXXXXXX" |
#define CVS_LOGMSG_FTMPL "/tmp/cvsXXXXXXXXXX" |
#define CVS_LOGMSG_PREFIX "CVS:" |
#define CVS_LOGMSG_PREFIX "CVS:" |
#define CVS_LOGMSG_LOGLINE \ |
#define CVS_LOGMSG_LINE \ |
"----------------------------------------------------------------------" |
"----------------------------------------------------------------------" |
|
|
|
|
|
static const char *cvs_logmsg_ops[3] = { |
|
"Added", "Modified", "Removed", |
|
}; |
|
|
|
|
/* |
/* |
* cvs_logmsg_open() |
* cvs_logmsg_open() |
* |
* |
|
|
/* |
/* |
* cvs_logmsg_get() |
* cvs_logmsg_get() |
* |
* |
* Get a log message by forking and executing the user's editor. |
* Get a log message by forking and executing the user's editor. The <dir> |
|
* argument is a relative path to the directory for which the log message |
|
* applies, and the 3 tail queue arguemnts contains all the files for which the |
|
* log message will apply. Any of these arguments can be set to NULL in the |
|
* case where there is no information to display. |
* Returns the message in a dynamically allocated string on success, NULL on |
* Returns the message in a dynamically allocated string on success, NULL on |
* failure. |
* failure. |
*/ |
*/ |
char* |
char* |
cvs_logmsg_get(const char *dir, struct cvs_flist *files) |
cvs_logmsg_get(const char *dir, struct cvs_flist *added, |
|
struct cvs_flist *modified, struct cvs_flist *removed) |
{ |
{ |
int ret, fd, argc, fds[3], nl; |
int i, fd, argc, fds[3], nl; |
size_t len, tlen; |
size_t len, tlen; |
char *argv[4], buf[16], path[MAXPATHLEN], fpath[MAXPATHLEN], *msg; |
char *argv[4], buf[16], path[MAXPATHLEN], fpath[MAXPATHLEN], *msg; |
FILE *fp; |
FILE *fp; |
CVSFILE *cvsfp; |
CVSFILE *cvsfp; |
struct stat st1, st2; |
struct stat st1, st2; |
|
struct cvs_flist *files[3]; |
|
|
|
files[0] = added; |
|
files[1] = modified; |
|
files[2] = removed; |
|
|
msg = NULL; |
msg = NULL; |
fds[0] = -1; |
fds[0] = -1; |
fds[1] = -1; |
fds[1] = -1; |
|
|
if (unlink(path) == -1) |
if (unlink(path) == -1) |
cvs_log(LP_ERRNO, "failed to unlink temporary file"); |
cvs_log(LP_ERRNO, "failed to unlink temporary file"); |
return (NULL); |
return (NULL); |
} else { |
} |
fprintf(fp, |
|
"\n%s %s\n%s Enter Log. Lines beginning with `%s' are " |
|
"removed automatically\n%s\n%s Commiting in %s\n" |
|
"%s\n", |
|
CVS_LOGMSG_PREFIX, CVS_LOGMSG_LOGLINE, |
|
CVS_LOGMSG_PREFIX, CVS_LOGMSG_PREFIX, |
|
CVS_LOGMSG_PREFIX, CVS_LOGMSG_PREFIX, |
|
dir, CVS_LOGMSG_PREFIX); |
|
|
|
/* XXX list files here */ |
fprintf(fp, "\n%s %s\n%s Enter Log. Lines beginning with `%s' are " |
fprintf(fp, "%s Modified Files:", CVS_LOGMSG_PREFIX); |
"removed automatically\n%s\n", CVS_LOGMSG_PREFIX, CVS_LOGMSG_LINE, |
|
CVS_LOGMSG_PREFIX, CVS_LOGMSG_PREFIX, CVS_LOGMSG_PREFIX); |
|
|
|
if (dir != NULL) |
|
fprintf(fp, "%s Commiting in %s\n%s\n", CVS_LOGMSG_PREFIX, dir, |
|
CVS_LOGMSG_PREFIX); |
|
|
|
for (i = 0; i < 3; i++) { |
|
if (files[i] == NULL) |
|
continue; |
|
|
|
fprintf(fp, "%s %s Files:", CVS_LOGMSG_PREFIX, |
|
cvs_logmsg_ops[i]); |
nl = 1; |
nl = 1; |
TAILQ_FOREACH(cvsfp, files, cf_list) { |
TAILQ_FOREACH(cvsfp, files[i], cf_list) { |
/* take the space into account */ |
/* take the space into account */ |
cvs_file_getpath(cvsfp, fpath, sizeof(fpath)); |
cvs_file_getpath(cvsfp, fpath, sizeof(fpath)); |
len = strlen(fpath) + 1; |
len = strlen(fpath) + 1; |
|
|
tlen += len; |
tlen += len; |
} |
} |
|
|
fprintf(fp, "\n%s %s\n", CVS_LOGMSG_PREFIX, |
fprintf(fp, "\n%s %s\n", CVS_LOGMSG_PREFIX, CVS_LOGMSG_LINE); |
CVS_LOGMSG_LOGLINE); |
|
} |
} |
(void)fflush(fp); |
(void)fflush(fp); |
|
|
|
|
} |
} |
|
|
for (;;) { |
for (;;) { |
ret = cvs_exec(argc, argv, fds); |
if (cvs_exec(argc, argv, fds) < 0) |
if (ret == -1) |
|
break; |
break; |
|
|
if (fstat(fd, &st2) == -1) { |
if (fstat(fd, &st2) == -1) { |
cvs_log(LP_ERRNO, "failed to stat log message file"); |
cvs_log(LP_ERRNO, "failed to stat log message file"); |
break; |
break; |
|
|
/* empty message */ |
/* empty message */ |
msg = strdup(""); |
msg = strdup(""); |
break; |
break; |
} else if (ret == 'e') |
} else if (buf[0] == 'e') |
continue; |
continue; |
else if (ret == '!') { |
else if (buf[0] == '!') { |
/* XXX do something */ |
/* XXX do something */ |
} |
} |
} |
} |