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