Commit | Line | Data |
---|---|---|
53102063 C |
1 | /* ftamrespond.c - FPM: responder */ |
2 | ||
3 | #ifndef lint | |
4 | static char *rcsid = "$Header: /f/osi/ftam/RCS/ftamrespond.c,v 7.5 91/02/22 09:23:12 mrose Interim $"; | |
5 | #endif | |
6 | ||
7 | /* | |
8 | * $Header: /f/osi/ftam/RCS/ftamrespond.c,v 7.5 91/02/22 09:23:12 mrose Interim $ | |
9 | * | |
10 | * | |
11 | * $Log: ftamrespond.c,v $ | |
12 | * Revision 7.5 91/02/22 09:23:12 mrose | |
13 | * Interim 6.8 | |
14 | * | |
15 | * Revision 7.4 91/01/07 12:40:20 mrose | |
16 | * update | |
17 | * | |
18 | * Revision 7.3 90/11/11 10:01:10 mrose | |
19 | * touch-up | |
20 | * | |
21 | * Revision 7.2 90/11/05 13:32:59 mrose | |
22 | * update | |
23 | * | |
24 | * Revision 7.1 90/11/04 19:15:10 mrose | |
25 | * update | |
26 | * | |
27 | * Revision 7.0 89/11/23 21:53:51 mrose | |
28 | * Release 6.0 | |
29 | * | |
30 | */ | |
31 | ||
32 | /* | |
33 | * NOTICE | |
34 | * | |
35 | * Acquisition, use, and distribution of this module and related | |
36 | * materials are subject to the restrictions of a license agreement. | |
37 | * Consult the Preface in the User's Manual for the full terms of | |
38 | * this agreement. | |
39 | * | |
40 | */ | |
41 | ||
42 | ||
43 | /* LINTLIBRARY */ | |
44 | ||
45 | #include <stdio.h> | |
46 | #include "fpkt.h" | |
47 | ||
48 | /* \f F-INITIALIZE.INDICATION */ | |
49 | ||
50 | int FInit (vecp, vec, fts, tracing, fti) | |
51 | int vecp; | |
52 | char **vec; | |
53 | struct FTAMstart *fts; | |
54 | IFP tracing; | |
55 | struct FTAMindication *fti; | |
56 | { | |
57 | register int i; | |
58 | PE pe = NULLPE; | |
59 | struct AcSAPstart acss; | |
60 | register struct AcSAPstart *acs = &acss; | |
61 | register struct PSAPstart *ps = &acs -> acs_start; | |
62 | struct AcSAPindication acis; | |
63 | register struct AcSAPindication *aci = &acis; | |
64 | register struct AcSAPabort *aca = &aci -> aci_abort; | |
65 | register struct ftamblk *fsb; | |
66 | struct type_FTAM_PDU *pdu; | |
67 | register struct type_FTAM_F__INITIALIZE__request *req; | |
68 | register struct type_FTAM_F__INITIALIZE__response *rsp; | |
69 | ||
70 | missingP (vec); | |
71 | missingP (fts); | |
72 | missingP (fti); | |
73 | ||
74 | if ((fsb = newfsblk ()) == NULL) | |
75 | return ftamlose (fti, FS_GEN_NOREASON, 0, NULLCP, "out of memory"); | |
76 | fsb -> fsb_trace = tracing; | |
77 | ||
78 | bzero ((char *) fts, sizeof *fts); | |
79 | ||
80 | pdu = NULL; | |
81 | ||
82 | if (AcInit (vecp, vec, acs, aci) == NOTOK) { | |
83 | (void) acs2ftamlose (fsb, fti, "AcInit", aca); | |
84 | goto out1; | |
85 | } | |
86 | ||
87 | fsb -> fsb_fd = acs -> acs_sd; | |
88 | ||
89 | fsb -> fsb_srequirements = ps -> ps_srequirements; | |
90 | fsb -> fsb_srequirements &= ~SR_RESYNC; /* XXX */ | |
91 | if (!(fsb -> fsb_srequirements & (SR_MINORSYNC | SR_RESYNC))) | |
92 | ps -> ps_isn = SERIAL_NONE; | |
93 | ||
94 | fsb -> fsb_settings = ps -> ps_settings; | |
95 | #define dotoken(requires,shift,bit,type) \ | |
96 | { \ | |
97 | if (fsb -> fsb_srequirements & requires) \ | |
98 | switch (fsb -> fsb_settings & (ST_MASK << shift)) { \ | |
99 | case ST_INIT_VALUE << shift: \ | |
100 | fsb -> fsb_avail |= bit; \ | |
101 | break; \ | |
102 | \ | |
103 | case ST_RESP_VALUE << shift: \ | |
104 | fsb -> fsb_owned |= bit; \ | |
105 | fsb -> fsb_avail |= bit; \ | |
106 | break; \ | |
107 | \ | |
108 | default: \ | |
109 | (void) ftamoops (fti, FS_PRO_ERRPROC, 1, EREF_RFPM, \ | |
110 | EREF_IFPM, NULLCP, \ | |
111 | "%s token management botched", type); \ | |
112 | goto out2; \ | |
113 | } \ | |
114 | } | |
115 | dotokens (); | |
116 | #undef dotoken | |
117 | if (fsb -> fsb_owned != 0) { | |
118 | (void) ftamoops (fti, FS_PRO_ERRPROC, 1, EREF_RFPM, EREF_IFPM, NULLCP, | |
119 | "token management botched"); | |
120 | goto out2; | |
121 | } | |
122 | fsb -> fsb_ssn = ps -> ps_isn; | |
123 | fsb -> fsb_ssdusize = ps -> ps_ssdusize; | |
124 | fsb -> fsb_connect = ps -> ps_connect; /* struct copy */ | |
125 | fsb -> fsb_prequirements = ps -> ps_prequirements; | |
126 | ||
127 | if (acs -> acs_ninfo < 1 || (pe = acs -> acs_info[0]) == NULLPE) { | |
128 | (void) ftamoops (fti, FS_PRO_ERR, 1, EREF_RFPM, EREF_IFPM, NULLCP, | |
129 | NULLCP); | |
130 | goto out2; | |
131 | } | |
132 | ||
133 | if (decode_FTAM_PDU (pe, 1, NULLIP, NULLVP, &pdu) == NOTOK) { | |
134 | (void) ftamoops (fti, FS_PRO_ERRMSG, 1, EREF_RFPM, EREF_RFPM, | |
135 | NULLCP, "unable to parse PDU: %s", PY_pepy); | |
136 | goto out3; | |
137 | } | |
138 | if (pdu -> offset != type_FTAM_PDU_f__initialize__request) { | |
139 | (void) ftamoops (fti, FS_PRO_ERRPROC, 1, EREF_RFPM, EREF_RFPM, | |
140 | NULLCP, "expecting F-INITIALIZE-request, got %d", | |
141 | pdu -> offset); | |
142 | goto out3; | |
143 | } | |
144 | req = pdu -> un.f__initialize__request; | |
145 | ||
146 | fsbtrace (fsb, (fsb -> fsb_fd, "A-ASSOCIATE.INDICATION", | |
147 | "F-INITIALIZE-request", pe, 1)); | |
148 | ||
149 | fsb -> fsb_id = pe -> pe_context; | |
150 | ||
151 | if (req -> presentation__context__management) { | |
152 | if (!(fsb -> fsb_prequirements & PR_MANAGEMENT)) { | |
153 | req -> presentation__context__management = 0; | |
154 | fsb -> fsb_prequirements &= ~PR_RESTORATION; | |
155 | } | |
156 | } | |
157 | else | |
158 | fsb -> fsb_prequirements &= ~(PR_MANAGEMENT | PR_RESTORATION); | |
159 | if (req -> service__class) { | |
160 | if (fpm2bits (fsb, fclass_pairs, req -> service__class, | |
161 | &fsb -> fsb_class, fti) == NOTOK) | |
162 | goto out3; | |
163 | } | |
164 | else | |
165 | fsb -> fsb_class = FCLASS_TRANSFER; | |
166 | ||
167 | if (fpm2bits (fsb, funit_pairs, req -> functional__units, | |
168 | &fsb -> fsb_units, fti) == NOTOK) | |
169 | goto out3; | |
170 | /* conservative... */ | |
171 | if (fsb -> fsb_class & FCLASS_TRANSFER) | |
172 | fsb -> fsb_units |= FUNITS_TRANSFER; | |
173 | if (fsb -> fsb_class & FCLASS_TM) | |
174 | fsb -> fsb_units |= FUNITS_TM; | |
175 | if (fsb -> fsb_class & FCLASS_ACCESS) | |
176 | fsb -> fsb_units |= FUNITS_ACCESS; | |
177 | if (fsb -> fsb_class & FCLASS_MANAGE) | |
178 | fsb -> fsb_units |= FUNITS_MANAGE; | |
179 | if (!(fsb -> fsb_class &= | |
180 | (FCLASS_TRANSFER | FCLASS_TM | FCLASS_MANAGE | FCLASS_ACCESS))) { | |
181 | (void) ftamoops (fti, FS_ACS_CLASS, 1, EREF_RFPM, EREF_IFPM, | |
182 | NULLCP, NULLCP); | |
183 | goto out3; | |
184 | } | |
185 | if (!(fsb -> fsb_units & FUNIT_LIMITED) | |
186 | && (fsb -> fsb_units & FUNIT_ENHANCED)) { | |
187 | (void) ftamoops (fti, FS_PRO_ERRFUNIT, 1, EREF_RFPM, EREF_IFPM, | |
188 | NULLCP, | |
189 | "enhanced-file-management requires limited-file-management"); | |
190 | goto out3; | |
191 | } | |
192 | if (!(fsb -> fsb_units & FUNIT_GROUPING)) { /* XXX: should be OPTIONAL */ | |
193 | (void) ftamoops (fti, FS_PRO_ERRFUNIT, 1, EREF_RFPM, EREF_IFPM, | |
194 | NULLCP, | |
195 | "insufficient functional units for service class"); | |
196 | goto out3; | |
197 | } | |
198 | if (req -> attribute__groups | |
199 | && fpm2bits (fsb, fattr_pairs, req -> attribute__groups, | |
200 | &fsb -> fsb_attrs, fti) == NOTOK) | |
201 | goto out3; | |
202 | #ifdef notdef | |
203 | if ((fsb -> fsb_attrs & FATTR_SECURITY) | |
204 | && !(fsb -> fsb_attrs & FATTR_STORAGE)) { | |
205 | (void) ftamoops (fti, FS_ACS_GRP, 1, EREF_RFPM, EREF_IFPM, | |
206 | NULLCP, NULLCP); | |
207 | goto out3; | |
208 | } | |
209 | #endif | |
210 | ||
211 | fts -> fts_sd = fsb -> fsb_fd; | |
212 | fts -> fts_callingtitle = acs -> acs_callingtitle; /* struct copy */ | |
213 | bzero ((char *) &acs -> acs_callingtitle, sizeof acs -> acs_callingtitle); | |
214 | fts -> fts_calledtitle = acs -> acs_calledtitle; /* struct copy */ | |
215 | bzero ((char *) &acs -> acs_calledtitle, sizeof acs -> acs_calledtitle); | |
216 | if ((fsb -> fsb_context = oid_cpy (acs -> acs_context)) == NULLOID) { | |
217 | no_mem: ; | |
218 | (void) ftamoops (fti, FS_GEN_NOREASON, 1, EREF_RFPM, EREF_RFPM, | |
219 | NULLCP, "out of memory"); | |
220 | goto out3; | |
221 | } | |
222 | fts -> fts_context = acs -> acs_context; | |
223 | acs -> acs_context = NULLOID; | |
224 | fts -> fts_callingaddr = ps -> ps_calling; /* struct copy */ | |
225 | fts -> fts_calledaddr = ps -> ps_called; /* struct copy */ | |
226 | fts -> fts_manage = (fsb -> fsb_prequirements & PR_MANAGEMENT) ? 1 : 0; | |
227 | fts -> fts_class = fsb -> fsb_class; | |
228 | fts -> fts_units = fsb -> fsb_units; | |
229 | fts -> fts_attrs = fsb -> fsb_attrs; | |
230 | if (req -> shared__ASE__information | |
231 | && fpm2shared (fsb, req -> shared__ASE__information, | |
232 | &fts -> fts_sharedASE, fti) == NOTOK) | |
233 | goto out3; | |
234 | fts -> fts_fqos = fsb -> fsb_fqos = MY_FQOS; | |
235 | ||
236 | if (ps -> ps_ctxlist.pc_nctx > 1) { | |
237 | #define PC_XXX (-2) /* unique code */ | |
238 | ||
239 | int acsid; | |
240 | register struct type_FTAM_Contents__Type__List *dtn; | |
241 | register struct FTAMcontent *fx, | |
242 | *fx2; | |
243 | register struct PSAPcontext *px; | |
244 | register struct isodocument *id; | |
245 | ||
246 | fsb -> fsb_contexts = ps -> ps_ctxlist;/* struct copy */ | |
247 | bzero ((char *) &ps -> ps_ctxlist, sizeof ps -> ps_ctxlist); | |
248 | ||
249 | fx = fts -> fts_contents.fc_contents; | |
250 | ||
251 | (void) AcFindPCI (fsb -> fsb_fd, &acsid, aci); | |
252 | ||
253 | fx2 = fsb -> fsb_contents.fc_contents; | |
254 | fsb -> fsb_contents.fc_ncontent = 0; | |
255 | ||
256 | for (px = fsb -> fsb_contexts.pc_ctx, | |
257 | i = fsb -> fsb_contexts.pc_nctx - 1; | |
258 | i >= 0; | |
259 | px++, i--) | |
260 | if (px -> pc_id != fsb -> fsb_id | |
261 | && px -> pc_id != acsid | |
262 | && px -> pc_result == PC_ACCEPT) | |
263 | px -> pc_result = PC_XXX; | |
264 | ||
265 | for (dtn = req -> contents__type__list; dtn; dtn = dtn -> next) { | |
266 | if ((id = getisodocumentbytype (dtn -> Document__Type__Name)) | |
267 | == NULL) | |
268 | continue; | |
269 | for (px = fsb -> fsb_contexts.pc_ctx, | |
270 | i = fsb -> fsb_contexts.pc_nctx - 1; | |
271 | i >= 0; | |
272 | px++, i--) { | |
273 | if (px -> pc_id == fsb -> fsb_id | |
274 | || px -> pc_id == acsid | |
275 | || oid_cmp (id -> id_abstract, px -> pc_asn)) | |
276 | continue; | |
277 | break; | |
278 | } | |
279 | ||
280 | if (i < 0) | |
281 | continue; | |
282 | ||
283 | if ((fx2 -> fc_dtn = oid_cpy (dtn -> Document__Type__Name)) | |
284 | == NULLOID | |
285 | || (fx -> fc_dtn = oid_cpy (dtn -> Document__Type__Name)) | |
286 | == NULLOID) | |
287 | goto no_mem; | |
288 | fx2 -> fc_id = fx -> fc_id = px -> pc_id; | |
289 | if (px -> pc_result == PC_XXX) | |
290 | px -> pc_result = PC_ACCEPT; | |
291 | fx2 -> fc_result = fx -> fc_result = px -> pc_result; | |
292 | ||
293 | fx++, fts -> fts_contents.fc_ncontent++; | |
294 | fx2++, fsb -> fsb_contents.fc_ncontent++; | |
295 | } | |
296 | ||
297 | for (px = fsb -> fsb_contexts.pc_ctx, | |
298 | i = fsb -> fsb_contexts.pc_nctx - 1; | |
299 | i >= 0; | |
300 | px++, i--) | |
301 | if (px -> pc_result == PC_XXX) | |
302 | px -> pc_result = PC_REJECTED; | |
303 | ||
304 | #undef PC_XXX | |
305 | } | |
306 | else | |
307 | if (req -> contents__type__list) { | |
308 | (void) ftamoops (fti, FS_PRO_ERRPROC, 1, EREF_RFPM, EREF_IFPM, | |
309 | NULLCP, "content types management botched"); | |
310 | goto out3; | |
311 | } | |
312 | ||
313 | if (req -> initiator__identity | |
314 | && (fts -> fts_initiator = qb2str (req -> initiator__identity)) | |
315 | == NULL) | |
316 | goto no_mem; | |
317 | if (req -> account | |
318 | && (fts -> fts_account = qb2str (req -> account)) == NULL) | |
319 | goto no_mem; | |
320 | if (req -> filestore__password) { /* both choices are qbufs... */ | |
321 | register struct qbuf *qb = req -> filestore__password -> un.graphic; | |
322 | ||
323 | if ((fts -> fts_password = qb2str (qb)) == NULL) | |
324 | goto no_mem; | |
325 | fts -> fts_passlen = qb -> qb_len; | |
326 | } | |
327 | fts -> fts_ssdusize = fsb -> fsb_ssdusize; | |
328 | fts -> fts_qos = ps -> ps_qos; /* struct copy */ | |
329 | ||
330 | free_FTAM_PDU (pdu); | |
331 | ACSFREE (acs); | |
332 | ||
333 | return OK; | |
334 | ||
335 | out3: ; | |
336 | if (pdu) | |
337 | free_FTAM_PDU (pdu); | |
338 | ||
339 | out2: ; | |
340 | ACSFREE (acs); | |
341 | ||
342 | out1: ; | |
343 | pe = NULLPE; | |
344 | if ((pdu = (struct type_FTAM_PDU *) calloc (1, sizeof *pdu)) | |
345 | == NULL) | |
346 | goto carry_on; | |
347 | pdu -> offset = type_FTAM_PDU_f__initialize__response; | |
348 | if ((rsp = (struct type_FTAM_F__INITIALIZE__response *) | |
349 | calloc (1, sizeof *rsp)) == NULL) | |
350 | goto carry_on; | |
351 | pdu -> un.f__initialize__response = rsp; | |
352 | if (rsp -> state__result = (struct type_FTAM_State__Result *) | |
353 | calloc (1, sizeof *rsp -> state__result)) | |
354 | rsp -> state__result -> parm = FSTATE_FAILURE; | |
355 | if (rsp -> action__result = (struct type_FTAM_Action__Result *) | |
356 | calloc (1, sizeof *rsp -> action__result)) | |
357 | rsp -> action__result -> parm= FACTION_PERM; | |
358 | rsp -> functional__units = bits2fpm (fsb, funit_pairs, 0, fti); | |
359 | if (rsp -> ftam__quality__of__service = | |
360 | (struct type_FTAM_FTAM__Quality__Of__Service *) | |
361 | calloc (1, sizeof *rsp -> ftam__quality__of__service)) | |
362 | rsp -> ftam__quality__of__service -> parm = MY_FQOS; | |
363 | rsp -> diagnostic = diag2fpm (fsb, 1, fti -> fti_abort.fta_diags, 1, fti); | |
364 | rsp -> checkpoint__window = 1; | |
365 | ||
366 | if (encode_FTAM_PDU (&pe, 1, 0, NULLCP, pdu) != NOTOK) | |
367 | pe -> pe_context = fsb -> fsb_id; | |
368 | ||
369 | carry_on: ; | |
370 | fsbtrace (fsb, (fsb -> fsb_fd, "A-ASSOCIATE.RESPONSE(reject)", | |
371 | "F-INITIALIZE-response", pe, 0)); | |
372 | ||
373 | (void) AcAssocResponse (acs -> acs_sd, ACS_TRANSIENT, ACS_USER_NOREASON, | |
374 | NULLOID, NULLAEI, NULLPA, NULLPC, ps -> ps_defctxresult, 0, 0, | |
375 | SERIAL_NONE, 0, &ps -> ps_connect, pe ? &pe : NULLPEP, | |
376 | pe ? 1 : 0, aci); | |
377 | if (pe) | |
378 | pe_free (pe); | |
379 | if (pdu) | |
380 | free_FTAM_PDU (pdu); | |
381 | ||
382 | fsb -> fsb_fd = NOTOK; | |
383 | freefsblk (fsb); | |
384 | ||
385 | return NOTOK; | |
386 | } | |
387 | ||
388 | /* \f F-INITIALIZE.RESPONSE */ | |
389 | ||
390 | int FInitializeResponse (sd, state, action, context, respondtitle, | |
391 | respondaddr, manage, class, units, attrs, sharedASE, fqos, contents, | |
392 | diag, ndiag, fti) | |
393 | int sd; | |
394 | int state, | |
395 | action, | |
396 | manage, | |
397 | class, | |
398 | units, | |
399 | attrs, | |
400 | fqos; | |
401 | OID context; | |
402 | AEI respondtitle; | |
403 | struct PSAPaddr *respondaddr; | |
404 | PE sharedASE; | |
405 | struct FTAMcontentlist *contents; | |
406 | struct FTAMdiagnostic diag[]; | |
407 | int ndiag; | |
408 | struct FTAMindication *fti; | |
409 | { | |
410 | register int i; | |
411 | int result, | |
412 | status; | |
413 | PE pe; | |
414 | register struct FTAMcontentlist *pl; | |
415 | register struct FTAMcontent *px; | |
416 | struct AcSAPindication acis; | |
417 | register struct AcSAPindication *aci = &acis; | |
418 | register struct AcSAPabort *aca = &aci -> aci_abort; | |
419 | register struct ftamblk *fsb; | |
420 | register struct type_FTAM_PDU *pdu; | |
421 | register struct type_FTAM_F__INITIALIZE__response *rsp; | |
422 | ||
423 | if ((fsb = findfsblk (sd)) == NULL || (fsb -> fsb_flags & FSB_CONN)) | |
424 | return ftamlose (fti, FS_GEN_NOREASON, 0, NULLCP, | |
425 | "invalid ftam descriptor"); | |
426 | ||
427 | switch (state) { | |
428 | case FSTATE_SUCCESS: | |
429 | status = ACS_ACCEPT; | |
430 | break; | |
431 | ||
432 | case FSTATE_FAILURE: | |
433 | break; | |
434 | ||
435 | default: | |
436 | return ftamlose (fti, FS_GEN (fsb), 0, NULLCP, | |
437 | "bad value for state parameter"); | |
438 | } | |
439 | switch (action) { | |
440 | case FACTION_SUCCESS: | |
441 | if (state == FSTATE_SUCCESS) | |
442 | break; | |
443 | bad_pair: ; | |
444 | return ftamlose (fti, FS_GEN (fsb), 0, NULLCP, | |
445 | "bad value for state/action parameters"); | |
446 | ||
447 | case FACTION_TRANS: | |
448 | if (state != FSTATE_FAILURE) | |
449 | goto bad_pair; | |
450 | status = ACS_TRANSIENT; | |
451 | break; | |
452 | ||
453 | case FACTION_PERM: | |
454 | if (state != FSTATE_FAILURE) | |
455 | goto bad_pair; | |
456 | status = ACS_PERMANENT; | |
457 | break; | |
458 | ||
459 | default: | |
460 | return ftamlose (fti, FS_GEN (fsb), 0, NULLCP, | |
461 | "bad value for action parameter"); | |
462 | } | |
463 | #ifdef notdef | |
464 | missingP (context); | |
465 | missingP (respondtitle); | |
466 | missingP (respondaddr); | |
467 | #endif | |
468 | if (manage) { | |
469 | if (!(fsb -> fsb_prequirements & PR_MANAGEMENT)) | |
470 | return ftamlose (fti, FS_ACS_CONTEXT, 0, NULLCP, NULLCP); | |
471 | } | |
472 | else | |
473 | fsb -> fsb_prequirements &= ~(PR_MANAGEMENT | PR_RESTORATION); | |
474 | switch (class & fsb -> fsb_class) { | |
475 | case FCLASS_TRANSFER: | |
476 | case FCLASS_ACCESS: | |
477 | case FCLASS_MANAGE: | |
478 | case FCLASS_TM: | |
479 | fsb -> fsb_class &= class; | |
480 | break; | |
481 | ||
482 | default: | |
483 | return ftamlose (fti, FS_GEN (fsb), 0, NULLCP, | |
484 | "service class mismatch, offered 0x%x received 0x%x", | |
485 | fsb -> fsb_class, class); | |
486 | } | |
487 | if (units & ~fsb -> fsb_units) | |
488 | return ftamlose (fti, FS_GEN (fsb), 0, NULLCP, | |
489 | "functional units not open for negotiation"); | |
490 | if (!(units & FUNIT_LIMITED) && (units & FUNIT_ENHANCED)) | |
491 | return ftamlose (fti, FS_GEN (fsb), 0, NULLCP, | |
492 | "enhanced-file-management requires limited-file-management"); | |
493 | if (!((fsb -> fsb_units = units) & (FUNIT_RECOVERY | FUNIT_RESTART))) { | |
494 | fsb -> fsb_srequirements &= ~SR_MINORSYNC; | |
495 | fsb -> fsb_ssn = SERIAL_NONE; | |
496 | } | |
497 | switch (fsb -> fsb_class) { | |
498 | case FCLASS_TRANSFER: | |
499 | if (!(fsb -> fsb_units & FUNITS_TRANSFER)) | |
500 | goto not_enough; | |
501 | goto do_trans; | |
502 | case FCLASS_TM: | |
503 | if (!(fsb -> fsb_units & FUNITS_TM)) | |
504 | goto not_enough; | |
505 | do_trans: ; | |
506 | if (!(fsb -> fsb_units & (FUNIT_READ | FUNIT_WRITE))) { | |
507 | not_enough: ; | |
508 | return ftamlose (fti, FS_GEN (fsb), 0, NULLCP, | |
509 | "insufficient functional units for service class"); | |
510 | } | |
511 | if (fsb -> fsb_units & (FUNIT_ACCESS | FUNIT_FADULOCK)) { | |
512 | too_many: ; | |
513 | return ftamlose (fti, FS_GEN (fsb), 0, NULLCP, | |
514 | "illegal functional units for service class"); | |
515 | } | |
516 | break; | |
517 | ||
518 | case FCLASS_ACCESS: | |
519 | if (!(fsb -> fsb_units & FUNITS_ACCESS)) | |
520 | goto not_enough; | |
521 | break; | |
522 | ||
523 | case FCLASS_MANAGE: | |
524 | if (!(fsb -> fsb_units & FUNITS_MANAGE)) | |
525 | goto not_enough; | |
526 | if (fsb -> fsb_units & (FUNIT_READ | FUNIT_WRITE | |
527 | | FUNIT_ACCESS | FUNIT_FADULOCK | |
528 | | FUNIT_RECOVERY | FUNIT_RESTART)) | |
529 | goto too_many; | |
530 | break; | |
531 | } | |
532 | if (attrs & ~fsb -> fsb_attrs) | |
533 | return ftamlose (fti, FS_GEN (fsb), 0, NULLCP, | |
534 | "attribute groups not open for negotiation"); | |
535 | #ifdef notdef | |
536 | if ((attrs & FATTR_SECURITY) && !(attrs & FATTR_STORAGE)) | |
537 | return ftamlose (fti, FS_ACS_GRP, 0, NULLCP, NULLCP); | |
538 | #endif | |
539 | fsb -> fsb_attrs = attrs; | |
540 | if (fqos != MY_FQOS) | |
541 | return ftamlose (fti, FS_ACS_ROLLBACK, 1, NULLCP, | |
542 | "class-%d-recovery not supported", fqos); | |
543 | pl = &fsb -> fsb_contents; | |
544 | if (contents) { | |
545 | int acsid; | |
546 | register struct FTAMcontent *fx = contents -> fc_contents; | |
547 | ||
548 | if (contents -> fc_ncontent != pl -> fc_ncontent) | |
549 | return ftamlose (fti, FS_GEN (fsb), 0, NULLCP, | |
550 | "proposed/resulting content types mismatch"); | |
551 | ||
552 | (void) AcFindPCI (fsb -> fsb_fd, &acsid, aci); | |
553 | for (px = pl -> fc_contents, i = pl -> fc_ncontent - 1; | |
554 | i >= 0; | |
555 | px++, i--) { | |
556 | if (fx -> fc_id != px -> fc_id) | |
557 | return ftamlose (fti, FS_GEN (fsb), 0, NULLCP, | |
558 | "bad context id %d at offset %d (wanted %d)", | |
559 | fx -> fc_id, fx - contents -> fc_contents, | |
560 | px -> fc_id); | |
561 | switch (fx -> fc_result) { | |
562 | case PC_ACCEPT: | |
563 | case PC_REJECTED: | |
564 | if (px -> fc_result != PC_ACCEPT) { | |
565 | invalid_result: ; | |
566 | return ftamlose (fti, FS_GEN (fsb), 0, NULLCP, | |
567 | "invalid result %d for content id %d", | |
568 | fx -> fc_result, fx -> fc_id); | |
569 | } | |
570 | px -> fc_result = fx -> fc_result; | |
571 | break; | |
572 | ||
573 | default: | |
574 | if (px -> fc_result != fx -> fc_result) | |
575 | goto invalid_result; | |
576 | break; | |
577 | } | |
578 | ||
579 | fx++; | |
580 | } | |
581 | } | |
582 | ||
583 | toomuchP (diag, ndiag, NFDIAG, "diagnostic"); | |
584 | missingP (fti); | |
585 | ||
586 | if ((pdu = (struct type_FTAM_PDU *) calloc (1, sizeof *pdu)) == NULL) { | |
587 | no_mem: ; | |
588 | result = ftamlose (fti, FS_GEN (fsb), 1, NULLCP, "out of memory"); | |
589 | goto out; | |
590 | } | |
591 | pdu -> offset = type_FTAM_PDU_f__initialize__response; | |
592 | if ((rsp = (struct type_FTAM_F__INITIALIZE__response *) | |
593 | calloc (1, sizeof *rsp)) == NULL) | |
594 | goto no_mem; | |
595 | pdu -> un.f__initialize__response = rsp; | |
596 | if (state != int_FTAM_State__Result_success) { | |
597 | if ((rsp -> state__result = | |
598 | (struct type_FTAM_State__Result *) | |
599 | calloc (1, sizeof *rsp -> state__result)) | |
600 | == NULL) | |
601 | goto no_mem; | |
602 | rsp -> state__result -> parm = state; | |
603 | } | |
604 | if (action != int_FTAM_Action__Result_success) { | |
605 | if ((rsp -> action__result = | |
606 | (struct type_FTAM_Action__Result *) | |
607 | calloc (1, sizeof *rsp -> action__result)) | |
608 | == NULL) | |
609 | goto no_mem; | |
610 | rsp -> action__result -> parm = action; | |
611 | } | |
612 | rsp -> presentation__context__management = manage; | |
613 | if (fsb -> fsb_class != FCLASS_TRANSFER | |
614 | && (rsp -> service__class = bits2fpm (fsb, fclass_pairs, | |
615 | fsb -> fsb_class, fti)) | |
616 | == NULLPE) | |
617 | goto out; | |
618 | if ((rsp -> functional__units = bits2fpm (fsb, funit_pairs, | |
619 | fsb -> fsb_units, fti)) | |
620 | == NULLPE) | |
621 | goto out; | |
622 | if (fsb -> fsb_attrs | |
623 | && (rsp -> attribute__groups = bits2fpm (fsb, fattr_pairs, | |
624 | attrs, fti)) == NULLPE) | |
625 | goto out; | |
626 | if (sharedASE | |
627 | && (rsp -> shared__ASE__information = | |
628 | shared2fpm (fsb, sharedASE, fti)) == NULL) | |
629 | goto out; | |
630 | if ((rsp -> ftam__quality__of__service = | |
631 | (struct type_FTAM_FTAM__Quality__Of__Service *) | |
632 | calloc (1, sizeof *rsp -> ftam__quality__of__service)) | |
633 | == NULL) | |
634 | goto no_mem; | |
635 | rsp -> ftam__quality__of__service -> parm = fsb -> fsb_fqos; | |
636 | if (contents) { | |
637 | struct type_FTAM_Contents__Type__List *fpm; | |
638 | register struct type_FTAM_Contents__Type__List **fpc; | |
639 | ||
640 | fpc = &rsp -> contents__type__list; | |
641 | for (px = pl -> fc_contents, i = pl -> fc_ncontent - 1; | |
642 | i >= 0; | |
643 | px++, i--) | |
644 | if (px -> fc_result == PC_ACCEPT) { | |
645 | if ((fpm = (struct type_FTAM_Contents__Type__List *) | |
646 | calloc (1, sizeof *fpm)) == NULL) | |
647 | goto no_mem; | |
648 | *fpc = fpm; | |
649 | ||
650 | if ((fpm -> Document__Type__Name = oid_cpy (px -> fc_dtn)) | |
651 | == NULLOID) | |
652 | goto no_mem; | |
653 | fpc = &fpm -> next; | |
654 | } | |
655 | } | |
656 | ||
657 | if (ndiag > 0 | |
658 | && (rsp -> diagnostic = diag2fpm (fsb, 0, diag, ndiag, fti)) | |
659 | == NULL) | |
660 | goto out; | |
661 | rsp -> checkpoint__window = 1; | |
662 | ||
663 | if (encode_FTAM_PDU (&pe, 1, 0, NULLCP, pdu) == NOTOK) { | |
664 | (void) ftamlose (fti, FS_GEN (fsb), 1, NULLCP, | |
665 | "error encoding PDU: %s", PY_pepy); | |
666 | goto out; | |
667 | } | |
668 | ||
669 | pe -> pe_context = fsb -> fsb_id; | |
670 | ||
671 | fsbtrace (fsb, (fsb -> fsb_fd, "A-ASSOCIATE.RESPONSE", | |
672 | "F-INITIALIZE-response", pe, 0)); | |
673 | ||
674 | result = AcAssocResponse (fsb -> fsb_fd, status, status != ACS_ACCEPT | |
675 | ? ACS_USER_NOREASON : ACS_USER_NULL, | |
676 | context ? context : fsb -> fsb_context, respondtitle, | |
677 | respondaddr, &fsb -> fsb_contexts, PC_ACCEPT, | |
678 | fsb -> fsb_prequirements, fsb -> fsb_srequirements, | |
679 | fsb -> fsb_ssn, fsb -> fsb_settings, &fsb -> fsb_connect, | |
680 | &pe, 1, aci); | |
681 | ||
682 | pe_free (pe); | |
683 | pe = NULLPE; | |
684 | free_FTAM_PDU (pdu); | |
685 | pdu = NULL; | |
686 | ||
687 | if (result == NOTOK) { | |
688 | (void) acs2ftamlose (fsb, fti, "AcAssocResponse", aca); | |
689 | goto out; | |
690 | } | |
691 | ||
692 | fsb -> fsb_flags |= FSB_CONN; | |
693 | return OK; | |
694 | ||
695 | out: ; | |
696 | if (pe) | |
697 | pe_free (pe); | |
698 | if (pdu) | |
699 | free_FTAM_PDU (pdu); | |
700 | ||
701 | pe = NULLPE; | |
702 | if ((pdu = (struct type_FTAM_PDU *) calloc (1, sizeof *pdu)) | |
703 | == NULL) | |
704 | goto carry_on; | |
705 | pdu -> offset = type_FTAM_PDU_f__initialize__response; | |
706 | if ((rsp = (struct type_FTAM_F__INITIALIZE__response *) | |
707 | calloc (1, sizeof *rsp)) | |
708 | == NULL) | |
709 | goto carry_on; | |
710 | pdu -> un.f__initialize__response = rsp; | |
711 | if (rsp -> state__result = (struct type_FTAM_State__Result *) | |
712 | calloc (1, sizeof *rsp -> state__result)) | |
713 | rsp -> state__result -> parm = FSTATE_FAILURE; | |
714 | if (rsp -> action__result = (struct type_FTAM_Action__Result *) | |
715 | calloc (1, sizeof *rsp -> action__result)) | |
716 | rsp -> action__result -> parm= FACTION_PERM; | |
717 | rsp -> functional__units = bits2fpm (fsb, funit_pairs, 0, fti); | |
718 | if (rsp -> ftam__quality__of__service = | |
719 | (struct type_FTAM_FTAM__Quality__Of__Service *) | |
720 | calloc (1, sizeof *rsp -> ftam__quality__of__service)) | |
721 | rsp -> ftam__quality__of__service -> parm = MY_FQOS; | |
722 | rsp -> diagnostic = diag2fpm (fsb, 1, fti -> fti_abort.fta_diags, 1, fti); | |
723 | rsp -> checkpoint__window = 1; | |
724 | ||
725 | if (encode_FTAM_PDU (&pe, 1, 0, NULLCP, pdu) != NOTOK) | |
726 | pe -> pe_context = fsb -> fsb_id; | |
727 | ||
728 | carry_on: ; | |
729 | fsbtrace (fsb, (fsb -> fsb_fd, "A-ASSOCIATE.RESPONSE(reject)", | |
730 | "F-INITIALIZE-response", pe, 0)); | |
731 | ||
732 | (void) AcAssocResponse (fsb -> fsb_fd, ACS_TRANSIENT, ACS_USER_NOREASON, | |
733 | NULLOID, NULLAEI, NULLPA, NULLPC, PC_ACCEPT, 0, 0, SERIAL_NONE, | |
734 | 0, &fsb -> fsb_connect, pe ? &pe : NULLPEP, pe ? 1 : 0, aci); | |
735 | if (pe) | |
736 | pe_free (pe); | |
737 | if (pdu) | |
738 | free_FTAM_PDU (pdu); | |
739 | ||
740 | fsb -> fsb_fd = NOTOK; | |
741 | freefsblk (fsb); | |
742 | ||
743 | return NOTOK; | |
744 | } |