Annotation of src/usr.bin/cvs/remote.c, Revision 1.2
1.2 ! joris 1: /* $OpenBSD: remote.c,v 1.1 2006/07/07 17:37:17 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: 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;
1.2 ! joris 193: }
! 194:
! 195: if (cf->file_ent != NULL) {
! 196: if (cf->file_ent->ce_type == CVS_ENT_DIR)
! 197: cf->file_type = CVS_DIR;
! 198: else
! 199: cf->file_type = CVS_FILE;
1.1 joris 200: }
201:
202: if (cf->fd != -1 && cf->file_ent != NULL) {
203: if (fstat(cf->fd, &st) == -1)
204: fatal("cvs_remote_classify_file(%s): %s", cf->file_path,
205: strerror(errno));
206:
207: mtime = cvs_hack_time(st.st_mtime, 1);
208: if (mtime != cf->file_ent->ce_mtime)
209: cf->file_status = FILE_MODIFIED;
210: else
211: cf->file_status = FILE_UPTODATE;
212: } else if (cf->fd == -1) {
213: cf->file_status = FILE_UNKNOWN;
214: }
215: }
216: