1 /* CVS client logging buffer.
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details. */
22 /* We want to be able to log data sent between us and the server. We
23 do it using log buffers. Each log buffer has another buffer which
24 handles the actual I/O, and a file to log information to.
26 This structure is the closure field of a log buffer. */
30 /* The underlying buffer. */
32 /* The file to log information to. */
36 static int log_buffer_input (void *, char *, int, int, int *);
37 static int log_buffer_output (void *, const char *, int, int *);
38 static int log_buffer_flush (void *);
39 static int log_buffer_block (void *, int);
40 static int log_buffer_shutdown (struct buffer *);
42 /* Create a log buffer. */
44 static struct buffer *
45 log_buffer_initialize (struct buffer *buf, FILE *fp, int input, void (*memory) (struct buffer *))
49 n = (struct log_buffer *) xmalloc (sizeof *n);
52 return buf_initialize (input ? log_buffer_input : NULL,
53 input ? NULL : log_buffer_output,
54 input ? NULL : log_buffer_flush,
61 /* The input function for a log buffer. */
64 log_buffer_input (void *closure, char *data, int need, int size, int *got)
66 struct log_buffer *lb = (struct log_buffer *) closure;
70 if (lb->buf->input == NULL)
73 status = (*lb->buf->input) (lb->buf->closure, data, need, size, got);
80 if (fwrite (data, 1, n_to_write, lb->log) != n_to_write)
81 error (0, errno, "writing to log file");
87 /* The output function for a log buffer. */
90 log_buffer_output (void *closure, const char *data, int have, int *wrote)
92 struct log_buffer *lb = (struct log_buffer *) closure;
96 if (lb->buf->output == NULL)
99 status = (*lb->buf->output) (lb->buf->closure, data, have, wrote);
106 if (fwrite (data, 1, n_to_write, lb->log) != n_to_write)
107 error (0, errno, "writing to log file");
113 /* The flush function for a log buffer. */
116 log_buffer_flush (void *closure)
118 struct log_buffer *lb = (struct log_buffer *) closure;
120 if (lb->buf->flush == NULL)
123 /* We don't really have to flush the log file here, but doing it
124 will let tail -f on the log file show what is sent to the
125 network as it is sent. */
126 if (fflush (lb->log) != 0)
127 error (0, errno, "flushing log file");
129 return (*lb->buf->flush) (lb->buf->closure);
132 /* The block function for a log buffer. */
135 log_buffer_block (void *closure, int block)
137 struct log_buffer *lb = (struct log_buffer *) closure;
140 return set_block (lb->buf);
142 return set_nonblock (lb->buf);
145 /* The shutdown function for a log buffer. */
148 log_buffer_shutdown (struct buffer *buf)
150 struct log_buffer *lb = (struct log_buffer *) buf->closure;
153 retval = buf_shutdown (lb->buf);
154 if (fclose (lb->log) < 0)
155 error (0, errno, "closing log file");
161 setup_logfiles (struct buffer **to_server_p, struct buffer **from_server_p)
163 char *log = getenv ("CVS_CLIENT_LOG");
165 /* Set up logfiles, if any.
167 * We do this _after_ authentication on purpose. Wouldn't really like to
168 * worry about logging passwords...
172 int len = strlen (log);
173 char *buf = xmalloc (len + 5);
180 /* Open logfiles in binary mode so that they reflect
181 exactly what was transmitted and received (that is
182 more important than that they be maximally
183 convenient to view). */
184 /* Note that if we create several connections in a single CVS client
185 (currently used by update.c), then the last set of logfiles will
186 overwrite the others. There is currently no way around this. */
188 fp = open_file (buf, "wb");
190 error (0, errno, "opening to-server logfile %s", buf);
192 *to_server_p = log_buffer_initialize (*to_server_p, fp, 0,
193 (BUFMEMERRPROC) NULL);
196 fp = open_file (buf, "wb");
198 error (0, errno, "opening from-server logfile %s", buf);
200 *from_server_p = log_buffer_initialize (*from_server_p, fp, 1,
201 (BUFMEMERRPROC) NULL);
207 #endif /* CLIENT_SUPPORT */