diff options
author | Jean-Francois Brousseau <jfb@cvs.openbsd.org> | 2004-12-07 16:48:56 +0000 |
---|---|---|
committer | Jean-Francois Brousseau <jfb@cvs.openbsd.org> | 2004-12-07 16:48:56 +0000 |
commit | 2348195e75220fe47d1af53445293fc2d0b616d4 (patch) | |
tree | 299e66ab053db1c152a05c69cc4d48be10d21ce7 | |
parent | 4327e193d476bd5cb9bad5ba8fb83b476dbafeb9 (diff) |
avoid a crash when receiving either a Created, Updated, Update-existing
or Merged response by reopening the Entries file correctly before
making modifications to it
Fixes a SIGSEGV reported by Joris Vink and djm@
-rw-r--r-- | usr.bin/cvs/resp.c | 37 |
1 files changed, 26 insertions, 11 deletions
diff --git a/usr.bin/cvs/resp.c b/usr.bin/cvs/resp.c index 4948e9da502..8f5ad26497d 100644 --- a/usr.bin/cvs/resp.c +++ b/usr.bin/cvs/resp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: resp.c,v 1.11 2004/12/06 21:03:12 deraadt Exp $ */ +/* $OpenBSD: resp.c,v 1.12 2004/12/07 16:48:55 jfb Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org> * All rights reserved. @@ -124,7 +124,7 @@ struct cvs_resphdlr { static char *cvs_mt_stack[CVS_MTSTK_MAXDEPTH]; static u_int cvs_mtstk_depth = 0; -static time_t cvs_modtime = 0; +static time_t cvs_modtime = CVS_DATE_DMSEC; /* last checksum received */ @@ -519,6 +519,7 @@ cvs_resp_updated(struct cvsroot *root, int type, char *line) char path[MAXPATHLEN], cksum_buf[CVS_CKSUM_LEN]; BUF *fbuf; CVSFILE *cf; + CVSENTRIES *entfile; struct cvs_ent *ep; struct timeval tv[2]; @@ -543,12 +544,23 @@ cvs_resp_updated(struct cvsroot *root, int type, char *line) return (-1); snprintf(path, sizeof(path), "%s/%s", line, ep->ce_name); + entfile = cvs_ent_open(line, O_WRONLY); + if (entfile == NULL) { + cvs_ent_free(ep); + return (-1); + } + if (type == CVS_RESP_CREATED) { /* set the timestamp as the last one received from Mod-time */ ep->ce_mtime = cvs_modtime; - cvs_ent_add(cf->cf_ddat->cd_ent, ep); - } else if (type == CVS_RESP_UPDEXIST) { - } else if (type == CVS_RESP_UPDATED) { + cvs_ent_add(entfile, ep); + } else if ((type == CVS_RESP_UPDEXIST) || (type == CVS_RESP_UPDATED)) { + if (cvs_ent_remove(entfile, ep->ce_name) < 0) + cvs_log(LP_WARN, "failed to remove entry for `%s'", + ep->ce_name); + + cvs_ent_add(entfile, ep); + } else if (type == CVS_RESP_MERGED) { } fbuf = cvs_recvfile(root, &fmode); @@ -557,12 +569,14 @@ cvs_resp_updated(struct cvsroot *root, int type, char *line) cvs_buf_write(fbuf, path, fmode); - tv[0].tv_sec = (long)cvs_modtime; - tv[0].tv_usec = 0; - tv[1].tv_sec = (long)cvs_modtime; - tv[1].tv_usec = 0; - if (utimes(path, tv) == -1) - cvs_log(LP_ERRNO, "failed to set file timestamps"); + if (cvs_modtime != CVS_DATE_DMSEC) { + tv[0].tv_sec = (long)cvs_modtime; + tv[0].tv_usec = 0; + tv[1].tv_sec = (long)cvs_modtime; + tv[1].tv_usec = 0; + if (utimes(path, tv) == -1) + cvs_log(LP_ERRNO, "failed to set file timestamps"); + } /* now see if there is a checksum */ if (cvs_fcksum != NULL) { @@ -627,6 +641,7 @@ static int cvs_resp_mode(struct cvsroot *root, int type, char *line) { if (cvs_strtomode(line, &cvs_lastmode) < 0) { + cvs_log(LP_ERR, "error handling Mode response"); return (-1); } return (0); |