BSD 4_3_Net_2 development
[unix-history] / usr / src / contrib / isode / ftam / ftaminitiate.c
CommitLineData
53102063
C
1/* ftaminitiate.c - FPM: initiator */
2
3#ifndef lint
4static 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
49int FInitializeRequest (context, callingtitle, calledtitle, callingaddr,
50 calledaddr, manage, class, units, attrs, sharedASE, fqos, contents,
51 initiator, account, password, passlen, qos, tracing, ftc, fti)
52OID context;
53AEI callingtitle,
54 calledtitle;
55struct PSAPaddr *callingaddr,
56 *calledaddr;
57int manage,
58 class,
59 units,
60 attrs,
61 fqos,
62 passlen;
63PE sharedASE;
64struct FTAMcontentlist *contents;
65char *initiator,
66 *account,
67 *password;
68struct QOStype *qos;
69IFP tracing;
70struct FTAMconnect *ftc;
71struct 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))) {
92not_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
143static 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)
147OID context;
148AEI callingtitle,
149 calledtitle;
150struct PSAPaddr *callingaddr,
151 *calledaddr;
152int manage,
153 class,
154 units,
155 attrs,
156 fqos,
157 passlen;
158PE sharedASE;
159struct FTAMcontentlist *contents;
160char *initiator,
161 *account,
162 *password;
163struct QOStype *qos;
164IFP tracing;
165struct FTAMconnect *ftc;
166struct 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) {
209no_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;
556do_trans: ;
557 if (!(fsb -> fsb_units & (FUNIT_READ | FUNIT_WRITE))) {
558not_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)) {
564too_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
692out2: ;
693 ACCFREE (acc);
694
695out1: ;
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}