|
|
1.1 root 1: /* ryresponder.c - generic idempotent responder */
2:
3: #include <stdio.h>
4: #include <setjmp.h>
5: #include "ryresponder.h"
6: #include <isode/tsap.h> /* for listening */
7:
8: /* DATA */
9:
10: int debug = 0;
11:
12: static LLog _pgm_log = {
13: "responder.log", NULLCP, NULLCP,
14: LLOG_FATAL | LLOG_EXCEPTIONS | LLOG_NOTICE, LLOG_FATAL, -1,
15: LLOGCLS | LLOGCRT | LLOGZER, NOTOK
16: };
17: LLog *pgm_log = &_pgm_log;
18:
19: static char *myname = "ryresponder";
20:
21:
22: static jmp_buf toplevel;
23:
24:
25: static IFP startfnx;
26: static IFP stopfnx;
27:
28: int ros_init (), ros_work (), ros_indication (), ros_lose ();
29:
30:
31: extern int errno;
32:
33: /* RESPONDER */
34:
35: int ryresponder (argc, argv, host, myservice, mycontext,
36: dispatches, ops, start, stop)
37: int argc;
38: char **argv,
39: *host,
40: *myservice,
41: *mycontext;
42: struct dispatch *dispatches;
43: struct RyOperation *ops;
44: IFP start,
45: stop;
46: {
47: register struct dispatch *ds;
48: AEI aei;
49: struct TSAPdisconnect tds;
50: struct TSAPdisconnect *td = &tds;
51: struct RoSAPindication rois;
52: register struct RoSAPindication *roi = &rois;
53: register struct RoSAPpreject *rop = &roi -> roi_preject;
54:
55: if (myname = rindex (argv[0], '/'))
56: myname++;
57: if (myname == NULL || *myname == NULL)
58: myname = argv[0];
59:
60: isodetailor (myname, 0);
61: if (debug = isatty (fileno (stderr)))
62: ll_dbinit (pgm_log, myname);
63: else {
64: static char myfile[BUFSIZ];
65:
66: (void) sprintf (myfile, "%s.log",
67: (strncmp (myname, "ros.", 4)
68: && strncmp (myname, "lpp.", 4))
69: || myname[4] == NULL
70: ? myname : myname + 4);
71: pgm_log -> ll_file = myfile;
72: ll_hdinit (pgm_log, myname);
73: }
74:
75: advise (LLOG_NOTICE, NULLCP, "starting");
76:
77: if ((aei = _str2aei (host, myservice, mycontext, 0)) == NULLAEI)
78: adios (NULLCP, "unable to resolve service: %s", PY_pepy);
79:
80: for (ds = dispatches; ds -> ds_name; ds++)
81: if (RyDispatch (NOTOK, ops, ds -> ds_operation, ds -> ds_vector, roi)
82: == NOTOK)
83: ros_adios (rop, ds -> ds_name);
84:
85: startfnx = start;
86: stopfnx = stop;
87:
88: if (isodeserver (argc, argv, aei, ros_init, ros_work, ros_lose, td)
89: == NOTOK) {
90: if (td -> td_cc > 0)
91: adios (NULLCP, "isodeserver: [%s] %*.*s",
92: TErrString (td -> td_reason),
93: td -> td_cc, td -> td_cc, td -> td_data);
94: else
95: adios (NULLCP, "isodeserver: [%s]",
96: TErrString (td -> td_reason));
97: }
98:
99: return 0;
100: }
101:
102:
103: static int ros_init (vecp, vec)
104: int vecp;
105: char **vec;
106: {
107: int reply,
108: result,
109: sd;
110: struct AcSAPstart acss;
111: register struct AcSAPstart *acs = &acss;
112: struct AcSAPindication acis;
113: register struct AcSAPindication *aci = &acis;
114: register struct AcSAPabort *aca = &aci -> aci_abort;
115: register struct PSAPstart *ps = &acs -> acs_start;
116: struct RoSAPindication rois;
117: register struct RoSAPindication *roi = &rois;
118: register struct RoSAPpreject *rop = &roi -> roi_preject;
119:
120: if (AcInit (vecp, vec, acs, aci) == NOTOK) {
121: acs_advise (aca, "initialization fails");
122: return NOTOK;
123: }
124: advise (LLOG_NOTICE, NULLCP,
125: "A-ASSOCIATE.INDICATION: <%d, %s, %s, %s, %d>",
126: acs -> acs_sd, oid2ode (acs -> acs_context),
127: sprintaei (&acs -> acs_callingtitle),
128: sprintaei (&acs -> acs_calledtitle), acs -> acs_ninfo);
129:
130: sd = acs -> acs_sd;
131:
132: for (vec++; *vec; vec++)
133: advise (LLOG_EXCEPTIONS, NULLCP, "unknown argument \"%s\"", *vec);
134:
135: reply = startfnx ? (*startfnx) (sd, acs) : ACS_ACCEPT;
136:
137: result = AcAssocResponse (sd, reply, reply != ACS_ACCEPT
138: ? ACS_USER_NOREASON : ACS_USER_NULL,
139: NULLOID, NULLAEI,
140: NULLPA, NULLPC, ps -> ps_defctxresult,
141: ps -> ps_prequirements, ps -> ps_srequirements,
142: SERIAL_NONE, ps -> ps_settings, &ps -> ps_connect,
143: NULLPEP, 0, aci);
144:
145: ACSFREE (acs);
146:
147: if (result == NOTOK) {
148: acs_advise (aca, "A-ASSOCIATE.RESPONSE");
149: return NOTOK;
150: }
151: if (reply != ACS_ACCEPT)
152: return NOTOK;
153:
154: if (RoSetService (sd, RoPService, roi) == NOTOK)
155: ros_adios (rop, "set RO/PS fails");
156:
157: return sd;
158: }
159:
160:
161: static int ros_work (fd)
162: int fd;
163: {
164: int result;
165: caddr_t out;
166: struct AcSAPindication acis;
167: struct RoSAPindication rois;
168: register struct RoSAPindication *roi = &rois;
169: register struct RoSAPpreject *rop = &roi -> roi_preject;
170:
171: switch (setjmp (toplevel)) {
172: case OK:
173: break;
174:
175: default:
176: if (stopfnx)
177: (*stopfnx) (fd, (struct AcSAPfinish *) 0);
178: case DONE:
179: (void) AcUAbortRequest (fd, NULLPEP, 0, &acis);
180: (void) RyLose (fd, roi);
181: return NOTOK;
182: }
183:
184: switch (result = RyWait (fd, NULLIP, &out, OK, roi)) {
185: case NOTOK:
186: if (rop -> rop_reason == ROS_TIMER)
187: break;
188: case OK:
189: case DONE:
190: ros_indication (fd, roi);
191: break;
192:
193: default:
194: adios (NULLCP, "unknown return from RoWaitRequest=%d", result);
195: }
196:
197: return OK;
198: }
199:
200:
201: static int ros_indication (sd, roi)
202: int sd;
203: register struct RoSAPindication *roi;
204: {
205: int reply,
206: result;
207:
208: switch (roi -> roi_type) {
209: case ROI_INVOKE:
210: case ROI_RESULT:
211: case ROI_ERROR:
212: adios (NULLCP, "unexpected indication type=%d", roi -> roi_type);
213: break;
214:
215: case ROI_UREJECT:
216: {
217: register struct RoSAPureject *rou = &roi -> roi_ureject;
218:
219: if (rou -> rou_noid)
220: advise (LLOG_EXCEPTIONS, NULLCP,
221: "RO-REJECT-U.INDICATION/%d: %s",
222: sd, RoErrString (rou -> rou_reason));
223: else
224: advise (LLOG_EXCEPTIONS, NULLCP,
225: "RO-REJECT-U.INDICATION/%d: %s (id=%d)",
226: sd, RoErrString (rou -> rou_reason),
227: rou -> rou_id);
228: }
229: break;
230:
231: case ROI_PREJECT:
232: {
233: register struct RoSAPpreject *rop = &roi -> roi_preject;
234:
235: if (ROS_FATAL (rop -> rop_reason))
236: ros_adios (rop, "RO-REJECT-P.INDICATION");
237: ros_advise (rop, "RO-REJECT-P.INDICATION");
238: }
239: break;
240:
241: case ROI_FINISH:
242: {
243: register struct AcSAPfinish *acf = &roi -> roi_finish;
244: struct AcSAPindication acis;
245: register struct AcSAPabort *aca = &acis.aci_abort;
246:
247: advise (LLOG_NOTICE, NULLCP, "A-RELEASE.INDICATION/%d: %d",
248: sd, acf -> acf_reason);
249:
250: reply = stopfnx ? (*stopfnx) (sd, acf) : ACS_ACCEPT;
251:
252: result = AcRelResponse (sd, reply, ACR_NORMAL, NULLPEP,
253: 0, &acis);
254:
255: ACFFREE (acf);
256:
257: if (result == NOTOK)
258: acs_advise (aca, "A-RELEASE.RESPONSE");
259: else
260: if (reply != ACS_ACCEPT)
261: break;
262: longjmp (toplevel, DONE);
263: }
264: /* NOTREACHED */
265:
266: default:
267: adios (NULLCP, "unknown indication type=%d", roi -> roi_type);
268: }
269: }
270:
271:
272: static int ros_lose (td)
273: struct TSAPdisconnect *td;
274: {
275: if (td -> td_cc > 0)
276: adios (NULLCP, "TNetAccept: [%s] %*.*s",
277: TErrString (td -> td_reason), td -> td_cc, td -> td_cc,
278: td -> td_data);
279: else
280: adios (NULLCP, "TNetAccept: [%s]", TErrString (td -> td_reason));
281: }
282:
283: ...
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.