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