Commit | Line | Data |
---|---|---|
53102063 C |
1 | /* ftaminitiate.c - FPM: initiator */ |
2 | ||
3 | #ifndef lint | |
4 | static char *rcsid = "$Header: /f/osi/ftam/RCS/ftaminitiate.c,v 7.3 91/02/22 09:23:00 mrose Interim $"; | |
5 | #endif | |
6 | ||
7 | /* | |
8 | * $Header: /f/osi/ftam/RCS/ftaminitiate.c,v 7.3 91/02/22 09:23:00 mrose Interim $ | |
9 | * | |
10 | * | |
11 | * $Log: ftaminitiate.c,v $ | |
12 | * Revision 7.3 91/02/22 09:23:00 mrose | |
13 | * Interim 6.8 | |
14 | * | |
15 | * Revision 7.2 91/01/07 12:40:10 mrose | |
16 | * update | |
17 | * | |
18 | * Revision 7.1 90/11/21 11:30:08 mrose | |
19 | * sun | |
20 | * | |
21 | * Revision 7.0 89/11/23 21:53:41 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 <signal.h> | |
41 | #include "fpkt.h" | |
42 | ||
43 | ||
44 | #define FS_CTX "iso ftam" | |
45 | #define FS_ASN "ftam pci" | |
46 | ||
47 | /* \f F-INITIALIZE.REQUEST */ | |
48 | ||
49 | int FInitializeRequest (context, callingtitle, calledtitle, callingaddr, | |
50 | calledaddr, manage, class, units, attrs, sharedASE, fqos, contents, | |
51 | initiator, account, password, passlen, qos, tracing, ftc, fti) | |
52 | OID context; | |
53 | AEI callingtitle, | |
54 | calledtitle; | |
55 | struct PSAPaddr *callingaddr, | |
56 | *calledaddr; | |
57 | int manage, | |
58 | class, | |
59 | units, | |
60 | attrs, | |
61 | fqos, | |
62 | passlen; | |
63 | PE sharedASE; | |
64 | struct FTAMcontentlist *contents; | |
65 | char *initiator, | |
66 | *account, | |
67 | *password; | |
68 | struct QOStype *qos; | |
69 | IFP tracing; | |
70 | struct FTAMconnect *ftc; | |
71 | struct FTAMindication *fti; | |
72 | { | |
73 | SBV smask; | |
74 | int result; | |
75 | ||
76 | #ifdef notdef | |
77 | missingP (context); | |
78 | missingP (callingtitle); | |
79 | missingP (calledtitle); | |
80 | missingP (callingaddr); | |
81 | #endif | |
82 | missingP (calledaddr); | |
83 | if (manage) | |
84 | return ftamlose (fti, FS_ACS_CONTEXT, 1, NULLCP, NULLCP); | |
85 | if (units & ~MY_FUNIT) | |
86 | return ftamlose (fti, FS_ACS_FUNIT, 1, NULLCP, NULLCP); | |
87 | if (!(units & FUNIT_LIMITED) && (units & FUNIT_ENHANCED)) | |
88 | return ftamlose (fti, FS_GEN_NOREASON, 1, NULLCP, | |
89 | "enhanced-file-management requires limited-file-management"); | |
90 | if ((class & FCLASS_TRANSFER | |
91 | && ((units & FUNITS_TRANSFER) != FUNITS_TRANSFER))) { | |
92 | not_enough: ; | |
93 | return ftamlose (fti, FS_GEN_NOREASON, 1, NULLCP, | |
94 | "insufficient functional units for service class"); | |
95 | } | |
96 | if ((class & FCLASS_TM) && ((units & FUNITS_TM) != FUNITS_TM)) | |
97 | goto not_enough; | |
98 | if ((class & (FCLASS_TRANSFER | FCLASS_TM)) | |
99 | && !(units & (FUNIT_READ | FUNIT_WRITE))) | |
100 | goto not_enough; | |
101 | if ((class & FCLASS_ACCESS) && ((units & FUNITS_ACCESS) != FUNITS_ACCESS)) | |
102 | goto not_enough; | |
103 | if ((class & FCLASS_MANAGE) && ((units & FUNITS_MANAGE) != FUNITS_MANAGE)) | |
104 | goto not_enough; | |
105 | if (!(class &= | |
106 | (FCLASS_TRANSFER | FCLASS_TM | FCLASS_MANAGE | FCLASS_ACCESS))) | |
107 | return ftamlose (fti, FS_ACS_CLASS, 1, NULLCP, NULLCP); | |
108 | if (!(units & FUNIT_LIMITED) && (units & FUNIT_ENHANCED)) | |
109 | return ftamlose (fti, FS_GEN_NOREASON, 1, NULLCP, | |
110 | "enhanced-file-management requires limited-file-management"); | |
111 | if (!(units & FUNIT_GROUPING)) /* XXX: should be OPTIONAL */ | |
112 | goto not_enough; | |
113 | if (attrs & ~MY_FATTR) | |
114 | return ftamlose (fti, FS_ACS_GRPSUP, 1, NULLCP, NULLCP); | |
115 | #ifdef notdef | |
116 | if ((attrs & FATTR_SECURITY) && !(attrs & FATTR_STORAGE)) | |
117 | return ftamlose (fti, FS_ACS_GRP, 1, NULLCP, NULLCP); | |
118 | #endif | |
119 | if (contents && contents -> fc_ncontent > NFCONT) | |
120 | return ftamlose (fti, FS_GEN_NOREASON, 1, NULLCP, | |
121 | "too many content types"); | |
122 | if (password == NULL) | |
123 | passlen = 0; | |
124 | #ifdef notdef | |
125 | missingP (qos); | |
126 | #endif | |
127 | missingP (fti); | |
128 | ||
129 | smask = sigioblock (); | |
130 | ||
131 | result = FInitializeRequestAux (context, callingtitle, calledtitle, | |
132 | callingaddr, calledaddr, manage, class, units, attrs, sharedASE, fqos, | |
133 | contents, initiator, account, password, passlen, qos, tracing, ftc, | |
134 | fti); | |
135 | ||
136 | (void) sigiomask (smask); | |
137 | ||
138 | return result; | |
139 | } | |
140 | ||
141 | /* \f */ | |
142 | ||
143 | static int FInitializeRequestAux (context, callingtitle, calledtitle, | |
144 | callingaddr, calledaddr, manage, class, units, attrs, sharedASE, fqos, | |
145 | contents, initiator, account, password, passlen, qos, tracing, ftc, | |
146 | fti) | |
147 | OID context; | |
148 | AEI callingtitle, | |
149 | calledtitle; | |
150 | struct PSAPaddr *callingaddr, | |
151 | *calledaddr; | |
152 | int manage, | |
153 | class, | |
154 | units, | |
155 | attrs, | |
156 | fqos, | |
157 | passlen; | |
158 | PE sharedASE; | |
159 | struct FTAMcontentlist *contents; | |
160 | char *initiator, | |
161 | *account, | |
162 | *password; | |
163 | struct QOStype *qos; | |
164 | IFP tracing; | |
165 | struct FTAMconnect *ftc; | |
166 | struct FTAMindication *fti; | |
167 | { | |
168 | register int i; | |
169 | int bits, | |
170 | rcvd_bits, | |
171 | idc, | |
172 | result, | |
173 | settings; | |
174 | long isn; | |
175 | PE pe; | |
176 | OID ctx, | |
177 | pci; | |
178 | struct SSAPref *sr; | |
179 | register struct PSAPcontext *px; | |
180 | struct PSAPctxlist pls; | |
181 | register struct PSAPctxlist *pl = &pls; | |
182 | struct AcSAPconnect accs; | |
183 | register struct AcSAPconnect *acc = &accs; | |
184 | register struct PSAPconnect *pc = &acc -> acc_connect; | |
185 | struct AcSAPindication acis; | |
186 | register struct AcSAPindication *aci = &acis; | |
187 | register struct AcSAPabort *aca = &aci -> aci_abort; | |
188 | register struct FTAMcontent *fx; | |
189 | register struct ftamblk *fsb; | |
190 | struct type_FTAM_PDU *pdu; | |
191 | register struct type_FTAM_F__INITIALIZE__request *req; | |
192 | register struct type_FTAM_F__INITIALIZE__response *rsp; | |
193 | ||
194 | if ((fsb = newfsblk ()) == NULL) | |
195 | return ftamlose (fti, FS_GEN_NOREASON, 1, NULLCP, "out of memory"); | |
196 | fsb -> fsb_flags |= FSB_INIT; | |
197 | fsb -> fsb_trace = tracing; | |
198 | ||
199 | ctx = pci = NULLOID, pl -> pc_nctx = 0; | |
200 | bzero ((char *) ftc, sizeof *ftc); | |
201 | ||
202 | pdu = NULL; | |
203 | ||
204 | if (context == NULLOID && (context = ode2oid (FS_CTX)) == NULLOID) { | |
205 | result = ftamlose (fti, FS_ACS_MGMT, 1, NULLCP, "%s: unknown", FS_CTX); | |
206 | goto out1; | |
207 | } | |
208 | if ((ctx = oid_cpy (context)) == NULLOID) { | |
209 | no_mem: ; | |
210 | result = ftamlose (fti, FS_GEN_NOREASON, 1, NULLCP, "out of memory"); | |
211 | goto out1; | |
212 | } | |
213 | ||
214 | if ((pci = ode2oid (FS_ASN)) == NULLOID) { | |
215 | result = ftamlose (fti, FS_ACS_MGMT, 1, NULLCP, "%s: unknown", FS_ASN); | |
216 | goto out1; | |
217 | } | |
218 | if ((pci = oid_cpy (pci)) == NULLOID) | |
219 | goto no_mem; | |
220 | ||
221 | px = pl -> pc_ctx, pl -> pc_nctx = 0; | |
222 | ||
223 | px -> pc_id = fsb -> fsb_id = idc = 1; | |
224 | if ((px -> pc_asn = ode2oid (FS_ASN)) == NULLOID) { | |
225 | result = ftamlose (fti, FS_ACS_MGMT, 1, NULLCP, "%s: unknown", FS_ASN); | |
226 | goto out1; | |
227 | } | |
228 | if ((px -> pc_asn = oid_cpy (px -> pc_asn)) == NULLOID) | |
229 | goto no_mem; | |
230 | if ((px -> pc_atn = ode2oid (BER)) == NULLOID) { | |
231 | result = ftamlose (fti, FS_ACS_MGMT, 1, NULLCP, "%s: unknown", BER); | |
232 | goto out1; | |
233 | } | |
234 | if ((px -> pc_atn = oid_cpy (px -> pc_atn)) == NULLOID) | |
235 | goto no_mem; | |
236 | px++, pl -> pc_nctx++; | |
237 | ||
238 | if (contents) { | |
239 | register struct isodocument *id; | |
240 | ||
241 | for (fx = contents -> fc_contents, i = contents -> fc_ncontent - 1; | |
242 | i >= 0; | |
243 | fx++, i--) { | |
244 | if (fx -> fc_dtn == NULLOID) { | |
245 | result = ftamlose (fti, FS_GEN (fsb), 1, NULLCP, | |
246 | "empty content type at slot %d", | |
247 | contents -> fc_ncontent - i - 1); | |
248 | goto out1; | |
249 | } | |
250 | ||
251 | if ((id = getisodocumentbytype (fx -> fc_dtn)) == NULL) { | |
252 | result = ftamlose (fti, FS_GEN (fsb), 1, NULLCP, | |
253 | "unknown document type %s at slot %d", | |
254 | sprintoid (fx -> fc_dtn), | |
255 | contents -> fc_ncontent - i - 1); | |
256 | goto out1; | |
257 | } | |
258 | ||
259 | px -> pc_id = (idc += 2); | |
260 | if ((px -> pc_asn = oid_cpy (id -> id_abstract)) == NULLOID) | |
261 | goto no_mem; | |
262 | if ((px -> pc_atn = oid_cpy (id -> id_transfer)) == NULLOID) | |
263 | goto no_mem; | |
264 | px++, pl -> pc_nctx++; | |
265 | } | |
266 | } | |
267 | ||
268 | if ((pdu = (struct type_FTAM_PDU *) calloc (1, sizeof *pdu)) == NULL) | |
269 | goto no_mem; | |
270 | pdu -> offset = type_FTAM_PDU_f__initialize__request; | |
271 | if ((req = (struct type_FTAM_F__INITIALIZE__request *) | |
272 | calloc (1, sizeof *req)) == NULL) | |
273 | goto no_mem; | |
274 | pdu -> un.f__initialize__request = req; | |
275 | req -> presentation__context__management = manage; | |
276 | if (class != FCLASS_TRANSFER | |
277 | && (req -> service__class = bits2fpm (fsb, fclass_pairs, class, | |
278 | fti)) == NULLPE) | |
279 | goto out1; | |
280 | if ((req -> functional__units = bits2fpm (fsb, funit_pairs, units, fti)) | |
281 | == NULLPE) | |
282 | goto out1; | |
283 | if (attrs && (req -> attribute__groups = bits2fpm (fsb, fattr_pairs, | |
284 | attrs, fti)) == NULLPE) | |
285 | goto out1; | |
286 | if (sharedASE | |
287 | && (req -> shared__ASE__information = | |
288 | shared2fpm (fsb, sharedASE, fti)) == NULL) | |
289 | goto out1; | |
290 | if ((req -> ftam__quality__of__service = | |
291 | (struct type_FTAM_FTAM__Quality__Of__Service *) | |
292 | calloc (1, sizeof *req -> ftam__quality__of__service)) | |
293 | == NULL) | |
294 | goto no_mem; | |
295 | #ifdef lint | |
296 | req -> ftam__quality__of__service -> parm = fqos; | |
297 | #else | |
298 | req -> ftam__quality__of__service -> parm = MY_FQOS; | |
299 | #endif | |
300 | if (contents) { | |
301 | struct type_FTAM_Contents__Type__List *fpm; | |
302 | register struct type_FTAM_Contents__Type__List **fpc; | |
303 | ||
304 | fpc = &req -> contents__type__list; | |
305 | for (fx = contents -> fc_contents, i = contents -> fc_ncontent - 1; | |
306 | i >= 0; | |
307 | fx++, i--) { | |
308 | if ((fpm = (struct type_FTAM_Contents__Type__List *) | |
309 | calloc (1, sizeof *fpm)) == NULL) | |
310 | goto no_mem; | |
311 | *fpc = fpm; | |
312 | ||
313 | if ((fpm -> Document__Type__Name = oid_cpy (fx -> fc_dtn)) | |
314 | == NULLOID) | |
315 | goto no_mem; | |
316 | fpc = &fpm -> next; | |
317 | } | |
318 | } | |
319 | if (initiator | |
320 | && (req -> initiator__identity = str2qb (initiator, | |
321 | strlen (initiator), 1)) | |
322 | == NULL) | |
323 | goto out1; | |
324 | if (account | |
325 | && (req -> account = str2qb (account, strlen (account), 1)) | |
326 | == NULL) | |
327 | goto out1; | |
328 | if (password) { | |
329 | register struct type_FTAM_Password *p; | |
330 | ||
331 | if ((p = (struct type_FTAM_Password *) calloc (1, sizeof *p)) | |
332 | == NULL) | |
333 | goto no_mem; | |
334 | req -> filestore__password = p; | |
335 | p -> offset = type_FTAM_Password_binary; | |
336 | if ((p -> un.binary = str2qb (password, passlen, 1)) == NULL) | |
337 | goto no_mem; | |
338 | } | |
339 | req -> checkpoint__window = 1; | |
340 | ||
341 | if (encode_FTAM_PDU (&pe, 1, 0, NULLCP, pdu) == NOTOK) { | |
342 | (void) ftamlose (fti, FS_GEN (fsb), 1, NULLCP, | |
343 | "error encoding PDU: %s", PY_pepy); | |
344 | goto out1; | |
345 | } | |
346 | ||
347 | pe -> pe_context = fsb -> fsb_id; | |
348 | ||
349 | fsb -> fsb_srequirements = SR_DUPLEX | SR_RESYNC; | |
350 | fsb -> fsb_srequirements &= ~SR_RESYNC; /* XXX */ | |
351 | if (units & (FUNIT_RECOVERY | FUNIT_RESTART)) | |
352 | fsb -> fsb_srequirements |= SR_MINORSYNC; | |
353 | isn = (fsb -> fsb_srequirements & (SR_MINORSYNC | SR_RESYNC)) ? 1L | |
354 | : SERIAL_NONE; | |
355 | fsb -> fsb_prequirements = manage ? (PR_MANAGEMENT | PR_RESTORATION) : 0; | |
356 | settings = 0; | |
357 | #define dotoken(requires,shift,bit,type) \ | |
358 | { \ | |
359 | if (fsb -> fsb_srequirements & requires) \ | |
360 | settings |= ST_INIT_VALUE << shift; \ | |
361 | } | |
362 | dotokens (); | |
363 | #undef dotoken | |
364 | ||
365 | if ((sr = addr2ref (PLocalHostName ())) == NULL) | |
366 | goto no_mem; | |
367 | ||
368 | fsbtrace (fsb, (fsb -> fsb_fd, "A-ASSOCIATE.REQUEST", | |
369 | "F-INITIALIZE-request", pe, 0)); | |
370 | ||
371 | result = AcAssocRequest (ctx, callingtitle, calledtitle, callingaddr, | |
372 | calledaddr, pl, NULLOID /* pci */, fsb -> fsb_prequirements, | |
373 | fsb -> fsb_srequirements, isn, settings, sr, &pe, 1, | |
374 | qos, acc, aci); | |
375 | ||
376 | if (result == NOTOK) { | |
377 | (void) acs2ftamlose (fsb, fti, "AcAssocRequest", aca); | |
378 | goto out1; | |
379 | } | |
380 | ||
381 | fsb -> fsb_fd = acc -> acc_sd; | |
382 | ||
383 | pe_free (pe); | |
384 | pe = NULLPE; | |
385 | free_FTAM_PDU (pdu); | |
386 | pdu = NULL; | |
387 | oid_free (ctx); | |
388 | ctx = NULLOID; | |
389 | oid_free (pci); | |
390 | pci = NULLOID; | |
391 | for (px = pl -> pc_ctx, i = pl -> pc_nctx - 1; i >= 0; px++, i--) { | |
392 | if (px -> pc_asn) | |
393 | oid_free (px -> pc_asn); | |
394 | if (px -> pc_atn) | |
395 | oid_free (px -> pc_atn); | |
396 | } | |
397 | ||
398 | if (acc -> acc_ninfo < 1 || (pe = acc -> acc_info[0]) == NULLPE) { | |
399 | if (acc -> acc_result != ACS_ACCEPT) { | |
400 | register struct FTAMabort *fta = &fti -> fti_abort; | |
401 | ||
402 | aca -> aca_reason = acc -> acc_result; | |
403 | (void) acs2ftamlose (fsb, fti, "AcAssocRequest(pseudo)", aca); | |
404 | ||
405 | ftc -> ftc_sd = NOTOK; | |
406 | ftc -> ftc_state = FSTATE_FAILURE; | |
407 | ftc -> ftc_action = FACTION_PERM; | |
408 | *ftc -> ftc_diags = *fta -> fta_diags; /* struct copy */ | |
409 | ftc -> ftc_ndiag = fta -> fta_ndiag; | |
410 | ||
411 | result = OK; | |
412 | } | |
413 | else | |
414 | result = fpktlose (fsb, fti, FS_PRO_ERR, NULLCP, NULLCP); | |
415 | goto out2; | |
416 | } | |
417 | ||
418 | if (decode_FTAM_PDU (pe, 1, NULLIP, NULLVP, &pdu) == NOTOK) { | |
419 | result = fpktlose (fsb, fti, FS_PRO_ERRMSG, NULLCP, | |
420 | "unable to parse PDU: %s", PY_pepy); | |
421 | goto out2; | |
422 | } | |
423 | if (pdu -> offset != type_FTAM_PDU_f__initialize__response) { | |
424 | result = fpktlose (fsb, fti, FS_PRO_ERRPROC, NULLCP, | |
425 | "expecting F-INITIALIZE-response, got %d", | |
426 | pdu -> offset); | |
427 | goto out2; | |
428 | } | |
429 | rsp = pdu -> un.f__initialize__response; | |
430 | ||
431 | fsbtrace (fsb, | |
432 | (fsb -> fsb_fd, "A-ASSOCIATE.CONFIRMATION", "F-INITIALIZE-response", | |
433 | pe, 1)); | |
434 | ||
435 | ftc -> ftc_state = rsp -> state__result | |
436 | ? rsp -> state__result -> parm | |
437 | : int_FTAM_State__Result_success; | |
438 | ftc -> ftc_action = rsp -> action__result | |
439 | ? rsp -> action__result -> parm | |
440 | : int_FTAM_Action__Result_success; | |
441 | switch (acc -> acc_result) { | |
442 | case ACS_ACCEPT: | |
443 | if (ftc -> ftc_state != FSTATE_SUCCESS | |
444 | || ftc -> ftc_action != FACTION_SUCCESS) { | |
445 | result = fpktlose (fsb, fti, FS_PRO_ERRPROC, NULLCP, | |
446 | "state/action mismatch"); | |
447 | goto out2; | |
448 | } | |
449 | ||
450 | fsb -> fsb_flags |= FSB_CONN; | |
451 | fsb -> fsb_srequirements &= pc -> pc_srequirements; | |
452 | #define dotoken(requires,shift,bit,type) \ | |
453 | { \ | |
454 | if (fsb -> fsb_srequirements & requires) \ | |
455 | switch (pc -> pc_settings & (ST_MASK << shift)) { \ | |
456 | case ST_INIT_VALUE << shift: \ | |
457 | fsb -> fsb_owned |= bit; \ | |
458 | fsb -> fsb_avail |= bit; \ | |
459 | break; \ | |
460 | \ | |
461 | case ST_RESP_VALUE << shift: \ | |
462 | fsb -> fsb_avail |= bit; \ | |
463 | break; \ | |
464 | \ | |
465 | default: \ | |
466 | result = fpktlose (fsb, fti, FS_PRO_ERRPROC, NULLCP, \ | |
467 | "%s token management botched", type); \ | |
468 | goto out2; \ | |
469 | } \ | |
470 | } | |
471 | dotokens (); | |
472 | #undef dotoken | |
473 | if (fsb -> fsb_owned != fsb -> fsb_avail) { | |
474 | result = fpktlose (fsb, fti, FS_PRO_ERRPROC, NULLCP, | |
475 | "token management botched"); | |
476 | goto out2; | |
477 | } | |
478 | fsb -> fsb_ssdusize = pc -> pc_ssdusize; | |
479 | ||
480 | pl = &pc -> pc_ctxlist; | |
481 | if (pl -> pc_nctx > 0 && pl -> pc_ctx[0].pc_result != PC_ACCEPT) { | |
482 | result = fpktlose (fsb, fti, FS_PRO_ERRPROC, NULLCP, | |
483 | "FTAM PCI rejected"); | |
484 | goto out2; | |
485 | } | |
486 | ||
487 | fsb -> fsb_prequirements &= pc -> pc_prequirements; | |
488 | if (rsp -> presentation__context__management) { | |
489 | if (!(fsb -> fsb_prequirements & PR_MANAGEMENT)) { | |
490 | result = fpktlose (fsb, fti, FS_PRO_ERRPROC, NULLCP, | |
491 | "presentation content management mismatch"); | |
492 | goto out2; | |
493 | } | |
494 | } | |
495 | else | |
496 | fsb -> fsb_prequirements &= ~PR_MANAGEMENT; | |
497 | ||
498 | if (rsp -> service__class) { | |
499 | rcvd_bits = fpm2bits (fsb, fclass_pairs, rsp -> service__class, | |
500 | &bits, fti); | |
501 | if (rcvd_bits == NOTOK) | |
502 | goto out2; | |
503 | else if (rcvd_bits > 1) { | |
504 | result = fpktlose (fsb, fti, FS_PRO_ERRPROC, NULLCP, | |
505 | "illegal negotiation of service classes"); | |
506 | goto out2; | |
507 | } | |
508 | } | |
509 | else | |
510 | bits = FCLASS_TRANSFER; | |
511 | switch (fsb -> fsb_class = (bits & class)) { | |
512 | case FCLASS_TRANSFER: | |
513 | i = FUNITS_TRANSFER; | |
514 | break; | |
515 | ||
516 | case FCLASS_ACCESS: | |
517 | i = FUNITS_ACCESS; | |
518 | break; | |
519 | ||
520 | case FCLASS_MANAGE: | |
521 | i = FUNITS_MANAGE; | |
522 | break; | |
523 | ||
524 | case FCLASS_TM: | |
525 | i = FUNITS_TM; | |
526 | break; | |
527 | ||
528 | case FCLASS_UNCONS: | |
529 | i = FUNITS_UNCONS; | |
530 | break; | |
531 | ||
532 | default: | |
533 | result = fpktlose (fsb, fti, FS_PRO_ERRPROC, NULLCP, | |
534 | "service class mismatch, offered 0x%x received 0x%x", | |
535 | class, bits); | |
536 | goto out2; | |
537 | } | |
538 | if (fpm2bits (fsb, funit_pairs, rsp -> functional__units, &bits, | |
539 | fti) == NOTOK) | |
540 | goto out2; | |
541 | bits |= i; /* conservative... */ | |
542 | if ((fsb -> fsb_units = bits) & ~units) { | |
543 | result = fpktlose (fsb, fti, FS_PRO_ERRFUNIT, NULLCP, | |
544 | "functional unit mismatch"); | |
545 | goto out2; | |
546 | } | |
547 | /* check for illegal and mandatory functional units */ | |
548 | switch (fsb -> fsb_class) { | |
549 | case FCLASS_TRANSFER: | |
550 | if (!(fsb -> fsb_units & FUNITS_TRANSFER)) | |
551 | goto not_enough; | |
552 | goto do_trans; | |
553 | case FCLASS_TM: | |
554 | if (!(fsb -> fsb_units & FUNITS_TM)) | |
555 | goto not_enough; | |
556 | do_trans: ; | |
557 | if (!(fsb -> fsb_units & (FUNIT_READ | FUNIT_WRITE))) { | |
558 | not_enough: ; | |
559 | result = fpktlose (fsb, fti, FS_PRO_ERRFUNIT, NULLCP, | |
560 | "insufficient functional units for service class"); | |
561 | goto out2; | |
562 | } | |
563 | if (fsb -> fsb_units & (FUNIT_ACCESS | FUNIT_FADULOCK)) { | |
564 | too_many: ; | |
565 | result = fpktlose (fsb, fti, FS_PRO_ERRFUNIT, NULLCP, | |
566 | "illegal functional units for service class"); | |
567 | goto out2; | |
568 | } | |
569 | break; | |
570 | ||
571 | case FCLASS_ACCESS: | |
572 | if (!(fsb -> fsb_units & FUNITS_ACCESS)) | |
573 | goto not_enough; | |
574 | break; | |
575 | ||
576 | case FCLASS_MANAGE: | |
577 | if (!(fsb -> fsb_units & FUNITS_MANAGE)) | |
578 | goto not_enough; | |
579 | if (fsb -> fsb_units & (FUNIT_READ | FUNIT_WRITE | |
580 | | FUNIT_ACCESS | FUNIT_FADULOCK | |
581 | | FUNIT_RECOVERY | |
582 | | FUNIT_RESTART)) | |
583 | goto too_many; | |
584 | break; | |
585 | } | |
586 | if (rsp -> attribute__groups) { | |
587 | if (fpm2bits (fsb, fattr_pairs, rsp -> attribute__groups, | |
588 | &bits, fti) == NOTOK) | |
589 | goto out2; | |
590 | } | |
591 | else | |
592 | bits = 0; | |
593 | if (bits & ~attrs) { | |
594 | result = fpktlose (fsb, fti, FS_PRO_ERRPROC, NULLCP, | |
595 | "attribute group mismatch"); | |
596 | goto out2; | |
597 | } | |
598 | fsb -> fsb_attrs = bits; | |
599 | if (rsp -> ftam__quality__of__service -> parm != MY_FQOS) { | |
600 | result = fpktlose (fsb, fti, FS_ACS_ROLLBACK, NULLCP, | |
601 | "class-%d-recovery not supported", | |
602 | rsp -> ftam__quality__of__service -> parm); | |
603 | goto out2; | |
604 | } | |
605 | fsb -> fsb_fqos = MY_FQOS; | |
606 | ||
607 | ftc -> ftc_sd = fsb -> fsb_fd; | |
608 | break; | |
609 | ||
610 | default: | |
611 | ftc -> ftc_sd = NOTOK; | |
612 | if (ftc -> ftc_state == FSTATE_SUCCESS | |
613 | && ftc -> ftc_action == FACTION_SUCCESS) { | |
614 | result = fpktlose (fsb, fti, FS_PRO_ERRPROC, NULLCP, | |
615 | "state/action mismatch"); | |
616 | goto out2; | |
617 | } | |
618 | { | |
619 | register struct FTAMabort *fta = &fti -> fti_abort; | |
620 | ||
621 | bzero ((char *) fta, sizeof *fta); | |
622 | fta -> fta_peer = 1; | |
623 | } | |
624 | break; | |
625 | } | |
626 | ||
627 | ftc -> ftc_respondtitle = acc -> acc_respondtitle; /* struct copy */ | |
628 | bzero ((char *) &acc -> acc_respondtitle, sizeof acc -> acc_respondtitle); | |
629 | ftc -> ftc_respondaddr = pc -> pc_responding; /* struct copy */ | |
630 | ftc -> ftc_context = acc -> acc_context; | |
631 | acc -> acc_context = NULLOID; | |
632 | ftc -> ftc_manage = (fsb -> fsb_prequirements & PR_MANAGEMENT) ? 1 : 0; | |
633 | ftc -> ftc_class = fsb -> fsb_class; | |
634 | ftc -> ftc_units = fsb -> fsb_units; | |
635 | ftc -> ftc_attrs = fsb -> fsb_attrs; | |
636 | if (rsp -> shared__ASE__information | |
637 | && fpm2shared (fsb, rsp -> shared__ASE__information, | |
638 | &ftc -> ftc_sharedASE, fti) == NOTOK) | |
639 | goto out2; | |
640 | ftc -> ftc_fqos = fsb -> fsb_fqos; | |
641 | ||
642 | if (contents) { | |
643 | register struct type_FTAM_Contents__Type__List *dtn; | |
644 | register struct FTAMcontent *fx2; | |
645 | ||
646 | fx2 = ftc -> ftc_contents.fc_contents; | |
647 | ||
648 | for (fx = contents -> fc_contents, | |
649 | i = contents -> fc_ncontent - 1; | |
650 | i >= 0; | |
651 | fx++, i--) { | |
652 | for (dtn = rsp -> contents__type__list; dtn; dtn = dtn -> next) | |
653 | if (oid_cmp (fx -> fc_dtn, dtn -> Document__Type__Name) == 0) | |
654 | break; | |
655 | if (dtn == NULL) | |
656 | continue; | |
657 | ||
658 | px = pl -> pc_ctx + 1 + (fx - contents -> fc_contents); | |
659 | ||
660 | fx2 -> fc_dtn = dtn -> Document__Type__Name; | |
661 | fx2 -> fc_id = px -> pc_id; | |
662 | fx2 -> fc_result = px -> pc_result; | |
663 | ||
664 | fx2++, ftc -> ftc_contents.fc_ncontent++; | |
665 | } | |
666 | ||
667 | for (dtn = rsp -> contents__type__list; dtn; dtn = dtn -> next) { | |
668 | for (fx2 = ftc -> ftc_contents.fc_contents, | |
669 | i = ftc -> ftc_contents.fc_ncontent - 1; | |
670 | i >= 0; | |
671 | fx2++, i--) | |
672 | if (dtn -> Document__Type__Name == fx2 -> fc_dtn) { | |
673 | dtn -> Document__Type__Name = NULLOID; | |
674 | break; | |
675 | } | |
676 | } | |
677 | } | |
678 | if (rsp -> diagnostic) | |
679 | (void) fpm2diag (fsb, rsp -> diagnostic, ftc -> ftc_diags, | |
680 | &ftc -> ftc_ndiag, fti); | |
681 | ftc -> ftc_ssdusize = fsb -> fsb_ssdusize; | |
682 | ftc -> ftc_qos = pc -> pc_qos; /* struct copy */ | |
683 | ||
684 | free_FTAM_PDU (pdu); | |
685 | ACCFREE (acc); | |
686 | ||
687 | if (acc -> acc_result != ACS_ACCEPT) | |
688 | freefsblk (fsb); | |
689 | ||
690 | return OK; | |
691 | ||
692 | out2: ; | |
693 | ACCFREE (acc); | |
694 | ||
695 | out1: ; | |
696 | if (pdu) | |
697 | free_FTAM_PDU (pdu); | |
698 | if (ctx) | |
699 | oid_free (ctx); | |
700 | if (pci) | |
701 | oid_free (pci); | |
702 | for (px = pl -> pc_ctx, i = pl -> pc_nctx - 1; i >= 0; px++, i--) { | |
703 | if (px -> pc_asn) | |
704 | oid_free (px -> pc_asn); | |
705 | if (px -> pc_atn) | |
706 | oid_free (px -> pc_atn); | |
707 | } | |
708 | freefsblk (fsb); | |
709 | ||
710 | return result; | |
711 | } |