Annotation of src/usr.bin/cvs/remote.c, Revision 1.14
1.14 ! otto 1: /* $OpenBSD: remote.c,v 1.13 2007/01/31 21:07:35 xsa Exp $ */
1.1 joris 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:
1.14 ! otto 18: #include <sys/stat.h>
! 19:
! 20: #include <errno.h>
! 21: #include <fcntl.h>
! 22: #include <stdlib.h>
! 23: #include <string.h>
! 24: #include <unistd.h>
1.1 joris 25:
26: #include "cvs.h"
27: #include "remote.h"
28:
29: struct cvs_resp *
30: cvs_remote_get_response_info(const char *response)
31: {
32: int i;
33:
34: for (i = 0; cvs_responses[i].supported != -1; i++) {
35: if (!strcmp(cvs_responses[i].name, response))
36: return (&(cvs_responses[i]));
37: }
38:
39: return (NULL);
40: }
41:
42: struct cvs_req *
43: cvs_remote_get_request_info(const char *request)
44: {
45: int i;
46:
47: for (i = 0; cvs_requests[i].supported != -1; i++) {
48: if (!strcmp(cvs_requests[i].name, request))
49: return (&(cvs_requests[i]));
50: }
51:
52: return (NULL);
53: }
54:
55: void
56: cvs_remote_output(const char *data)
57: {
58: FILE *out;
59:
60: if (cvs_server_active)
61: out = stdout;
62: else
63: out = current_cvsroot->cr_srvin;
64:
65: fputs(data, out);
66: fputs("\n", out);
67: }
68:
69: char *
70: cvs_remote_input(void)
71: {
72: FILE *in;
73: size_t len;
74: char *data, *ldata;
75:
76: if (cvs_server_active)
77: in = stdin;
78: else
79: in = current_cvsroot->cr_srvout;
80:
81: data = fgetln(in, &len);
82: if (data == NULL) {
83: if (sig_received != 0)
84: fatal("received signal %d", sig_received);
85:
86: if (cvs_server_active) {
87: cvs_cleanup();
88: exit(0);
89: }
90:
91: fatal("the connection has been closed by the server");
92: }
93:
94: if (data[len - 1] == '\n') {
95: data[len - 1] = '\0';
1.9 otto 96: ldata = xstrdup(data);
1.1 joris 97: } else {
98: ldata = xmalloc(len + 1);
1.9 otto 99: memcpy(ldata, data, len);
100: ldata[len] = '\0';
1.1 joris 101: }
1.5 joris 102:
103: if (cvs_server_active == 0 && cvs_client_outlog_fd != -1) {
104: BUF *bp;
105:
106: bp = cvs_buf_alloc(strlen(ldata), BUF_AUTOEXT);
107:
108: if (cvs_buf_append(bp, ldata, strlen(ldata)) < 0)
109: fatal("cvs_remote_input: cvs_buf_append");
110:
111: cvs_buf_putc(bp, '\n');
112:
113: if (cvs_buf_write_fd(bp, cvs_client_outlog_fd) < 0)
114: fatal("cvs_remote_input: cvs_buf_write_fd");
115:
116: cvs_buf_free(bp);
117: }
118:
1.1 joris 119: return (ldata);
120: }
121:
1.6 joris 122: void
123: cvs_remote_receive_file(int fd, size_t len)
1.1 joris 124: {
125: FILE *in;
1.10 otto 126: char data[MAXBSIZE];
1.6 joris 127: size_t nread, nwrite, nleft, toread;
1.1 joris 128:
129: if (cvs_server_active)
130: in = stdin;
131: else
132: in = current_cvsroot->cr_srvout;
133:
1.6 joris 134: nleft = len;
135:
136: while (nleft > 0) {
137: toread = MIN(nleft, MAXBSIZE);
138:
139: nread = fread(data, sizeof(char), toread, in);
140: if (nread == 0)
141: fatal("error receiving file");
1.4 joris 142:
1.6 joris 143: nwrite = write(fd, data, nread);
144: if (nwrite != nread)
1.8 otto 145: fatal("failed to write %zu bytes", nread);
1.6 joris 146:
147: if (cvs_server_active == 0 &&
148: cvs_client_outlog_fd != -1)
149: (void)write(cvs_client_outlog_fd, data, nread);
1.1 joris 150:
1.6 joris 151: nleft -= nread;
1.5 joris 152: }
1.1 joris 153: }
154:
155: void
156: cvs_remote_send_file(const char *path)
157: {
1.13 xsa 158: int fd;
1.6 joris 159: FILE *out, *in;
1.8 otto 160: size_t ret, rw;
161: off_t total;
1.1 joris 162: struct stat st;
1.11 otto 163: char buf[18], data[MAXBSIZE];
1.1 joris 164:
165: if (cvs_server_active)
166: out = stdout;
167: else
168: out = current_cvsroot->cr_srvin;
169:
170: if ((fd = open(path, O_RDONLY)) == -1)
171: fatal("cvs_remote_send_file: %s: %s", path, strerror(errno));
172:
173: if (fstat(fd, &st) == -1)
174: fatal("cvs_remote_send_file: %s: %s", path, strerror(errno));
175:
176: cvs_modetostr(st.st_mode, buf, sizeof(buf));
177: cvs_remote_output(buf);
178:
1.13 xsa 179: (void)xsnprintf(buf, sizeof(buf), "%lld", st.st_size);
1.1 joris 180: cvs_remote_output(buf);
181:
1.6 joris 182: if ((in = fdopen(fd, "r")) == NULL)
183: fatal("cvs_remote_send_file: fdopen %s", strerror(errno));
184:
185: total = 0;
186: while ((ret = fread(data, sizeof(char), MAXBSIZE, in)) != 0) {
187: rw = fwrite(data, sizeof(char), ret, out);
188: if (rw != ret)
1.8 otto 189: fatal("failed to write %zu bytes", ret);
1.5 joris 190:
1.6 joris 191: if (cvs_server_active == 0 &&
192: cvs_client_outlog_fd != -1)
193: (void)write(cvs_client_outlog_fd, data, ret);
194:
195: total += ret;
1.5 joris 196: }
1.1 joris 197:
1.6 joris 198: if (total != st.st_size)
1.8 otto 199: fatal("length mismatch, %lld vs %lld", total, st.st_size);
1.4 joris 200:
1.6 joris 201: (void)fclose(in);
1.1 joris 202: }
203:
204: void
205: cvs_remote_classify_file(struct cvs_file *cf)
206: {
207: struct stat st;
208: CVSENTRIES *entlist;
209:
210: entlist = cvs_ent_open(cf->file_wd);
211: cf->file_ent = cvs_ent_get(entlist, cf->file_name);
212: cvs_ent_close(entlist, ENT_NOSYNC);
213:
214: if (cf->file_ent != NULL && cf->file_ent->ce_status != CVS_ENT_REG) {
215: if (cf->file_ent->ce_status == CVS_ENT_ADDED)
216: cf->file_status = FILE_ADDED;
217: else
218: cf->file_status = FILE_REMOVED;
219: return;
1.2 joris 220: }
221:
222: if (cf->file_ent != NULL) {
223: if (cf->file_ent->ce_type == CVS_ENT_DIR)
224: cf->file_type = CVS_DIR;
225: else
226: cf->file_type = CVS_FILE;
1.1 joris 227: }
228:
229: if (cf->fd != -1 && cf->file_ent != NULL) {
230: if (fstat(cf->fd, &st) == -1)
231: fatal("cvs_remote_classify_file(%s): %s", cf->file_path,
232: strerror(errno));
233:
1.12 joris 234: if (st.st_mtime != cf->file_ent->ce_mtime)
1.1 joris 235: cf->file_status = FILE_MODIFIED;
236: else
237: cf->file_status = FILE_UPTODATE;
238: } else if (cf->fd == -1) {
239: cf->file_status = FILE_UNKNOWN;
240: }
1.7 joris 241:
242: if (cvs_cmdop == CVS_OP_IMPORT && cf->file_type == CVS_FILE)
243: cf->file_status = FILE_MODIFIED;
1.1 joris 244: }
245: