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