386BSD 0.1 development
[unix-history] / usr / othersrc / contrib / isode / psap / dg2ps.c
CommitLineData
cf908fd1
WJ
1/* dg2ps.c - datagram-backed abstraction for PStreams */
2
3#ifndef lint
4static char *rcsid = "$Header: /f/osi/psap/RCS/dg2ps.c,v 7.3 91/02/22 09:35:36 mrose Interim $";
5#endif
6
7/*
8 * $Header: /f/osi/psap/RCS/dg2ps.c,v 7.3 91/02/22 09:35:36 mrose Interim $
9 *
10 *
11 * $Log: dg2ps.c,v $
12 * Revision 7.3 91/02/22 09:35:36 mrose
13 * Interim 6.8
14 *
15 * Revision 7.2 91/01/07 12:40:25 mrose
16 * update
17 *
18 * Revision 7.1 90/08/08 14:02:31 mrose
19 * stuff
20 *
21 * Revision 7.0 89/11/23 22:12:34 mrose
22 * Release 6.0
23 *
24 */
25
26/*
27 * NOTICE
28 *
29 * Acquisition, use, and distribution of this module and related
30 * materials are subject to the restrictions of a license agreement.
31 * Consult the Preface in the User's Manual for the full terms of
32 * this agreement.
33 *
34 */
35
36
37/* LINTLIBRARY */
38
39#include <stdio.h>
40#include "psap.h"
41
42
43struct ps_dg {
44 int ps_fd;
45 int ps_maxsize;
46
47 struct ps_inout {
48 struct qbuf *pio_qb;
49 char *pio_ptr;
50 int pio_cnt;
51
52 IFP pio_fnx;
53 } ps_input,
54 ps_output;
55
56 IFP ps_check;
57};
58
59
60extern IFP set_check_fd ();
61
62/* \f */
63
64static int dg_prime (ps, waiting)
65register PS ps;
66int waiting;
67{
68 struct qbuf *qb;
69 register struct ps_dg *pt = (struct ps_dg *) ps -> ps_addr;
70 register struct ps_inout *pi = &pt -> ps_input;
71
72 switch (waiting) {
73 case 0:
74 if (pi -> pio_cnt > 0)
75 return OK;
76 break;
77
78 case 1:
79 default:
80 return (pi -> pio_cnt > 0 ? DONE : OK);
81
82 case -1:
83 if (pi -> pio_cnt <= 0)
84 return OK;
85 break;
86 }
87
88 if (pi -> pio_qb != NULL) {
89 qb_free (pi -> pio_qb);
90 pi -> pio_qb = NULL;
91 }
92 pi -> pio_cnt = 0;
93
94 if (waiting < 0)
95 return ps_seterr (ps, PS_ERR_EXTRA, NOTOK);
96
97 if ((*pi -> pio_fnx) (pt -> ps_fd, &qb) == NOTOK)
98 return ps_seterr (ps, PS_ERR_IO, NOTOK);
99
100 if (pi -> pio_qb = qb)
101 pi -> pio_ptr = qb -> qb_data, pi -> pio_cnt = qb -> qb_len;
102 else
103 pi -> pio_ptr = NULL, pi -> pio_cnt = 0;
104
105 return OK;
106}
107
108
109/* ARGSUSED */
110
111static int dg_read (ps, data, n, in_line)
112register PS ps;
113PElementData data;
114PElementLen n;
115int in_line;
116{
117 int cc;
118 register struct ps_dg *pt = (struct ps_dg *) ps -> ps_addr;
119 register struct ps_inout *pi = &pt -> ps_input;
120
121 if ((cc = pi -> pio_cnt) <= 0)
122 return 0;
123 if (cc > n)
124 cc = n;
125
126 bcopy (pi -> pio_ptr, (char *) data, cc);
127 pi -> pio_ptr += cc, pi -> pio_cnt -= cc;
128
129 return cc;
130}
131
132
133/* ARGSUSED */
134
135static int dg_write (ps, data, n, in_line)
136register PS ps;
137PElementData data;
138PElementLen n;
139int in_line;
140{
141 register struct ps_dg *pt = (struct ps_dg *) ps -> ps_addr;
142 register struct ps_inout *po = &pt -> ps_output;
143
144 if (po -> pio_cnt < n)
145 return 0;
146
147 bcopy ((char *) data, po -> pio_ptr, n);
148 po -> pio_ptr += n, po -> pio_cnt -= n;
149
150 return n;
151}
152
153
154static int dg_flush (ps)
155register PS ps;
156{
157 register struct ps_dg *pt = (struct ps_dg *) ps -> ps_addr;
158 register struct ps_inout *po = &pt -> ps_output;
159 register struct qbuf *qb = po -> pio_qb;
160
161 qb -> qb_len = po -> pio_ptr - qb -> qb_data;
162 if ((*po -> pio_fnx) (pt -> ps_fd, qb) != qb -> qb_len)
163 return ps_seterr (ps, PS_ERR_IO, NOTOK);
164
165 po -> pio_ptr = qb -> qb_data, po -> pio_cnt = pt -> ps_maxsize;
166
167 return OK;
168}
169
170
171static int dg_close (ps)
172register PS ps;
173{
174 register struct ps_dg *pt = (struct ps_dg *) ps -> ps_addr;
175
176 if (pt == NULL)
177 return OK;
178
179 if (pt -> ps_input.pio_qb)
180 qb_free (pt -> ps_input.pio_qb);
181 if (pt -> ps_output.pio_qb)
182 qb_free (pt -> ps_output.pio_qb);
183
184 (void) set_check_fd (pt -> ps_fd, NULLIFP, NULLCP);
185
186 free ((char *) pt);
187
188 return OK;
189}
190
191
192static int dg_check (fd, data)
193int fd;
194caddr_t data;
195{
196 int n;
197 PS ps = (PS) data;
198 register struct ps_dg *pt = (struct ps_dg *) ps -> ps_addr;
199
200 if (pt -> ps_check && (n = (*pt -> ps_check) (fd)))
201 return n;
202
203 return (ps_prime (ps, 1) > 0 ? DONE : OK);
204}
205
206/* \f */
207
208int dg_open (ps)
209register PS ps;
210{
211 ps -> ps_primeP = dg_prime;
212 ps -> ps_readP = dg_read;
213 ps -> ps_writeP = dg_write;
214 ps -> ps_flushP = dg_flush;
215 ps -> ps_closeP = dg_close;
216
217 return OK;
218}
219
220
221int dg_setup (ps, fd, size, rfx, wfx, cfx)
222register PS ps;
223int fd,
224 size;
225IFP rfx,
226 wfx,
227 cfx;
228{
229 register struct ps_dg *pt;
230 register struct ps_inout *po;
231 register struct qbuf *qb;
232
233 if ((pt = (struct ps_dg *) calloc (1, sizeof *pt)) == NULL)
234 return ps_seterr (ps, PS_ERR_NMEM, NOTOK);
235 ps -> ps_addr = (caddr_t) pt;
236
237 pt -> ps_fd = fd;
238 pt -> ps_maxsize = size;
239
240 if ((qb = (struct qbuf *) malloc (sizeof *qb
241 + (unsigned) pt -> ps_maxsize))
242 == NULL)
243 return ps_seterr (ps, PS_ERR_NMEM, NOTOK);
244 qb -> qb_forw = qb -> qb_back = qb;
245 qb -> qb_len = 0;
246 qb -> qb_data = qb -> qb_base;
247
248 po = &pt -> ps_output;
249 po -> pio_qb = qb;
250 po -> pio_ptr = qb -> qb_data, po -> pio_cnt = pt -> ps_maxsize;
251 if ((pt -> ps_input.pio_fnx = rfx) == NULLIFP
252 || (po -> pio_fnx = wfx) == NULLIFP)
253 return ps_seterr (ps, PS_ERR_XXX, NOTOK);
254
255 pt -> ps_check = cfx;
256 (void) set_check_fd (fd, dg_check, (caddr_t) ps);
257
258 return OK;
259}