Annotation of src/usr.bin/cvs/remote.c, Revision 1.1
1.1 ! joris 1: /* $OpenBSD$ */
! 2: /*
! 3: * Copyright (c) 2006 Joris Vink <joris@openbsd.org>
! 4: *
! 5: * Permission to use, copy, modify, and distribute this software for any
! 6: * purpose with or without fee is hereby granted, provided that the above
! 7: * copyright notice and this permission notice appear in all copies.
! 8: *
! 9: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
! 10: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
! 11: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
! 12: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
! 13: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
! 14: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
! 15: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
! 16: */
! 17:
! 18: #include "includes.h"
! 19:
! 20: #include "cvs.h"
! 21: #include "log.h"
! 22: #include "diff.h"
! 23: #include "remote.h"
! 24:
! 25: struct cvs_resp *
! 26: cvs_remote_get_response_info(const char *response)
! 27: {
! 28: int i;
! 29:
! 30: for (i = 0; cvs_responses[i].supported != -1; i++) {
! 31: if (!strcmp(cvs_responses[i].name, response))
! 32: return (&(cvs_responses[i]));
! 33: }
! 34:
! 35: return (NULL);
! 36: }
! 37:
! 38: struct cvs_req *
! 39: cvs_remote_get_request_info(const char *request)
! 40: {
! 41: int i;
! 42:
! 43: for (i = 0; cvs_requests[i].supported != -1; i++) {
! 44: if (!strcmp(cvs_requests[i].name, request))
! 45: return (&(cvs_requests[i]));
! 46: }
! 47:
! 48: return (NULL);
! 49: }
! 50:
! 51: void
! 52: cvs_remote_output(const char *data)
! 53: {
! 54: FILE *out;
! 55:
! 56: if (cvs_server_active)
! 57: out = stdout;
! 58: else
! 59: out = current_cvsroot->cr_srvin;
! 60:
! 61: if (cvs_server_active == 0)
! 62: cvs_log(LP_TRACE, "cvs_remote_output(%s)", data);
! 63:
! 64: fputs(data, out);
! 65: fputs("\n", out);
! 66: }
! 67:
! 68: char *
! 69: cvs_remote_input(void)
! 70: {
! 71: FILE *in;
! 72: size_t len;
! 73: char *data, *ldata;
! 74:
! 75: if (cvs_server_active)
! 76: in = stdin;
! 77: else
! 78: in = current_cvsroot->cr_srvout;
! 79:
! 80: data = fgetln(in, &len);
! 81: if (data == NULL) {
! 82: if (sig_received != 0)
! 83: fatal("received signal %d", sig_received);
! 84:
! 85: if (cvs_server_active) {
! 86: cvs_cleanup();
! 87: exit(0);
! 88: }
! 89:
! 90: fatal("the connection has been closed by the server");
! 91: }
! 92:
! 93: if (data[len - 1] == '\n') {
! 94: data[len - 1] = '\0';
! 95: } else {
! 96: ldata = xmalloc(len + 1);
! 97: if (strlcpy(ldata, data, len) >= len)
! 98: fatal("cvs_remote_input: truncation");
! 99: data = ldata;
! 100: }
! 101:
! 102: ldata = xstrdup(data);
! 103: return (ldata);
! 104: }
! 105:
! 106: BUF *
! 107: cvs_remote_receive_file(size_t len)
! 108: {
! 109: BUF *bp;
! 110: FILE *in;
! 111: size_t ret;
! 112: char *data;
! 113:
! 114: if (cvs_server_active)
! 115: in = stdin;
! 116: else
! 117: in = current_cvsroot->cr_srvout;
! 118:
! 119: cvs_log(LP_TRACE, "cvs_remote_receive_file(%ld)", len);
! 120:
! 121: data = xmalloc(len);
! 122: ret = fread(data, sizeof(char), len, in);
! 123: if (ret != len)
! 124: fatal("length mismatch, expected %ld, got %ld", len, ret);
! 125:
! 126: bp = cvs_buf_alloc(len, BUF_AUTOEXT);
! 127: cvs_buf_set(bp, data, len, 0);
! 128: xfree(data);
! 129: return (bp);
! 130: }
! 131:
! 132: void
! 133: cvs_remote_send_file(const char *path)
! 134: {
! 135: BUF *bp;
! 136: int l, fd;
! 137: FILE *out;
! 138: size_t ret;
! 139: struct stat st;
! 140: char buf[16], *fcont;
! 141:
! 142: if (cvs_server_active)
! 143: out = stdout;
! 144: else
! 145: out = current_cvsroot->cr_srvin;
! 146:
! 147: cvs_log(LP_TRACE, "cvs_remote_send_file(%s)", path);
! 148:
! 149: if ((fd = open(path, O_RDONLY)) == -1)
! 150: fatal("cvs_remote_send_file: %s: %s", path, strerror(errno));
! 151:
! 152: if (fstat(fd, &st) == -1)
! 153: fatal("cvs_remote_send_file: %s: %s", path, strerror(errno));
! 154:
! 155: cvs_modetostr(st.st_mode, buf, sizeof(buf));
! 156: cvs_remote_output(buf);
! 157:
! 158: l = snprintf(buf, sizeof(buf), "%lld", st.st_size);
! 159: if (l == -1 || l >= (int)sizeof(buf))
! 160: fatal("cvs_remote_send_file: overflow");
! 161: cvs_remote_output(buf);
! 162:
! 163: bp = cvs_buf_load_fd(fd, BUF_AUTOEXT);
! 164: fcont = cvs_buf_release(bp);
! 165: ret = fwrite(fcont, sizeof(char), st.st_size, out);
! 166: if (ret != st.st_size)
! 167: fatal("length mismatch, tried to write %lld only wrote %ld",
! 168: st.st_size, ret);
! 169:
! 170: xfree(fcont);
! 171: (void)close(fd);
! 172: }
! 173:
! 174: void
! 175: cvs_remote_classify_file(struct cvs_file *cf)
! 176: {
! 177: time_t mtime;
! 178: struct stat st;
! 179: CVSENTRIES *entlist;
! 180:
! 181: cvs_log(LP_TRACE, "cvs_remote_classify_file(%s)", cf->file_path);
! 182:
! 183: entlist = cvs_ent_open(cf->file_wd);
! 184: cf->file_ent = cvs_ent_get(entlist, cf->file_name);
! 185: cvs_ent_close(entlist, ENT_NOSYNC);
! 186:
! 187: if (cf->file_ent != NULL && cf->file_ent->ce_status != CVS_ENT_REG) {
! 188: if (cf->file_ent->ce_status == CVS_ENT_ADDED)
! 189: cf->file_status = FILE_ADDED;
! 190: else
! 191: cf->file_status = FILE_REMOVED;
! 192: return;
! 193: }
! 194:
! 195: if (cf->fd != -1 && cf->file_ent != NULL) {
! 196: if (fstat(cf->fd, &st) == -1)
! 197: fatal("cvs_remote_classify_file(%s): %s", cf->file_path,
! 198: strerror(errno));
! 199:
! 200: mtime = cvs_hack_time(st.st_mtime, 1);
! 201: if (mtime != cf->file_ent->ce_mtime)
! 202: cf->file_status = FILE_MODIFIED;
! 203: else
! 204: cf->file_status = FILE_UPTODATE;
! 205: } else if (cf->fd == -1) {
! 206: cf->file_status = FILE_UNKNOWN;
! 207: }
! 208: }
! 209: