File: | src/gnu/usr.bin/cvs/src/client.c |
Warning: | line 1237, column 23 Null pointer passed as 1st argument to string length function |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* JT thinks BeOS is worth the trouble. */ | ||
2 | |||
3 | /* CVS client-related stuff. | ||
4 | |||
5 | This program is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published by | ||
7 | the Free Software Foundation; either version 2, or (at your option) | ||
8 | any later version. | ||
9 | |||
10 | This program is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | GNU General Public License for more details. */ | ||
14 | |||
15 | #ifdef HAVE_CONFIG_H1 | ||
16 | #include "config.h" | ||
17 | #endif /* HAVE_CONFIG_H */ | ||
18 | |||
19 | #include <assert.h> | ||
20 | #include "cvs.h" | ||
21 | #include "getline.h" | ||
22 | #include "edit.h" | ||
23 | #include "buffer.h" | ||
24 | |||
25 | #ifdef CLIENT_SUPPORT1 | ||
26 | |||
27 | #include "md5.h" | ||
28 | |||
29 | #if defined(AUTH_CLIENT_SUPPORT1) || HAVE_KERBEROS || defined(SOCK_ERRNO(*__errno())) || defined(SOCK_STRERRORstrerror) | ||
30 | # ifdef HAVE_WINSOCK_H | ||
31 | # include <winsock.h> | ||
32 | # else /* No winsock.h */ | ||
33 | # include <sys/socket.h> | ||
34 | # include <netinet/in.h> | ||
35 | # include <arpa/inet.h> | ||
36 | # include <netdb.h> | ||
37 | # endif /* No winsock.h */ | ||
38 | #endif | ||
39 | |||
40 | /* If SOCK_ERRNO is defined, then send()/recv() and other socket calls | ||
41 | do not set errno, but that this macro should be used to obtain an | ||
42 | error code. This probably doesn't make sense unless | ||
43 | NO_SOCKET_TO_FD is also defined. */ | ||
44 | #ifndef SOCK_ERRNO(*__errno()) | ||
45 | #define SOCK_ERRNO(*__errno()) errno(*__errno()) | ||
46 | #endif | ||
47 | |||
48 | /* If SOCK_STRERROR is defined, then the error codes returned by | ||
49 | socket operations are not known to strerror, and this macro must be | ||
50 | used instead to convert those error codes to strings. */ | ||
51 | #ifndef SOCK_STRERRORstrerror | ||
52 | # define SOCK_STRERRORstrerror strerror | ||
53 | |||
54 | # if STDC_HEADERS1 | ||
55 | # include <string.h> | ||
56 | # endif | ||
57 | |||
58 | # ifndef strerror | ||
59 | extern char *strerror (); | ||
60 | # endif | ||
61 | #endif /* ! SOCK_STRERROR */ | ||
62 | |||
63 | #if HAVE_KERBEROS | ||
64 | #define CVS_PORT 1999 | ||
65 | |||
66 | #include <krb.h> | ||
67 | |||
68 | extern char *krb_realmofhost (); | ||
69 | #ifndef HAVE_KRB_GET_ERR_TEXT | ||
70 | #define krb_get_err_text(status) krb_err_txt[status] | ||
71 | #endif /* HAVE_KRB_GET_ERR_TEXT */ | ||
72 | |||
73 | /* Information we need if we are going to use Kerberos encryption. */ | ||
74 | static C_Block kblock; | ||
75 | static Key_schedule sched; | ||
76 | |||
77 | #endif /* HAVE_KERBEROS */ | ||
78 | |||
79 | #ifdef HAVE_GSSAPI | ||
80 | |||
81 | # include "xgssapi.h" | ||
82 | |||
83 | /* This is needed for GSSAPI encryption. */ | ||
84 | static gss_ctx_id_t gcontext; | ||
85 | |||
86 | static int connect_to_gserver PROTO((int, const char *))(int, const char *); | ||
87 | |||
88 | #endif /* HAVE_GSSAPI */ | ||
89 | |||
90 | static void add_prune_candidate PROTO((char *))(char *); | ||
91 | |||
92 | /* All the commands. */ | ||
93 | int add PROTO((int argc, char **argv))(int argc, char **argv); | ||
94 | int admin PROTO((int argc, char **argv))(int argc, char **argv); | ||
95 | int checkout PROTO((int argc, char **argv))(int argc, char **argv); | ||
96 | int commit PROTO((int argc, char **argv))(int argc, char **argv); | ||
97 | int diff PROTO((int argc, char **argv))(int argc, char **argv); | ||
98 | int history PROTO((int argc, char **argv))(int argc, char **argv); | ||
99 | int import PROTO((int argc, char **argv))(int argc, char **argv); | ||
100 | int cvslog PROTO((int argc, char **argv))(int argc, char **argv); | ||
101 | int patch PROTO((int argc, char **argv))(int argc, char **argv); | ||
102 | int release PROTO((int argc, char **argv))(int argc, char **argv); | ||
103 | int cvsremove PROTO((int argc, char **argv))(int argc, char **argv); | ||
104 | int rtag PROTO((int argc, char **argv))(int argc, char **argv); | ||
105 | int status PROTO((int argc, char **argv))(int argc, char **argv); | ||
106 | int tag PROTO((int argc, char **argv))(int argc, char **argv); | ||
107 | int update PROTO((int argc, char **argv))(int argc, char **argv); | ||
108 | |||
109 | /* All the response handling functions. */ | ||
110 | static void handle_ok PROTO((char *, int))(char *, int); | ||
111 | static void handle_error PROTO((char *, int))(char *, int); | ||
112 | static void handle_valid_requests PROTO((char *, int))(char *, int); | ||
113 | static void handle_checked_in PROTO((char *, int))(char *, int); | ||
114 | static void handle_new_entry PROTO((char *, int))(char *, int); | ||
115 | static void handle_checksum PROTO((char *, int))(char *, int); | ||
116 | static void handle_copy_file PROTO((char *, int))(char *, int); | ||
117 | static void handle_updated PROTO((char *, int))(char *, int); | ||
118 | static void handle_merged PROTO((char *, int))(char *, int); | ||
119 | static void handle_patched PROTO((char *, int))(char *, int); | ||
120 | static void handle_rcs_diff PROTO((char *, int))(char *, int); | ||
121 | static void handle_removed PROTO((char *, int))(char *, int); | ||
122 | static void handle_remove_entry PROTO((char *, int))(char *, int); | ||
123 | static void handle_set_static_directory PROTO((char *, int))(char *, int); | ||
124 | static void handle_clear_static_directory PROTO((char *, int))(char *, int); | ||
125 | static void handle_set_sticky PROTO((char *, int))(char *, int); | ||
126 | static void handle_clear_sticky PROTO((char *, int))(char *, int); | ||
127 | static void handle_set_checkin_prog PROTO((char *, int))(char *, int); | ||
128 | static void handle_set_update_prog PROTO((char *, int))(char *, int); | ||
129 | static void handle_module_expansion PROTO((char *, int))(char *, int); | ||
130 | static void handle_wrapper_rcs_option PROTO((char *, int))(char *, int); | ||
131 | static void handle_m PROTO((char *, int))(char *, int); | ||
132 | static void handle_e PROTO((char *, int))(char *, int); | ||
133 | static void handle_f PROTO((char *, int))(char *, int); | ||
134 | static void handle_notified PROTO((char *, int))(char *, int); | ||
135 | |||
136 | static size_t try_read_from_server PROTO ((char *, size_t))(char *, size_t); | ||
137 | #endif /* CLIENT_SUPPORT */ | ||
138 | |||
139 | #ifdef CLIENT_SUPPORT1 | ||
140 | |||
141 | /* We need to keep track of the list of directories we've sent to the | ||
142 | server. This list, along with the current CVSROOT, will help us | ||
143 | decide which command-line arguments to send. */ | ||
144 | List *dirs_sent_to_server = NULL((void*)0); | ||
145 | |||
146 | static int is_arg_a_parent_or_listed_dir PROTO((Node *, void *))(Node *, void *); | ||
147 | |||
148 | static int | ||
149 | is_arg_a_parent_or_listed_dir (n, d) | ||
150 | Node *n; | ||
151 | void *d; | ||
152 | { | ||
153 | char *directory = n->key; /* name of the dir sent to server */ | ||
154 | char *this_argv_elem = (char *) d; /* this argv element */ | ||
155 | |||
156 | /* Say we should send this argument if the argument matches the | ||
157 | beginning of a directory name sent to the server. This way, | ||
158 | the server will know to start at the top of that directory | ||
159 | hierarchy and descend. */ | ||
160 | |||
161 | if (strncmp (directory, this_argv_elem, strlen (this_argv_elem)) == 0) | ||
162 | return 1; | ||
163 | |||
164 | return 0; | ||
165 | } | ||
166 | |||
167 | static int arg_should_not_be_sent_to_server PROTO((char *))(char *); | ||
168 | |||
169 | /* Return nonzero if this argument should not be sent to the | ||
170 | server. */ | ||
171 | |||
172 | static int | ||
173 | arg_should_not_be_sent_to_server (arg) | ||
174 | char *arg; | ||
175 | { | ||
176 | /* Decide if we should send this directory name to the server. We | ||
177 | should always send argv[i] if: | ||
178 | |||
179 | 1) the list of directories sent to the server is empty (as it | ||
180 | will be for checkout, etc.). | ||
181 | |||
182 | 2) the argument is "." | ||
183 | |||
184 | 3) the argument is a file in the cwd and the cwd is checked out | ||
185 | from the current root | ||
186 | |||
187 | 4) the argument lies within one of the paths in | ||
188 | dirs_sent_to_server. | ||
189 | |||
190 | */ | ||
191 | |||
192 | if (list_isempty (dirs_sent_to_server)) | ||
193 | return 0; /* always send it */ | ||
194 | |||
195 | if (strcmp (arg, ".") == 0) | ||
196 | return 0; /* always send it */ | ||
197 | |||
198 | /* We should send arg if it is one of the directories sent to the | ||
199 | server or the parent of one; this tells the server to descend | ||
200 | the hierarchy starting at this level. */ | ||
201 | if (isdir (arg)) | ||
202 | { | ||
203 | if (walklist (dirs_sent_to_server, is_arg_a_parent_or_listed_dir, arg)) | ||
204 | return 0; | ||
205 | |||
206 | /* If arg wasn't a parent, we don't know anything about it (we | ||
207 | would have seen something related to it during the | ||
208 | send_files phase). Don't send it. */ | ||
209 | return 1; | ||
210 | } | ||
211 | |||
212 | /* Try to decide whether we should send arg to the server by | ||
213 | checking the contents of the corresponding CVSADM directory. */ | ||
214 | { | ||
215 | char *t, *this_root; | ||
216 | |||
217 | /* Calculate "dirname arg" */ | ||
218 | for (t = arg + strlen (arg) - 1; t >= arg; t--) | ||
219 | { | ||
220 | if (ISDIRSEP(*t)((*t) == '/')) | ||
221 | break; | ||
222 | } | ||
223 | |||
224 | /* Now we're either poiting to the beginning of the | ||
225 | string, or we found a path separator. */ | ||
226 | if (t >= arg) | ||
227 | { | ||
228 | /* Found a path separator. */ | ||
229 | char c = *t; | ||
230 | *t = '\0'; | ||
231 | |||
232 | /* First, check to see if we sent this directory to the | ||
233 | server, because it takes less time than actually | ||
234 | opening the stuff in the CVSADM directory. */ | ||
235 | if (walklist (dirs_sent_to_server, is_arg_a_parent_or_listed_dir, | ||
236 | arg)) | ||
237 | { | ||
238 | *t = c; /* make sure to un-truncate the arg */ | ||
239 | return 0; | ||
240 | } | ||
241 | |||
242 | /* Since we didn't find it in the list, check the CVSADM | ||
243 | files on disk. */ | ||
244 | this_root = Name_Root (arg, (char *) NULL((void*)0)); | ||
245 | *t = c; | ||
246 | } | ||
247 | else | ||
248 | { | ||
249 | /* We're at the beginning of the string. Look at the | ||
250 | CVSADM files in cwd. */ | ||
251 | this_root = Name_Root ((char *) NULL((void*)0), (char *) NULL((void*)0)); | ||
252 | } | ||
253 | |||
254 | /* | ||
255 | * This is so bogus! Means if you have checked out from | ||
256 | * a replica of a repository, and then when you want to | ||
257 | * check it in to the real (read/write) repository, the | ||
258 | * file will be skipped! | ||
259 | */ | ||
260 | #if 0 | ||
261 | /* Now check the value for root. */ | ||
262 | if (this_root && current_parsed_root | ||
263 | && (strcmp (this_root, current_parsed_root->original) != 0)) | ||
264 | { | ||
265 | /* Don't send this, since the CVSROOTs don't match. */ | ||
266 | free (this_root); | ||
267 | return 1; | ||
268 | } | ||
269 | #endif | ||
270 | free (this_root); | ||
271 | } | ||
272 | |||
273 | /* OK, let's send it. */ | ||
274 | return 0; | ||
275 | } | ||
276 | |||
277 | |||
278 | #endif /* CLIENT_SUPPORT */ | ||
279 | |||
280 | #if defined(CLIENT_SUPPORT1) || defined(SERVER_SUPPORT1) | ||
281 | |||
282 | /* Shared with server. */ | ||
283 | |||
284 | /* | ||
285 | * Return a malloc'd, '\0'-terminated string | ||
286 | * corresponding to the mode in SB. | ||
287 | */ | ||
288 | char * | ||
289 | #ifdef __STDC__1 | ||
290 | mode_to_string (mode_t mode) | ||
291 | #else /* ! __STDC__ */ | ||
292 | mode_to_string (mode) | ||
293 | mode_t mode; | ||
294 | #endif /* __STDC__ */ | ||
295 | { | ||
296 | char buf[18], u[4], g[4], o[4]; | ||
297 | int i; | ||
298 | |||
299 | i = 0; | ||
300 | if (mode & S_IRUSR0000400) u[i++] = 'r'; | ||
301 | if (mode & S_IWUSR0000200) u[i++] = 'w'; | ||
302 | if (mode & S_IXUSR0000100) u[i++] = 'x'; | ||
303 | u[i] = '\0'; | ||
304 | |||
305 | i = 0; | ||
306 | if (mode & S_IRGRP0000040) g[i++] = 'r'; | ||
307 | if (mode & S_IWGRP0000020) g[i++] = 'w'; | ||
308 | if (mode & S_IXGRP0000010) g[i++] = 'x'; | ||
309 | g[i] = '\0'; | ||
310 | |||
311 | i = 0; | ||
312 | if (mode & S_IROTH0000004) o[i++] = 'r'; | ||
313 | if (mode & S_IWOTH0000002) o[i++] = 'w'; | ||
314 | if (mode & S_IXOTH0000001) o[i++] = 'x'; | ||
315 | o[i] = '\0'; | ||
316 | |||
317 | sprintf(buf, "u=%s,g=%s,o=%s", u, g, o); | ||
318 | return xstrdup(buf); | ||
319 | } | ||
320 | |||
321 | /* | ||
322 | * Change mode of FILENAME to MODE_STRING. | ||
323 | * Returns 0 for success or errno code. | ||
324 | * If RESPECT_UMASK is set, then honor the umask. | ||
325 | */ | ||
326 | int | ||
327 | change_mode (filename, mode_string, respect_umask) | ||
328 | char *filename; | ||
329 | char *mode_string; | ||
330 | int respect_umask; | ||
331 | { | ||
332 | #ifdef CHMOD_BROKEN | ||
333 | char *p; | ||
334 | int writeable = 0; | ||
335 | |||
336 | /* We can only distinguish between | ||
337 | 1) readable | ||
338 | 2) writeable | ||
339 | 3) Picasso's "Blue Period" | ||
340 | We handle the first two. */ | ||
341 | p = mode_string; | ||
342 | while (*p != '\0') | ||
343 | { | ||
344 | if ((p[0] == 'u' || p[0] == 'g' || p[0] == 'o') && p[1] == '=') | ||
345 | { | ||
346 | char *q = p + 2; | ||
347 | while (*q != ',' && *q != '\0') | ||
348 | { | ||
349 | if (*q == 'w') | ||
350 | writeable = 1; | ||
351 | ++q; | ||
352 | } | ||
353 | } | ||
354 | /* Skip to the next field. */ | ||
355 | while (*p != ',' && *p != '\0') | ||
356 | ++p; | ||
357 | if (*p == ',') | ||
358 | ++p; | ||
359 | } | ||
360 | |||
361 | /* xchmod honors the umask for us. In the !respect_umask case, we | ||
362 | don't try to cope with it (probably to handle that well, the server | ||
363 | needs to deal with modes in data structures, rather than via the | ||
364 | modes in temporary files). */ | ||
365 | xchmod (filename, writeable); | ||
366 | return 0; | ||
367 | |||
368 | #else /* ! CHMOD_BROKEN */ | ||
369 | |||
370 | char *p; | ||
371 | mode_t mode = 0; | ||
372 | mode_t oumask; | ||
373 | |||
374 | p = mode_string; | ||
375 | while (*p != '\0') | ||
376 | { | ||
377 | if ((p[0] == 'u' || p[0] == 'g' || p[0] == 'o') && p[1] == '=') | ||
378 | { | ||
379 | int can_read = 0, can_write = 0, can_execute = 0; | ||
380 | char *q = p + 2; | ||
381 | while (*q != ',' && *q != '\0') | ||
382 | { | ||
383 | if (*q == 'r') | ||
384 | can_read = 1; | ||
385 | else if (*q == 'w') | ||
386 | can_write = 1; | ||
387 | else if (*q == 'x') | ||
388 | can_execute = 1; | ||
389 | ++q; | ||
390 | } | ||
391 | if (p[0] == 'u') | ||
392 | { | ||
393 | if (can_read) | ||
394 | mode |= S_IRUSR0000400; | ||
395 | if (can_write) | ||
396 | mode |= S_IWUSR0000200; | ||
397 | if (can_execute) | ||
398 | mode |= S_IXUSR0000100; | ||
399 | } | ||
400 | else if (p[0] == 'g') | ||
401 | { | ||
402 | if (can_read) | ||
403 | mode |= S_IRGRP0000040; | ||
404 | if (can_write) | ||
405 | mode |= S_IWGRP0000020; | ||
406 | if (can_execute) | ||
407 | mode |= S_IXGRP0000010; | ||
408 | } | ||
409 | else if (p[0] == 'o') | ||
410 | { | ||
411 | if (can_read) | ||
412 | mode |= S_IROTH0000004; | ||
413 | if (can_write) | ||
414 | mode |= S_IWOTH0000002; | ||
415 | if (can_execute) | ||
416 | mode |= S_IXOTH0000001; | ||
417 | } | ||
418 | } | ||
419 | /* Skip to the next field. */ | ||
420 | while (*p != ',' && *p != '\0') | ||
421 | ++p; | ||
422 | if (*p == ',') | ||
423 | ++p; | ||
424 | } | ||
425 | |||
426 | if (respect_umask) | ||
427 | { | ||
428 | oumask = umask (0); | ||
429 | (void) umask (oumask); | ||
430 | mode &= ~oumask; | ||
431 | } | ||
432 | |||
433 | if (chmod (filename, mode) < 0) | ||
434 | return errno(*__errno()); | ||
435 | return 0; | ||
436 | #endif /* ! CHMOD_BROKEN */ | ||
437 | } | ||
438 | |||
439 | #endif /* CLIENT_SUPPORT or SERVER_SUPPORT */ | ||
440 | |||
441 | #ifdef CLIENT_SUPPORT1 | ||
442 | |||
443 | int client_prune_dirs; | ||
444 | |||
445 | static List *ignlist = (List *) NULL((void*)0); | ||
446 | |||
447 | /* Buffer to write to the server. */ | ||
448 | static struct buffer *to_server; | ||
449 | /* The stream underlying to_server, if we are using a stream. */ | ||
450 | static FILE *to_server_fp; | ||
451 | |||
452 | /* Buffer used to read from the server. */ | ||
453 | static struct buffer *from_server; | ||
454 | /* The stream underlying from_server, if we are using a stream. */ | ||
455 | static FILE *from_server_fp; | ||
456 | |||
457 | /* Process ID of rsh subprocess. */ | ||
458 | static int rsh_pid = -1; | ||
459 | |||
460 | |||
461 | /* We want to be able to log data sent between us and the server. We | ||
462 | do it using log buffers. Each log buffer has another buffer which | ||
463 | handles the actual I/O, and a file to log information to. | ||
464 | |||
465 | This structure is the closure field of a log buffer. */ | ||
466 | |||
467 | struct log_buffer | ||
468 | { | ||
469 | /* The underlying buffer. */ | ||
470 | struct buffer *buf; | ||
471 | /* The file to log information to. */ | ||
472 | FILE *log; | ||
473 | }; | ||
474 | |||
475 | static struct buffer *log_buffer_initialize | ||
476 | PROTO((struct buffer *, FILE *, int, void (*) (struct buffer *)))(struct buffer *, FILE *, int, void (*) (struct buffer *)); | ||
477 | static int log_buffer_input PROTO((void *, char *, int, int, int *))(void *, char *, int, int, int *); | ||
478 | static int log_buffer_output PROTO((void *, const char *, int, int *))(void *, const char *, int, int *); | ||
479 | static int log_buffer_flush PROTO((void *))(void *); | ||
480 | static int log_buffer_block PROTO((void *, int))(void *, int); | ||
481 | static int log_buffer_shutdown PROTO((void *))(void *); | ||
482 | |||
483 | /* Create a log buffer. */ | ||
484 | |||
485 | static struct buffer * | ||
486 | log_buffer_initialize (buf, fp, input, memory) | ||
487 | struct buffer *buf; | ||
488 | FILE *fp; | ||
489 | int input; | ||
490 | void (*memory) PROTO((struct buffer *))(struct buffer *); | ||
491 | { | ||
492 | struct log_buffer *n; | ||
493 | |||
494 | n = (struct log_buffer *) xmalloc (sizeof *n); | ||
495 | n->buf = buf; | ||
496 | n->log = fp; | ||
497 | return buf_initialize (input ? log_buffer_input : NULL((void*)0), | ||
498 | input ? NULL((void*)0) : log_buffer_output, | ||
499 | input ? NULL((void*)0) : log_buffer_flush, | ||
500 | log_buffer_block, | ||
501 | log_buffer_shutdown, | ||
502 | memory, | ||
503 | n); | ||
504 | } | ||
505 | |||
506 | /* The input function for a log buffer. */ | ||
507 | |||
508 | static int | ||
509 | log_buffer_input (closure, data, need, size, got) | ||
510 | void *closure; | ||
511 | char *data; | ||
512 | int need; | ||
513 | int size; | ||
514 | int *got; | ||
515 | { | ||
516 | struct log_buffer *lb = (struct log_buffer *) closure; | ||
517 | int status; | ||
518 | size_t n_to_write; | ||
519 | |||
520 | if (lb->buf->input == NULL((void*)0)) | ||
521 | abort (); | ||
522 | |||
523 | status = (*lb->buf->input) (lb->buf->closure, data, need, size, got); | ||
524 | if (status != 0) | ||
525 | return status; | ||
526 | |||
527 | if (*got > 0) | ||
528 | { | ||
529 | n_to_write = *got; | ||
530 | if (fwrite (data, 1, n_to_write, lb->log) != n_to_write) | ||
531 | error (0, errno(*__errno()), "writing to log file"); | ||
532 | } | ||
533 | |||
534 | return 0; | ||
535 | } | ||
536 | |||
537 | /* The output function for a log buffer. */ | ||
538 | |||
539 | static int | ||
540 | log_buffer_output (closure, data, have, wrote) | ||
541 | void *closure; | ||
542 | const char *data; | ||
543 | int have; | ||
544 | int *wrote; | ||
545 | { | ||
546 | struct log_buffer *lb = (struct log_buffer *) closure; | ||
547 | int status; | ||
548 | size_t n_to_write; | ||
549 | |||
550 | if (lb->buf->output == NULL((void*)0)) | ||
551 | abort (); | ||
552 | |||
553 | status = (*lb->buf->output) (lb->buf->closure, data, have, wrote); | ||
554 | if (status != 0) | ||
555 | return status; | ||
556 | |||
557 | if (*wrote > 0) | ||
558 | { | ||
559 | n_to_write = *wrote; | ||
560 | if (fwrite (data, 1, n_to_write, lb->log) != n_to_write) | ||
561 | error (0, errno(*__errno()), "writing to log file"); | ||
562 | } | ||
563 | |||
564 | return 0; | ||
565 | } | ||
566 | |||
567 | /* The flush function for a log buffer. */ | ||
568 | |||
569 | static int | ||
570 | log_buffer_flush (closure) | ||
571 | void *closure; | ||
572 | { | ||
573 | struct log_buffer *lb = (struct log_buffer *) closure; | ||
574 | |||
575 | if (lb->buf->flush == NULL((void*)0)) | ||
576 | abort (); | ||
577 | |||
578 | /* We don't really have to flush the log file here, but doing it | ||
579 | will let tail -f on the log file show what is sent to the | ||
580 | network as it is sent. */ | ||
581 | if (fflush (lb->log) != 0) | ||
582 | error (0, errno(*__errno()), "flushing log file"); | ||
583 | |||
584 | return (*lb->buf->flush) (lb->buf->closure); | ||
585 | } | ||
586 | |||
587 | /* The block function for a log buffer. */ | ||
588 | |||
589 | static int | ||
590 | log_buffer_block (closure, block) | ||
591 | void *closure; | ||
592 | int block; | ||
593 | { | ||
594 | struct log_buffer *lb = (struct log_buffer *) closure; | ||
595 | |||
596 | if (block) | ||
597 | return set_block (lb->buf); | ||
598 | else | ||
599 | return set_nonblock (lb->buf); | ||
600 | } | ||
601 | |||
602 | /* The shutdown function for a log buffer. */ | ||
603 | |||
604 | static int | ||
605 | log_buffer_shutdown (closure) | ||
606 | void *closure; | ||
607 | { | ||
608 | struct log_buffer *lb = (struct log_buffer *) closure; | ||
609 | int retval; | ||
610 | |||
611 | retval = buf_shutdown (lb->buf); | ||
612 | if (fclose (lb->log) < 0) | ||
613 | error (0, errno(*__errno()), "closing log file"); | ||
614 | return retval; | ||
615 | } | ||
616 | |||
617 | #ifdef NO_SOCKET_TO_FD | ||
618 | |||
619 | /* Under certain circumstances, we must communicate with the server | ||
620 | via a socket using send() and recv(). This is because under some | ||
621 | operating systems (OS/2 and Windows 95 come to mind), a socket | ||
622 | cannot be converted to a file descriptor -- it must be treated as a | ||
623 | socket and nothing else. | ||
624 | |||
625 | We may also need to deal with socket routine error codes differently | ||
626 | in these cases. This is handled through the SOCK_ERRNO and | ||
627 | SOCK_STRERROR macros. */ | ||
628 | |||
629 | static int use_socket_style = 0; | ||
630 | static int server_sock; | ||
631 | |||
632 | /* These routines implement a buffer structure which uses send and | ||
633 | recv. The buffer is always in blocking mode so we don't implement | ||
634 | the block routine. */ | ||
635 | |||
636 | /* Note that it is important that these routines always handle errors | ||
637 | internally and never return a positive errno code, since it would in | ||
638 | general be impossible for the caller to know in general whether any | ||
639 | error code came from a socket routine (to decide whether to use | ||
640 | SOCK_STRERROR or simply strerror to print an error message). */ | ||
641 | |||
642 | /* We use an instance of this structure as the closure field. */ | ||
643 | |||
644 | struct socket_buffer | ||
645 | { | ||
646 | /* The socket number. */ | ||
647 | int socket; | ||
648 | }; | ||
649 | |||
650 | static struct buffer *socket_buffer_initialize | ||
651 | PROTO ((int, int, void (*) (struct buffer *)))(int, int, void (*) (struct buffer *)); | ||
652 | static int socket_buffer_input PROTO((void *, char *, int, int, int *))(void *, char *, int, int, int *); | ||
653 | static int socket_buffer_output PROTO((void *, const char *, int, int *))(void *, const char *, int, int *); | ||
654 | static int socket_buffer_flush PROTO((void *))(void *); | ||
655 | |||
656 | /* Create a buffer based on a socket. */ | ||
657 | |||
658 | static struct buffer * | ||
659 | socket_buffer_initialize (socket, input, memory) | ||
660 | int socket; | ||
661 | int input; | ||
662 | void (*memory) PROTO((struct buffer *))(struct buffer *); | ||
663 | { | ||
664 | struct socket_buffer *n; | ||
665 | |||
666 | n = (struct socket_buffer *) xmalloc (sizeof *n); | ||
667 | n->socket = socket; | ||
668 | return buf_initialize (input ? socket_buffer_input : NULL((void*)0), | ||
669 | input ? NULL((void*)0) : socket_buffer_output, | ||
670 | input ? NULL((void*)0) : socket_buffer_flush, | ||
671 | (int (*) PROTO((void *, int))(void *, int)) NULL((void*)0), | ||
672 | (int (*) PROTO((void *))(void *)) NULL((void*)0), | ||
673 | memory, | ||
674 | n); | ||
675 | } | ||
676 | |||
677 | /* The buffer input function for a buffer built on a socket. */ | ||
678 | |||
679 | static int | ||
680 | socket_buffer_input (closure, data, need, size, got) | ||
681 | void *closure; | ||
682 | char *data; | ||
683 | int need; | ||
684 | int size; | ||
685 | int *got; | ||
686 | { | ||
687 | struct socket_buffer *sb = (struct socket_buffer *) closure; | ||
688 | int nbytes; | ||
689 | |||
690 | /* I believe that the recv function gives us exactly the semantics | ||
691 | we want. If there is a message, it returns immediately with | ||
692 | whatever it could get. If there is no message, it waits until | ||
693 | one comes in. In other words, it is not like read, which in | ||
694 | blocking mode normally waits until all the requested data is | ||
695 | available. */ | ||
696 | |||
697 | *got = 0; | ||
698 | |||
699 | do | ||
700 | { | ||
701 | |||
702 | /* Note that for certain (broken?) networking stacks, like | ||
703 | VMS's UCX (not sure what version, problem reported with | ||
704 | recv() in 1997), and (according to windows-NT/config.h) | ||
705 | Windows NT 3.51, we must call recv or send with a | ||
706 | moderately sized buffer (say, less than 200K or something), | ||
707 | or else there may be network errors (somewhat hard to | ||
708 | produce, e.g. WAN not LAN or some such). buf_read_data | ||
709 | makes sure that we only recv() BUFFER_DATA_SIZE bytes at | ||
710 | a time. */ | ||
711 | |||
712 | nbytes = recv (sb->socket, data, size, 0); | ||
713 | if (nbytes < 0) | ||
714 | error (1, 0, "reading from server: %s", SOCK_STRERRORstrerror (SOCK_ERRNO(*__errno()))); | ||
715 | if (nbytes == 0) | ||
716 | { | ||
717 | /* End of file (for example, the server has closed | ||
718 | the connection). If we've already read something, we | ||
719 | just tell the caller about the data, not about the end of | ||
720 | file. If we've read nothing, we return end of file. */ | ||
721 | if (*got == 0) | ||
722 | return -1; | ||
723 | else | ||
724 | return 0; | ||
725 | } | ||
726 | need -= nbytes; | ||
727 | size -= nbytes; | ||
728 | data += nbytes; | ||
729 | *got += nbytes; | ||
730 | } | ||
731 | while (need > 0); | ||
732 | |||
733 | return 0; | ||
734 | } | ||
735 | |||
736 | /* The buffer output function for a buffer built on a socket. */ | ||
737 | |||
738 | static int | ||
739 | socket_buffer_output (closure, data, have, wrote) | ||
740 | void *closure; | ||
741 | const char *data; | ||
742 | int have; | ||
743 | int *wrote; | ||
744 | { | ||
745 | struct socket_buffer *sb = (struct socket_buffer *) closure; | ||
746 | |||
747 | *wrote = have; | ||
748 | |||
749 | /* See comment in socket_buffer_input regarding buffer size we pass | ||
750 | to send and recv. */ | ||
751 | |||
752 | #ifdef SEND_NEVER_PARTIAL | ||
753 | /* If send() never will produce a partial write, then just do it. This | ||
754 | is needed for systems where its return value is something other than | ||
755 | the number of bytes written. */ | ||
756 | if (send (sb->socket, data, have, 0) < 0) | ||
757 | error (1, 0, "writing to server socket: %s", SOCK_STRERRORstrerror (SOCK_ERRNO(*__errno()))); | ||
758 | #else | ||
759 | while (have > 0) | ||
760 | { | ||
761 | int nbytes; | ||
762 | |||
763 | nbytes = send (sb->socket, data, have, 0); | ||
764 | if (nbytes < 0) | ||
765 | error (1, 0, "writing to server socket: %s", SOCK_STRERRORstrerror (SOCK_ERRNO(*__errno()))); | ||
766 | |||
767 | have -= nbytes; | ||
768 | data += nbytes; | ||
769 | } | ||
770 | #endif | ||
771 | |||
772 | return 0; | ||
773 | } | ||
774 | |||
775 | /* The buffer flush function for a buffer built on a socket. */ | ||
776 | |||
777 | /*ARGSUSED*/ | ||
778 | static int | ||
779 | socket_buffer_flush (closure) | ||
780 | void *closure; | ||
781 | { | ||
782 | /* Nothing to do. Sockets are always flushed. */ | ||
783 | return 0; | ||
784 | } | ||
785 | |||
786 | #endif /* NO_SOCKET_TO_FD */ | ||
787 | |||
788 | /* | ||
789 | * Read a line from the server. Result does not include the terminating \n. | ||
790 | * | ||
791 | * Space for the result is malloc'd and should be freed by the caller. | ||
792 | * | ||
793 | * Returns number of bytes read. | ||
794 | */ | ||
795 | static int | ||
796 | read_line (resultp) | ||
797 | char **resultp; | ||
798 | { | ||
799 | int status; | ||
800 | char *result; | ||
801 | int len; | ||
802 | |||
803 | status = buf_flush (to_server, 1); | ||
804 | if (status != 0) | ||
805 | error (1, status, "writing to server"); | ||
806 | |||
807 | status = buf_read_line (from_server, &result, &len); | ||
808 | if (status != 0) | ||
809 | { | ||
810 | if (status == -1) | ||
811 | error (1, 0, "end of file from server (consult above messages if any)"); | ||
812 | else if (status == -2) | ||
813 | error (1, 0, "out of memory"); | ||
814 | else | ||
815 | error (1, status, "reading from server"); | ||
816 | } | ||
817 | |||
818 | if (resultp != NULL((void*)0)) | ||
819 | *resultp = result; | ||
820 | else | ||
821 | free (result); | ||
822 | |||
823 | return len; | ||
824 | } | ||
825 | |||
826 | #endif /* CLIENT_SUPPORT */ | ||
827 | |||
828 | |||
829 | #if defined(CLIENT_SUPPORT1) || defined(SERVER_SUPPORT1) | ||
830 | |||
831 | /* | ||
832 | * Zero if compression isn't supported or requested; non-zero to indicate | ||
833 | * a compression level to request from gzip. | ||
834 | */ | ||
835 | int gzip_level; | ||
836 | |||
837 | /* | ||
838 | * Level of compression to use when running gzip on a single file. | ||
839 | */ | ||
840 | int file_gzip_level; | ||
841 | |||
842 | #endif /* CLIENT_SUPPORT or SERVER_SUPPORT */ | ||
843 | |||
844 | #ifdef CLIENT_SUPPORT1 | ||
845 | |||
846 | /* | ||
847 | * The Repository for the top level of this command (not necessarily | ||
848 | * the CVSROOT, just the current directory at the time we do it). | ||
849 | */ | ||
850 | static char *toplevel_repos = NULL((void*)0); | ||
851 | |||
852 | /* Working directory when we first started. Note: we could speed things | ||
853 | up on some systems by using savecwd.h here instead of just always | ||
854 | storing a name. */ | ||
855 | char *toplevel_wd; | ||
856 | |||
857 | static void | ||
858 | handle_ok (args, len) | ||
859 | char *args; | ||
860 | int len; | ||
861 | { | ||
862 | return; | ||
863 | } | ||
864 | |||
865 | static void | ||
866 | handle_error (args, len) | ||
867 | char *args; | ||
868 | int len; | ||
869 | { | ||
870 | int something_printed; | ||
871 | |||
872 | /* | ||
873 | * First there is a symbolic error code followed by a space, which | ||
874 | * we ignore. | ||
875 | */ | ||
876 | char *p = strchr (args, ' '); | ||
877 | if (p == NULL((void*)0)) | ||
878 | { | ||
879 | error (0, 0, "invalid data from cvs server"); | ||
880 | return; | ||
881 | } | ||
882 | ++p; | ||
883 | |||
884 | /* Next we print the text of the message from the server. We | ||
885 | probably should be prefixing it with "server error" or some | ||
886 | such, because if it is something like "Out of memory", the | ||
887 | current behavior doesn't say which machine is out of | ||
888 | memory. */ | ||
889 | |||
890 | len -= p - args; | ||
891 | something_printed = 0; | ||
892 | for (; len > 0; --len) | ||
893 | { | ||
894 | something_printed = 1; | ||
895 | putc (*p++, stderr)(!__isthreaded ? __sputc(*p++, (&__sF[2])) : (putc)(*p++, (&__sF[2]))); | ||
896 | } | ||
897 | if (something_printed) | ||
898 | putc ('\n', stderr)(!__isthreaded ? __sputc('\n', (&__sF[2])) : (putc)('\n', (&__sF[2]))); | ||
899 | } | ||
900 | |||
901 | static void | ||
902 | handle_valid_requests (args, len) | ||
903 | char *args; | ||
904 | int len; | ||
905 | { | ||
906 | char *p = args; | ||
907 | char *q; | ||
908 | struct request *rq; | ||
909 | do | ||
910 | { | ||
911 | q = strchr (p, ' '); | ||
912 | if (q != NULL((void*)0)) | ||
913 | *q++ = '\0'; | ||
914 | for (rq = requests; rq->name != NULL((void*)0); ++rq) | ||
915 | { | ||
916 | if (strcmp (rq->name, p) == 0) | ||
917 | break; | ||
918 | } | ||
919 | if (rq->name == NULL((void*)0)) | ||
920 | /* | ||
921 | * It is a request we have never heard of (and thus never | ||
922 | * will want to use). So don't worry about it. | ||
923 | */ | ||
924 | ; | ||
925 | else | ||
926 | { | ||
927 | if (rq->flags & RQ_ENABLEME4) | ||
928 | { | ||
929 | /* | ||
930 | * Server wants to know if we have this, to enable the | ||
931 | * feature. | ||
932 | */ | ||
933 | send_to_server (rq->name, 0); | ||
934 | send_to_server ("\012", 0); | ||
935 | } | ||
936 | else | ||
937 | rq->flags |= RQ_SUPPORTED2; | ||
938 | } | ||
939 | p = q; | ||
940 | } while (q != NULL((void*)0)); | ||
941 | for (rq = requests; rq->name != NULL((void*)0); ++rq) | ||
942 | { | ||
943 | if ((rq->flags & RQ_SUPPORTED2) | ||
944 | || (rq->flags & RQ_ENABLEME4)) | ||
945 | continue; | ||
946 | if (rq->flags & RQ_ESSENTIAL1) | ||
947 | error (1, 0, "request `%s' not supported by server", rq->name); | ||
948 | } | ||
949 | } | ||
950 | |||
951 | /* This variable holds the result of Entries_Open, so that we can | ||
952 | close Entries_Close on it when we move on to a new directory, or | ||
953 | when we finish. */ | ||
954 | static List *last_entries; | ||
955 | |||
956 | /* | ||
957 | * Do all the processing for PATHNAME, where pathname consists of the | ||
958 | * repository and the filename. The parameters we pass to FUNC are: | ||
959 | * DATA is just the DATA parameter which was passed to | ||
960 | * call_in_directory; ENT_LIST is a pointer to an entries list (which | ||
961 | * we manage the storage for); SHORT_PATHNAME is the pathname of the | ||
962 | * file relative to the (overall) directory in which the command is | ||
963 | * taking place; and FILENAME is the filename portion only of | ||
964 | * SHORT_PATHNAME. When we call FUNC, the curent directory points to | ||
965 | * the directory portion of SHORT_PATHNAME. */ | ||
966 | |||
967 | static char *last_dir_name; | ||
968 | |||
969 | static void | ||
970 | call_in_directory (pathname, func, data) | ||
971 | char *pathname; | ||
972 | void (*func) PROTO((char *data, List *ent_list, char *short_pathname,(char *data, List *ent_list, char *short_pathname, char *filename ) | ||
973 | char *filename))(char *data, List *ent_list, char *short_pathname, char *filename ); | ||
974 | char *data; | ||
975 | { | ||
976 | char *dir_name; | ||
977 | char *filename; | ||
978 | /* This is what we get when we hook up the directory (working directory | ||
979 | name) from PATHNAME with the filename from REPOSNAME. For example: | ||
980 | pathname: ccvs/src/ | ||
981 | reposname: /u/src/master/ccvs/foo/ChangeLog | ||
982 | short_pathname: ccvs/src/ChangeLog | ||
983 | */ | ||
984 | char *short_pathname; | ||
985 | char *p; | ||
986 | |||
987 | /* | ||
988 | * Do the whole descent in parallel for the repositories, so we | ||
989 | * know what to put in CVS/Repository files. I'm not sure the | ||
990 | * full hair is necessary since the server does a similar | ||
991 | * computation; I suspect that we only end up creating one | ||
992 | * directory at a time anyway. | ||
993 | * | ||
994 | * Also note that we must *only* worry about this stuff when we | ||
995 | * are creating directories; `cvs co foo/bar; cd foo/bar; cvs co | ||
996 | * CVSROOT; cvs update' is legitimate, but in this case | ||
997 | * foo/bar/CVSROOT/CVS/Repository is not a subdirectory of | ||
998 | * foo/bar/CVS/Repository. | ||
999 | */ | ||
1000 | char *reposname; | ||
1001 | char *short_repos; | ||
1002 | char *reposdirname; | ||
1003 | char *rdirp; | ||
1004 | int reposdirname_absolute; | ||
1005 | |||
1006 | /* | ||
1007 | * For security reasons, if PATHNAME is absolute or attempts to | ||
1008 | * ascend outside of the current sandbox, we abort. The server should not | ||
1009 | * send us anything but relative paths which remain inside the sandbox | ||
1010 | * here. Anything less means a trojan CVS server could create and edit | ||
1011 | * arbitrary files on the client. | ||
1012 | */ | ||
1013 | if (isabsolute (pathname) || pathname_levels (pathname) > 0) | ||
1014 | { | ||
1015 | error (0, 0, | ||
1016 | "Server attempted to update a file via an invalid pathname:"); | ||
1017 | error (1, 0, "`%s'.", pathname); | ||
1018 | } | ||
1019 | |||
1020 | reposname = NULL((void*)0); | ||
1021 | read_line (&reposname); | ||
1022 | assert (reposname != NULL)((reposname != ((void*)0)) ? (void)0 : __assert2("/usr/src/gnu/usr.bin/cvs/src/client.c" , 1022, __func__, "reposname != NULL")); | ||
1023 | |||
1024 | reposdirname_absolute = 0; | ||
1025 | if (strncmp (reposname, toplevel_repos, strlen (toplevel_repos)) != 0) | ||
1026 | { | ||
1027 | reposdirname_absolute = 1; | ||
1028 | short_repos = reposname; | ||
1029 | } | ||
1030 | else | ||
1031 | { | ||
1032 | short_repos = reposname + strlen (toplevel_repos) + 1; | ||
1033 | if (short_repos[-1] != '/') | ||
1034 | { | ||
1035 | reposdirname_absolute = 1; | ||
1036 | short_repos = reposname; | ||
1037 | } | ||
1038 | } | ||
1039 | reposdirname = xstrdup (short_repos); | ||
1040 | p = strrchr (reposdirname, '/'); | ||
1041 | if (p == NULL((void*)0)) | ||
1042 | { | ||
1043 | reposdirname = xrealloc (reposdirname, 2); | ||
1044 | reposdirname[0] = '.'; reposdirname[1] = '\0'; | ||
1045 | } | ||
1046 | else | ||
1047 | *p = '\0'; | ||
1048 | |||
1049 | dir_name = xstrdup (pathname); | ||
1050 | p = strrchr (dir_name, '/'); | ||
1051 | if (p == NULL((void*)0)) | ||
1052 | { | ||
1053 | dir_name = xrealloc (dir_name, 2); | ||
1054 | dir_name[0] = '.'; dir_name[1] = '\0'; | ||
1055 | } | ||
1056 | else | ||
1057 | *p = '\0'; | ||
1058 | if (client_prune_dirs) | ||
1059 | add_prune_candidate (dir_name); | ||
1060 | |||
1061 | filename = strrchr (short_repos, '/'); | ||
1062 | if (filename == NULL((void*)0)) | ||
1063 | filename = short_repos; | ||
1064 | else | ||
1065 | ++filename; | ||
1066 | |||
1067 | short_pathname = xmalloc (strlen (pathname) + strlen (filename) + 5); | ||
1068 | strcpy (short_pathname, pathname); | ||
1069 | strcat (short_pathname, filename); | ||
1070 | |||
1071 | if (last_dir_name == NULL((void*)0) | ||
1072 | || strcmp (last_dir_name, dir_name) != 0) | ||
1073 | { | ||
1074 | int newdir; | ||
1075 | |||
1076 | if (strcmp (command_name, "export") != 0) | ||
1077 | if (last_entries) | ||
1078 | Entries_Close (last_entries); | ||
1079 | |||
1080 | if (last_dir_name
| ||
1081 | free (last_dir_name); | ||
1082 | last_dir_name = dir_name; | ||
1083 | |||
1084 | if (toplevel_wd == NULL((void*)0)) | ||
1085 | { | ||
1086 | toplevel_wd = xgetwd (); | ||
1087 | if (toplevel_wd == NULL((void*)0)) | ||
1088 | error (1, errno(*__errno()), "could not get working directory"); | ||
1089 | } | ||
1090 | |||
1091 | if (CVS_CHDIRchdir (toplevel_wd) < 0) | ||
1092 | error (1, errno(*__errno()), "could not chdir to %s", toplevel_wd); | ||
1093 | newdir = 0; | ||
1094 | |||
1095 | /* Create the CVS directory at the top level if needed. The | ||
1096 | isdir seems like an unneeded system call, but it *does* | ||
1097 | need to be called both if the CVS_CHDIR below succeeds | ||
1098 | (e.g. "cvs co .") or if it fails (e.g. basicb-1a in | ||
1099 | testsuite). We only need to do this for the "." case, | ||
1100 | since the server takes care of forcing this directory to be | ||
1101 | created in all other cases. If we don't create CVSADM | ||
1102 | here, the call to Entries_Open below will fail. FIXME: | ||
1103 | perhaps this means that we should change our algorithm | ||
1104 | below that calls Create_Admin instead of having this code | ||
1105 | here? */ | ||
1106 | if (/* I think the reposdirname_absolute case has to do with | ||
1107 | things like "cvs update /foo/bar". In any event, the | ||
1108 | code below which tries to put toplevel_repos into | ||
1109 | CVS/Repository is almost surely unsuited to | ||
1110 | the reposdirname_absolute case. */ | ||
1111 | !reposdirname_absolute |
26.1 | 'reposdirname_absolute' is 0 |
43 | Null pointer passed as 1st argument to string length function |
1 | Calling 'call_in_directory' |