Annotation of src/usr.bin/cvs/remote.c, Revision 1.5
1.5 ! joris 1: /* $OpenBSD: remote.c,v 1.4 2006/07/10 01:32:32 joris 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';
92: } else {
93: ldata = xmalloc(len + 1);
94: if (strlcpy(ldata, data, len) >= len)
95: fatal("cvs_remote_input: truncation");
96: data = ldata;
97: }
98:
99: ldata = xstrdup(data);
1.5 ! joris 100:
! 101: if (cvs_server_active == 0 && cvs_client_outlog_fd != -1) {
! 102: BUF *bp;
! 103:
! 104: bp = cvs_buf_alloc(strlen(ldata), BUF_AUTOEXT);
! 105:
! 106: if (cvs_buf_append(bp, ldata, strlen(ldata)) < 0)
! 107: fatal("cvs_remote_input: cvs_buf_append");
! 108:
! 109: cvs_buf_putc(bp, '\n');
! 110:
! 111: if (cvs_buf_write_fd(bp, cvs_client_outlog_fd) < 0)
! 112: fatal("cvs_remote_input: cvs_buf_write_fd");
! 113:
! 114: cvs_buf_free(bp);
! 115: }
! 116:
1.1 joris 117: return (ldata);
118: }
119:
120: BUF *
121: cvs_remote_receive_file(size_t len)
122: {
123: BUF *bp;
124: FILE *in;
125: size_t ret;
126: char *data;
127:
128: if (cvs_server_active)
129: in = stdin;
130: else
131: in = current_cvsroot->cr_srvout;
132:
1.4 joris 133: bp = cvs_buf_alloc(len, BUF_AUTOEXT);
134:
135: if (len != 0) {
136: data = xmalloc(len);
137: ret = fread(data, sizeof(char), len, in);
138: if (ret != len)
139: fatal("length mismatch, expected %ld, got %ld",
140: len, ret);
141: cvs_buf_set(bp, data, len, 0);
142: xfree(data);
143: }
1.1 joris 144:
1.5 ! joris 145: if (cvs_server_active == 0 && cvs_client_outlog_fd != -1) {
! 146: if (cvs_buf_write_fd(bp, cvs_client_outlog_fd) < 0)
! 147: fatal("cvs_remote_receive_file: cvs_buf_write_fd");
! 148: }
! 149:
1.1 joris 150: return (bp);
151: }
152:
153: void
154: cvs_remote_send_file(const char *path)
155: {
156: BUF *bp;
157: int l, fd;
158: FILE *out;
159: size_t ret;
160: struct stat st;
161: char buf[16], *fcont;
162:
163: if (cvs_server_active)
164: out = stdout;
165: else
166: out = current_cvsroot->cr_srvin;
167:
168: if ((fd = open(path, O_RDONLY)) == -1)
169: fatal("cvs_remote_send_file: %s: %s", path, strerror(errno));
170:
171: if (fstat(fd, &st) == -1)
172: fatal("cvs_remote_send_file: %s: %s", path, strerror(errno));
173:
174: cvs_modetostr(st.st_mode, buf, sizeof(buf));
175: cvs_remote_output(buf);
176:
177: l = snprintf(buf, sizeof(buf), "%lld", st.st_size);
178: if (l == -1 || l >= (int)sizeof(buf))
179: fatal("cvs_remote_send_file: overflow");
180: cvs_remote_output(buf);
181:
182: bp = cvs_buf_load_fd(fd, BUF_AUTOEXT);
1.5 ! joris 183:
! 184: if (cvs_server_active == 0 && cvs_client_inlog_fd != -1) {
! 185: if (cvs_buf_write_fd(bp, cvs_client_inlog_fd) < 0)
! 186: fatal("cvs_remote_send_file: cvs_buf_write");
! 187: }
! 188:
1.1 joris 189: fcont = cvs_buf_release(bp);
190:
1.4 joris 191: if (fcont != NULL) {
192: ret = fwrite(fcont, sizeof(char), st.st_size, out);
193: if (ret != st.st_size)
194: fatal("tried to write %lld only wrote %ld",
195: st.st_size, ret);
196: xfree(fcont);
197: }
198:
1.1 joris 199: (void)close(fd);
200: }
201:
202: void
203: cvs_remote_classify_file(struct cvs_file *cf)
204: {
205: time_t mtime;
206: struct stat st;
207: CVSENTRIES *entlist;
208:
209: entlist = cvs_ent_open(cf->file_wd);
210: cf->file_ent = cvs_ent_get(entlist, cf->file_name);
211: cvs_ent_close(entlist, ENT_NOSYNC);
212:
213: if (cf->file_ent != NULL && cf->file_ent->ce_status != CVS_ENT_REG) {
214: if (cf->file_ent->ce_status == CVS_ENT_ADDED)
215: cf->file_status = FILE_ADDED;
216: else
217: cf->file_status = FILE_REMOVED;
218: return;
1.2 joris 219: }
220:
221: if (cf->file_ent != NULL) {
222: if (cf->file_ent->ce_type == CVS_ENT_DIR)
223: cf->file_type = CVS_DIR;
224: else
225: cf->file_type = CVS_FILE;
1.1 joris 226: }
227:
228: if (cf->fd != -1 && cf->file_ent != NULL) {
229: if (fstat(cf->fd, &st) == -1)
230: fatal("cvs_remote_classify_file(%s): %s", cf->file_path,
231: strerror(errno));
232:
233: mtime = cvs_hack_time(st.st_mtime, 1);
234: if (mtime != cf->file_ent->ce_mtime)
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: }
241: }
242: