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