]> diplodocus.org Git - nmh/blob - uip/vmhsbr.c
Formatting cleanup.
[nmh] / uip / vmhsbr.c
1
2 /*
3 * vmhsbr.c -- routines to help vmh along
4 *
5 * This code is Copyright (c) 2002, by the authors of nmh. See the
6 * COPYRIGHT file in the root directory of the nmh distribution for
7 * complete copyright information.
8 */
9
10 /*
11 * TODO (for vrsn 2):
12 * INI: include width of windows
13 */
14
15 #include <h/mh.h>
16 #include <h/vmhsbr.h>
17 #include <h/utils.h>
18 #include <errno.h>
19
20 static char *types[] = {
21 "OK",
22 "INI", "ACK", "ERR", "CMD", "QRY", "TTY", "WIN", "DATA", "EOF", "FIN",
23 "XXX", NULL
24 };
25
26 static FILE *fp = NULL;
27
28 static int PEERrfd = NOTOK;
29 static int PEERwfd = NOTOK;
30
31 /*
32 * static prototypes
33 */
34 static int rclose (struct record *, char *, ...);
35
36
37 int
38 rcinit (int rfd, int wfd)
39 {
40 char *cp, buffer[BUFSIZ];
41
42 PEERrfd = rfd;
43 PEERwfd = wfd;
44
45 if ((cp = getenv ("MHVDEBUG")) && *cp) {
46 snprintf (buffer, sizeof(buffer), "%s.out", invo_name);
47 if ((fp = fopen (buffer, "w"))) {
48 fseek (fp, 0L, SEEK_END);
49 fprintf (fp, "%d: rcinit (%d, %d)\n", (int) getpid(), rfd, wfd);
50 fflush (fp);
51 }
52 }
53
54 return OK;
55 }
56
57
58 int
59 rcdone (void)
60 {
61 if (PEERrfd != NOTOK)
62 close (PEERrfd);
63 if (PEERwfd != NOTOK)
64 close (PEERwfd);
65
66 if (fp) {
67 fclose (fp);
68 fp = NULL;
69 }
70 return OK;
71 }
72
73
74 int
75 rc2rc (char code, int len, char *data, struct record *rc)
76 {
77 if (rc2peer (code, len, data) == NOTOK)
78 return NOTOK;
79
80 return peer2rc (rc);
81 }
82
83
84 int
85 str2rc (char code, char *str, struct record *rc)
86 {
87 return rc2rc (code, str ? strlen (str) : 0, str, rc);
88 }
89
90
91 int
92 peer2rc (struct record *rc)
93 {
94 if (rc->rc_data)
95 free (rc->rc_data);
96
97 if (read (PEERrfd, (char *) rc_head (rc), RHSIZE (rc)) != RHSIZE (rc))
98 return rclose (rc, "read from peer lost(1)");
99 if (rc->rc_len) {
100 rc->rc_data = mh_xmalloc ((unsigned) rc->rc_len + 1);
101 if (read (PEERrfd, rc->rc_data, rc->rc_len) != rc->rc_len)
102 return rclose (rc, "read from peer lost(2)");
103 rc->rc_data[rc->rc_len] = 0;
104 }
105 else
106 rc->rc_data = NULL;
107
108 if (fp) {
109 fseek (fp, 0L, SEEK_END);
110 fprintf (fp, "%d: <--- %s %d: \"%*.*s\"\n", (int) getpid(),
111 types[(unsigned char)rc->rc_type], rc->rc_len,
112 rc->rc_len, rc->rc_len, rc->rc_data);
113 fflush (fp);
114 }
115
116 return rc->rc_type;
117 }
118
119
120 int
121 rc2peer (char code, int len, char *data)
122 {
123 struct record rcs;
124 register struct record *rc = &rcs;
125
126 rc->rc_type = code;
127 rc->rc_len = len;
128
129 if (fp) {
130 fseek (fp, 0L, SEEK_END);
131 fprintf (fp, "%d: ---> %s %d: \"%*.*s\"\n", (int) getpid(),
132 types[(unsigned char)rc->rc_type], rc->rc_len,
133 rc->rc_len, rc->rc_len, data);
134 fflush (fp);
135 }
136
137 if (write (PEERwfd, (char *) rc_head (rc), RHSIZE (rc)) != RHSIZE (rc))
138 return rclose (rc, "write to peer lost(1)");
139
140 if (rc->rc_len)
141 if (write (PEERwfd, data, rc->rc_len) != rc->rc_len)
142 return rclose (rc, "write to peer lost(2)");
143
144 return OK;
145 }
146
147
148 int
149 str2peer (char code, char *str)
150 {
151 return rc2peer (code, str ? strlen (str) : 0, str);
152 }
153
154
155 int
156 fmt2peer (char code, char *fmt, ...)
157 {
158 va_list ap;
159
160 va_start(ap, fmt);
161 return verr2peer (code, NULL, fmt, ap);
162 va_end(ap);
163 }
164
165
166 int
167 err2peer (char code, char *what, char *fmt, ...)
168 {
169 int return_value;
170 va_list ap;
171
172 va_start(ap, fmt);
173 return_value = verr2peer(code, what, fmt, ap);
174 va_end(ap);
175 return return_value; /* This routine returned garbage before 1999-07-15. */
176 }
177
178
179 int
180 verr2peer (char code, char *what, char *fmt, va_list ap)
181 {
182 int eindex = errno;
183 int len, buflen;
184 char *bp, *s, buffer[BUFSIZ * 2];
185
186 /* Get buffer ready to go */
187 bp = buffer;
188 buflen = sizeof(buffer);
189
190 vsnprintf (bp, buflen, fmt, ap);
191 len = strlen (bp);
192 bp += len;
193 buflen -= len;
194
195 if (what) {
196 if (*what) {
197 snprintf (bp, buflen, " %s: ", what);
198 len = strlen (bp);
199 bp += len;
200 buflen -= len;
201 }
202 if ((s = strerror (eindex)))
203 strncpy (bp, s, buflen);
204 else
205 snprintf (bp, buflen, "unknown error %d", eindex);
206 len = strlen (bp);
207 bp += len;
208 buflen -= len;
209 }
210
211 return rc2peer (code, bp - buffer, buffer);
212 }
213
214
215 static int
216 rclose (struct record *rc, char *fmt, ...)
217 {
218 va_list ap;
219 static char buffer[BUFSIZ * 2];
220
221 va_start(ap, fmt);
222 vsnprintf (buffer, sizeof(buffer), fmt, ap);
223 va_end(ap);
224
225 rc->rc_len = strlen (rc->rc_data = getcpy (buffer));
226 return (rc->rc_type = RC_XXX);
227 }