|
|
1.1 root 1: /* ryresponder.c - generic idempotent responder */
2:
3: #ifndef lint
4: static char *rcsid = "$Header: /f/osi/others/lookup/RCS/ryresponder.c,v 7.1 90/07/09 14:39:56 mrose Exp $";
5: #endif
6:
7: /*
8: * $Header: /f/osi/others/lookup/RCS/ryresponder.c,v 7.1 90/07/09 14:39:56 mrose Exp $
9: *
10: *
11: * $Log: ryresponder.c,v $
12: * Revision 7.1 90/07/09 14:39:56 mrose
13: * sync
14: *
15: * Revision 7.0 89/11/23 22:56:44 mrose
16: * Release 6.0
17: *
18: */
19:
20: /*
21: * NOTICE
22: *
23: * Acquisition, use, and distribution of this module and related
24: * materials are subject to the restrictions of a license agreement.
25: * Consult the Preface in the User's Manual for the full terms of
26: * this agreement.
27: *
28: */
29:
30:
31: #include <stdio.h>
32: #include <setjmp.h>
33: #include <varargs.h>
34: #include "ryresponder.h"
35: #include "tsap.h" /* for listening */
36:
37: /* DATA */
38:
39: int debug = 0;
40:
41: static LLog _pgm_log = {
42: "responder.log", NULLCP, NULLCP,
43: LLOG_FATAL | LLOG_EXCEPTIONS | LLOG_NOTICE, LLOG_FATAL, -1,
44: LLOGCLS | LLOGCRT | LLOGZER, NOTOK
45: };
46: LLog *pgm_log = &_pgm_log;
47:
48: static char *myname = "ryresponder";
49:
50:
51: static jmp_buf toplevel;
52:
53:
54: static IFP startfnx;
55: static IFP stopfnx;
56:
57: int ros_init (), ros_work (), ros_indication (), ros_lose ();
58:
59:
60: extern int errno;
61:
62: /* RESPONDER */
63:
64: int ryresponder (argc, argv, host, myservice, mycontext, dispatches, ops,
65: start, stop)
66: int argc;
67: char **argv,
68: *host,
69: *myservice,
70: *mycontext;
71: struct dispatch *dispatches;
72: struct RyOperation *ops;
73: IFP start,
74: stop;
75: {
76: register struct dispatch *ds;
77: AEI aei;
78: struct TSAPdisconnect tds;
79: struct TSAPdisconnect *td = &tds;
80: struct RoSAPindication rois;
81: register struct RoSAPindication *roi = &rois;
82: register struct RoSAPpreject *rop = &roi -> roi_preject;
83:
84: if (myname = rindex (argv[0], '/'))
85: myname++;
86: if (myname == NULL || *myname == NULL)
87: myname = argv[0];
88:
89: isodetailor (myname, 0);
90: if (debug = isatty (fileno (stderr)))
91: ll_dbinit (pgm_log, myname);
92: else {
93: static char myfile[BUFSIZ];
94:
95: (void) sprintf (myfile, "%s.log",
96: (strncmp (myname, "ros.", 4)
97: && strncmp (myname, "lpp.", 4))
98: || myname[4] == NULL
99: ? myname : myname + 4);
100: pgm_log -> ll_file = myfile;
101: ll_hdinit (pgm_log, myname);
102: }
103:
104: advise (LLOG_NOTICE, NULLCP, "starting");
105:
106: if ((aei = str2aei (host, myservice, mycontext, 0)) == NULLAEI)
107: adios (NULLCP, "unable to resolve service);
108:
109: for (ds = dispatches; ds -> ds_name; ds++)
110: if (RyDispatch (NOTOK, ops, ds -> ds_operation, ds -> ds_vector, roi)
111: == NOTOK)
112: ros_adios (rop, ds -> ds_name);
113:
114: startfnx = start;
115: stopfnx = stop;
116:
117: if (isodeserver (argc, argv, aei, ros_init, ros_work, ros_lose, td)
118: == NOTOK) {
119: if (td -> td_cc > 0)
120: adios (NULLCP, "isodeserver: [%s] %*.*s",
121: TErrString (td -> td_reason),
122: td -> td_cc, td -> td_cc, td -> td_data);
123: else
124: adios (NULLCP, "isodeserver: [%s]",
125: TErrString (td -> td_reason));
126: }
127:
128: return 0;
129: }
130:
131: /* */
132:
133: static int ros_init (vecp, vec)
134: int vecp;
135: char **vec;
136: {
137: int reply,
138: result,
139: sd;
140: struct AcSAPstart acss;
141: register struct AcSAPstart *acs = &acss;
142: struct AcSAPindication acis;
143: register struct AcSAPindication *aci = &acis;
144: register struct AcSAPabort *aca = &aci -> aci_abort;
145: register struct PSAPstart *ps = &acs -> acs_start;
146: struct RoSAPindication rois;
147: register struct RoSAPindication *roi = &rois;
148: register struct RoSAPpreject *rop = &roi -> roi_preject;
149:
150: if (AcInit (vecp, vec, acs, aci) == NOTOK) {
151: acs_advise (aca, "initialization fails");
152: return NOTOK;
153: }
154: advise (LLOG_NOTICE, NULLCP,
155: "A-ASSOCIATE.INDICATION: <%d, %s, %s, %s, %d>",
156: acs -> acs_sd, oid2ode (acs -> acs_context),
157: sprintaei (&acs -> acs_callingtitle),
158: sprintaei (&acs -> acs_calledtitle), acs -> acs_ninfo);
159:
160: sd = acs -> acs_sd;
161:
162: for (vec++; *vec; vec++)
163: advise (LLOG_EXCEPTIONS, NULLCP, "unknown argument \"%s\"", *vec);
164:
165: reply = startfnx ? (*startfnx) (sd, acs) : ACS_ACCEPT;
166:
167: result = AcAssocResponse (sd, reply,
168: reply != ACS_ACCEPT ? ACS_USER_NOREASON : ACS_USER_NULL,
169: NULLOID, NULLAEI, NULLPA, NULLPC, ps -> ps_defctxresult,
170: ps -> ps_prequirements, ps -> ps_srequirements, SERIAL_NONE,
171: ps -> ps_settings, &ps -> ps_connect, NULLPEP, 0, aci);
172:
173: ACSFREE (acs);
174:
175: if (result == NOTOK) {
176: acs_advise (aca, "A-ASSOCIATE.RESPONSE");
177: return NOTOK;
178: }
179: if (reply != ACS_ACCEPT)
180: return NOTOK;
181:
182: if (RoSetService (sd, RoPService, roi) == NOTOK)
183: ros_adios (rop, "set RO/PS fails");
184:
185: return sd;
186: }
187:
188: /* */
189:
190: static int ros_work (fd)
191: int fd;
192: {
193: int result;
194: caddr_t out;
195: struct AcSAPindication acis;
196: struct RoSAPindication rois;
197: register struct RoSAPindication *roi = &rois;
198: register struct RoSAPpreject *rop = &roi -> roi_preject;
199:
200: switch (setjmp (toplevel)) {
201: case OK:
202: break;
203:
204: default:
205: if (stopfnx)
206: (*stopfnx) (fd, (struct AcSAPfinish *) 0);
207: case DONE:
208: (void) AcUAbortRequest (fd, NULLPEP, 0, &acis);
209: (void) RyLose (fd, roi);
210: return NOTOK;
211: }
212:
213: switch (result = RyWait (fd, NULLIP, &out, OK, roi)) {
214: case NOTOK:
215: if (rop -> rop_reason == ROS_TIMER)
216: break;
217: case OK:
218: case DONE:
219: ros_indication (fd, roi);
220: break;
221:
222: default:
223: adios (NULLCP, "unknown return from RoWaitRequest=%d", result);
224: }
225:
226: return OK;
227: }
228:
229: /* */
230:
231: static int ros_indication (sd, roi)
232: int sd;
233: register struct RoSAPindication *roi;
234: {
235: int reply,
236: result;
237:
238: switch (roi -> roi_type) {
239: case ROI_INVOKE:
240: case ROI_RESULT:
241: case ROI_ERROR:
242: adios (NULLCP, "unexpected indication type=%d", roi -> roi_type);
243: break;
244:
245: case ROI_UREJECT:
246: {
247: register struct RoSAPureject *rou = &roi -> roi_ureject;
248:
249: if (rou -> rou_noid)
250: advise (LLOG_EXCEPTIONS, NULLCP,
251: "RO-REJECT-U.INDICATION/%d: %s",
252: sd, RoErrString (rou -> rou_reason));
253: else
254: advise (LLOG_EXCEPTIONS, NULLCP,
255: "RO-REJECT-U.INDICATION/%d: %s (id=%d)",
256: sd, RoErrString (rou -> rou_reason),
257: rou -> rou_id);
258: }
259: break;
260:
261: case ROI_PREJECT:
262: {
263: register struct RoSAPpreject *rop = &roi -> roi_preject;
264:
265: if (ROS_FATAL (rop -> rop_reason))
266: ros_adios (rop, "RO-REJECT-P.INDICATION");
267: ros_advise (rop, "RO-REJECT-P.INDICATION");
268: }
269: break;
270:
271: case ROI_FINISH:
272: {
273: register struct AcSAPfinish *acf = &roi -> roi_finish;
274: struct AcSAPindication acis;
275: register struct AcSAPabort *aca = &acis.aci_abort;
276:
277: advise (LLOG_NOTICE, NULLCP, "A-RELEASE.INDICATION/%d: %d",
278: sd, acf -> acf_reason);
279:
280: reply = stopfnx ? (*stopfnx) (sd, acf) : ACS_ACCEPT;
281:
282: result = AcRelResponse (sd, reply, ACR_NORMAL, NULLPEP, 0,
283: &acis);
284:
285: ACFFREE (acf);
286:
287: if (result == NOTOK)
288: acs_advise (aca, "A-RELEASE.RESPONSE");
289: else
290: if (reply != ACS_ACCEPT)
291: break;
292: longjmp (toplevel, DONE);
293: }
294: /* NOTREACHED */
295:
296: default:
297: adios (NULLCP, "unknown indication type=%d", roi -> roi_type);
298: }
299: }
300:
301: /* */
302:
303: static int ros_lose (td)
304: struct TSAPdisconnect *td;
305: {
306: if (td -> td_cc > 0)
307: adios (NULLCP, "TNetAccept: [%s] %*.*s",
308: TErrString (td -> td_reason), td -> td_cc, td -> td_cc,
309: td -> td_data);
310: else
311: adios (NULLCP, "TNetAccept: [%s]", TErrString (td -> td_reason));
312: }
313:
314: /* ERRORS */
315:
316: void ros_adios (rop, event)
317: register struct RoSAPpreject *rop;
318: char *event;
319: {
320: ros_advise (rop, event);
321:
322: longjmp (toplevel, NOTOK);
323: }
324:
325:
326: void ros_advise (rop, event)
327: register struct RoSAPpreject *rop;
328: char *event;
329: {
330: char buffer[BUFSIZ];
331:
332: if (rop -> rop_cc > 0)
333: (void) sprintf (buffer, "[%s] %*.*s", RoErrString (rop -> rop_reason),
334: rop -> rop_cc, rop -> rop_cc, rop -> rop_data);
335: else
336: (void) sprintf (buffer, "[%s]", RoErrString (rop -> rop_reason));
337:
338: advise (LLOG_EXCEPTIONS, NULLCP, "%s: %s", event, buffer);
339: }
340:
341: /* */
342:
343: void acs_advise (aca, event)
344: register struct AcSAPabort *aca;
345: char *event;
346: {
347: char buffer[BUFSIZ];
348:
349: if (aca -> aca_cc > 0)
350: (void) sprintf (buffer, "[%s] %*.*s",
351: AcErrString (aca -> aca_reason),
352: aca -> aca_cc, aca -> aca_cc, aca -> aca_data);
353: else
354: (void) sprintf (buffer, "[%s]", AcErrString (aca -> aca_reason));
355:
356: advise (LLOG_EXCEPTIONS, NULLCP, "%s: %s (source %d)", event, buffer,
357: aca -> aca_source);
358: }
359:
360: /* */
361:
362: #ifndef lint
363: void adios (va_alist)
364: va_dcl
365: {
366: va_list ap;
367:
368: va_start (ap);
369:
370: _ll_log (pgm_log, LLOG_FATAL, ap);
371:
372: va_end (ap);
373:
374: _exit (1);
375: }
376: #else
377: /* VARARGS2 */
378:
379: void adios (what, fmt)
380: char *what,
381: *fmt;
382: {
383: adios (what, fmt);
384: }
385: #endif
386:
387:
388: #ifndef lint
389: void advise (va_alist)
390: va_dcl
391: {
392: int code;
393: va_list ap;
394:
395: va_start (ap);
396:
397: code = va_arg (ap, int);
398:
399: _ll_log (pgm_log, code, ap);
400:
401: va_end (ap);
402: }
403: #else
404: /* VARARGS3 */
405:
406: void advise (code, what, fmt)
407: char *what,
408: *fmt;
409: int code;
410: {
411: advise (code, what, fmt);
412: }
413: #endif
414:
415:
416: #ifndef lint
417: void ryr_advise (va_alist)
418: va_dcl
419: {
420: va_list ap;
421:
422: va_start (ap);
423:
424: _ll_log (pgm_log, LLOG_NOTICE, ap);
425:
426: va_end (ap);
427: }
428: #else
429: /* VARARGS2 */
430:
431: void ryr_advise (what, fmt)
432: char *what,
433: *fmt;
434: {
435: ryr_advise (what, fmt);
436: }
437: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.