|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T f
Length: 18988 (0x4a2c) Types: TextFile Names: »ftaminitiate.c«
└─⟦3d0c2be1b⟧ Bits:30001254 ISODE-5.0 Tape └─⟦eba4602b1⟧ »./isode-5.0.tar.Z« └─⟦d3ac74d73⟧ └─⟦this⟧ »isode-5.0/ftam/ftaminitiate.c«
/* ftaminitiate.c - FPM: initiator */ #ifndef lint static char *rcsid = "$Header: /f/osi/ftam/RCS/ftaminitiate.c,v 6.0 89/03/18 23:30:44 mrose Rel $"; #endif /* * $Header: /f/osi/ftam/RCS/ftaminitiate.c,v 6.0 89/03/18 23:30:44 mrose Rel $ * * * $Log: ftaminitiate.c,v $ * Revision 6.0 89/03/18 23:30:44 mrose * Release 5.0 * */ /* * NOTICE * * Acquisition, use, and distribution of this module and related * materials are subject to the restrictions of a license agreement. * Consult the Preface in the User's Manual for the full terms of * this agreement. * */ /* LINTLIBRARY */ #include <stdio.h> #include <signal.h> #include "fpkt.h" #define FS_CTX "iso ftam" #define FS_ASN "ftam pci" /* \f F-INITIALIZE.REQUEST */ int FInitializeRequest (context, callingtitle, calledtitle, callingaddr, calledaddr, manage, class, units, attrs, sharedASE, fqos, contents, initiator, account, password, passlen, qos, tracing, ftc, fti) OID context; AEI callingtitle, calledtitle; struct PSAPaddr *callingaddr, *calledaddr; int manage, class, units, attrs, fqos, passlen; PE sharedASE; struct FTAMcontentlist *contents; char *initiator, *account, *password; struct QOStype *qos; IFP tracing; struct FTAMconnect *ftc; struct FTAMindication *fti; { SBV smask; int result; #ifdef notdef missingP (context); missingP (callingtitle); missingP (calledtitle); missingP (callingaddr); #endif missingP (calledaddr); if (manage) return ftamlose (fti, FS_ACS_CONTEXT, 1, NULLCP, NULLCP); if (units & ~MY_FUNIT) return ftamlose (fti, FS_ACS_FUNIT, 1, NULLCP, NULLCP); if ((class & FCLASS_TRANSFER && ((units & FUNITS_TRANSFER) != FUNITS_TRANSFER))) { not_enough: ; return ftamlose (fti, FS_GEN_NOREASON, 1, NULLCP, "insufficient functional units for service class"); } if ((class & FCLASS_TM) && ((units & FUNITS_TM) != FUNITS_TM)) goto not_enough; if ((class & (FCLASS_TRANSFER | FCLASS_TM)) && !(units & (FUNIT_READ | FUNIT_WRITE))) goto not_enough; if ((class & FCLASS_ACCESS) && ((units & FUNITS_ACCESS) != FUNITS_ACCESS)) goto not_enough; if ((class & FCLASS_MANAGE) && ((units & FUNITS_MANAGE) != FUNITS_MANAGE)) goto not_enough; if (!(class &= (FCLASS_TRANSFER | FCLASS_TM | FCLASS_MANAGE | FCLASS_ACCESS))) return ftamlose (fti, FS_ACS_CLASS, 1, NULLCP, NULLCP); if (!(units & FUNIT_LIMITED) && (units & FUNIT_ENHANCED)) return ftamlose (fti, FS_GEN_NOREASON, 1, NULLCP, "enhanced-file-management requires limited-file-management"); if (!(units & FUNIT_GROUPING)) /* XXX: should be OPTIONAL */ goto not_enough; if (attrs & ~MY_FATTR) return ftamlose (fti, FS_ACS_GRPSUP, 1, NULLCP, NULLCP); if ((attrs & FATTR_SECURITY) && !(attrs & FATTR_STORAGE)) return ftamlose (fti, FS_ACS_GRP, 1, NULLCP, NULLCP); if (contents && contents -> fc_ncontent > NFCONT) return ftamlose (fti, FS_GEN_NOREASON, 1, NULLCP, "too many content types"); if (password == NULL) passlen = 0; #ifdef notdef missingP (qos); #endif missingP (fti); smask = sigioblock (); result = FInitializeRequestAux (context, callingtitle, calledtitle, callingaddr, calledaddr, manage, class, units, attrs, sharedASE, fqos, contents, initiator, account, password, passlen, qos, tracing, ftc, fti); (void) sigiomask (smask); return result; } /* \f */ static int FInitializeRequestAux (context, callingtitle, calledtitle, callingaddr, calledaddr, manage, class, units, attrs, sharedASE, fqos, contents, initiator, account, password, passlen, qos, tracing, ftc, fti) OID context; AEI callingtitle, calledtitle; struct PSAPaddr *callingaddr, *calledaddr; int manage, class, units, attrs, fqos, passlen; PE sharedASE; struct FTAMcontentlist *contents; char *initiator, *account, *password; struct QOStype *qos; IFP tracing; struct FTAMconnect *ftc; struct FTAMindication *fti; { register int i; int bits, idc, result, settings; long isn; PE pe; OID ctx, pci; struct SSAPref *sr; register struct PSAPcontext *px; struct PSAPctxlist pls; register struct PSAPctxlist *pl = &pls; struct AcSAPconnect accs; register struct AcSAPconnect *acc = &accs; register struct PSAPconnect *pc = &acc -> acc_connect; struct AcSAPindication acis; register struct AcSAPindication *aci = &acis; register struct AcSAPabort *aca = &aci -> aci_abort; register struct FTAMcontent *fx; register struct ftamblk *fsb; struct type_FTAM_PDU *pdu; register struct type_FTAM_F__INITIALIZE__request *req; register struct type_FTAM_F__INITIALIZE__response *rsp; if ((fsb = newfsblk ()) == NULL) return ftamlose (fti, FS_GEN_NOREASON, 1, NULLCP, "out of memory"); fsb -> fsb_flags |= FSB_INIT; fsb -> fsb_trace = tracing; ctx = pci = NULLOID, pl -> pc_nctx = 0; bzero ((char *) ftc, sizeof *ftc); pdu = NULL; if (context == NULLOID && (context = ode2oid (FS_CTX)) == NULLOID) { result = ftamlose (fti, FS_ACS_MGMT, 1, NULLCP, "%s: unknown", FS_CTX); goto out1; } if ((ctx = oid_cpy (context)) == NULLOID) { no_mem: ; result = ftamlose (fti, FS_GEN_NOREASON, 1, NULLCP, "out of memory"); goto out1; } if ((pci = ode2oid (FS_ASN)) == NULLOID) { result = ftamlose (fti, FS_ACS_MGMT, 1, NULLCP, "%s: unknown", FS_ASN); goto out1; } if ((pci = oid_cpy (pci)) == NULLOID) goto no_mem; px = pl -> pc_ctx, pl -> pc_nctx = 0; px -> pc_id = fsb -> fsb_id = idc = 1; if ((px -> pc_asn = ode2oid (FS_ASN)) == NULLOID) { result = ftamlose (fti, FS_ACS_MGMT, 1, NULLCP, "%s: unknown", FS_ASN); goto out1; } if ((px -> pc_asn = oid_cpy (px -> pc_asn)) == NULLOID) goto no_mem; if ((px -> pc_atn = ode2oid (BER)) == NULLOID) { result = ftamlose (fti, FS_ACS_MGMT, 1, NULLCP, "%s: unknown", BER); goto out1; } if ((px -> pc_atn = oid_cpy (px -> pc_atn)) == NULLOID) goto no_mem; px++, pl -> pc_nctx++; if (contents) { register struct isodocument *id; for (fx = contents -> fc_contents, i = contents -> fc_ncontent - 1; i >= 0; fx++, i--) { if (fx -> fc_dtn == NULLOID) { result = ftamlose (fti, FS_GEN (fsb), 1, NULLCP, "empty content type at slot %d", contents -> fc_ncontent - i - 1); goto out1; } if ((id = getisodocumentbytype (fx -> fc_dtn)) == NULL) { result = ftamlose (fti, FS_GEN (fsb), 1, NULLCP, "unknown document type %s at slot %d", sprintoid (fx -> fc_dtn), contents -> fc_ncontent - i - 1); goto out1; } px -> pc_id = (idc += 2); if ((px -> pc_asn = oid_cpy (id -> id_abstract)) == NULLOID) goto no_mem; if ((px -> pc_atn = oid_cpy (id -> id_transfer)) == NULLOID) goto no_mem; px++, pl -> pc_nctx++; } } if ((pdu = (struct type_FTAM_PDU *) calloc (1, sizeof *pdu)) == NULL) goto no_mem; pdu -> offset = type_FTAM_PDU_f__initialize__request; if ((req = (struct type_FTAM_F__INITIALIZE__request *) calloc (1, sizeof *req)) == NULL) goto no_mem; pdu -> un.f__initialize__request = req; req -> presentation__context__management = manage; if (class != FCLASS_TRANSFER && (req -> service__class = bits2fpm (fsb, fclass_pairs, class, fti)) == NULLPE) goto out1; if ((req -> functional__units = bits2fpm (fsb, funit_pairs, units, fti)) == NULLPE) goto out1; if (attrs && (req -> attribute__groups = bits2fpm (fsb, fattr_pairs, attrs, fti)) == NULLPE) goto out1; if (sharedASE && (req -> shared__ASE__information = shared2fpm (fsb, sharedASE, fti)) == NULL) goto out1; if ((req -> ftam__quality__of__service = (struct type_FTAM_FTAM__Quality__Of__Service *) calloc (1, sizeof *req -> ftam__quality__of__service)) == NULL) goto no_mem; #ifdef lint req -> ftam__quality__of__service -> parm = fqos; #else req -> ftam__quality__of__service -> parm = MY_FQOS; #endif if (contents) { struct type_FTAM_Contents__Type__List *fpm; register struct type_FTAM_Contents__Type__List **fpc; fpc = &req -> contents__type__list; for (fx = contents -> fc_contents, i = contents -> fc_ncontent - 1; i >= 0; fx++, i--) { if ((fpm = (struct type_FTAM_Contents__Type__List *) calloc (1, sizeof *fpm)) == NULL) goto no_mem; *fpc = fpm; if ((fpm -> Document__Type__Name = oid_cpy (fx -> fc_dtn)) == NULLOID) goto no_mem; fpc = &fpm -> next; } } if (initiator && (req -> initiator__identity = str2qb (initiator, strlen (initiator), 1)) == NULL) goto out1; if (account && (req -> account = str2qb (account, strlen (account), 1)) == NULL) goto out1; if (password) { register struct type_FTAM_Password *p; if ((p = (struct type_FTAM_Password *) calloc (1, sizeof *p)) == NULL) goto no_mem; req -> filestore__password = p; p -> offset = type_FTAM_Password_binary; if ((p -> un.binary = str2qb (password, passlen, 1)) == NULL) goto no_mem; } req -> checkpoint__window = 1; if (encode_FTAM_PDU (&pe, 1, 0, NULLCP, pdu) == NOTOK) { (void) ftamlose (fti, FS_GEN (fsb), 1, NULLCP, "error encoding PDU: %s", PY_pepy); goto out1; } pe -> pe_context = fsb -> fsb_id; fsb -> fsb_srequirements = SR_DUPLEX | SR_RESYNC; fsb -> fsb_srequirements &= ~SR_RESYNC; /* XXX */ if (units & (FUNIT_RECOVERY | FUNIT_RESTART)) fsb -> fsb_srequirements |= SR_MINORSYNC; isn = (fsb -> fsb_srequirements & (SR_MINORSYNC | SR_RESYNC)) ? 1L : SERIAL_NONE; fsb -> fsb_prequirements = manage ? (PR_MANAGEMENT | PR_RESTORATION) : 0; settings = 0; #define dotoken(requires,shift,bit,type) \ { \ if (fsb -> fsb_srequirements & requires) \ settings |= ST_INIT_VALUE << shift; \ } dotokens (); #undef dotoken if ((sr = addr2ref (PLocalHostName ())) == NULL) goto no_mem; fsbtrace (fsb, (fsb -> fsb_fd, "A-ASSOCIATE.REQUEST", "F-INITIALIZE-request", pe, 0)); result = AcAssocRequest (ctx, callingtitle, calledtitle, callingaddr, calledaddr, pl, NULLOID /* pci */, fsb -> fsb_prequirements, fsb -> fsb_srequirements, isn, settings, sr, &pe, 1, qos, acc, aci); if (result == NOTOK) { (void) acs2ftamlose (fsb, fti, "AcAssocRequest", aca); goto out1; } fsb -> fsb_fd = acc -> acc_sd; pe_free (pe); pe = NULLPE; free_FTAM_PDU (pdu); pdu = NULL; oid_free (ctx); ctx = NULLOID; oid_free (pci); pci = NULLOID; for (px = pl -> pc_ctx, i = pl -> pc_nctx - 1; i >= 0; px++, i--) { if (px -> pc_asn) oid_free (px -> pc_asn); if (px -> pc_atn) oid_free (px -> pc_atn); } if (acc -> acc_ninfo < 1 || (pe = acc -> acc_info[0]) == NULLPE) { if (acc -> acc_result != ACS_ACCEPT) { register struct FTAMabort *fta = &fti -> fti_abort; aca -> aca_reason = acc -> acc_result; (void) acs2ftamlose (fsb, fti, "AcAssocRequest(pseudo)", aca); ftc -> ftc_sd = NOTOK; ftc -> ftc_state = FSTATE_FAILURE; ftc -> ftc_action = FACTION_PERM; *ftc -> ftc_diags = *fta -> fta_diags; /* struct copy */ ftc -> ftc_ndiag = fta -> fta_ndiag; result = OK; } else result = fpktlose (fsb, fti, FS_PRO_ERR, NULLCP, NULLCP); goto out2; } if (decode_FTAM_PDU (pe, 1, NULLIP, NULLVP, &pdu) == NOTOK) { result = fpktlose (fsb, fti, FS_PRO_ERRMSG, NULLCP, "unable to parse PDU: %s", PY_pepy); goto out2; } if (pdu -> offset != type_FTAM_PDU_f__initialize__response) { result = fpktlose (fsb, fti, FS_PRO_ERRPROC, NULLCP, "expecting F-INITIALIZE-response, got %d", pdu -> offset); goto out2; } rsp = pdu -> un.f__initialize__response; fsbtrace (fsb, (fsb -> fsb_fd, "A-ASSOCIATE.CONFIRMATION", "F-INITIALIZE-response", pe, 1)); ftc -> ftc_state = rsp -> state__result ? rsp -> state__result -> parm : int_FTAM_State__Result_success; ftc -> ftc_action = rsp -> action__result ? rsp -> action__result -> parm : int_FTAM_Action__Result_success; switch (acc -> acc_result) { case ACS_ACCEPT: if (ftc -> ftc_state != FSTATE_SUCCESS || ftc -> ftc_action != FACTION_SUCCESS) { result = fpktlose (fsb, fti, FS_PRO_ERRPROC, NULLCP, "state/action mismatch"); goto out2; } fsb -> fsb_flags |= FSB_CONN; fsb -> fsb_srequirements &= pc -> pc_srequirements; #define dotoken(requires,shift,bit,type) \ { \ if (fsb -> fsb_srequirements & requires) \ switch (pc -> pc_settings & (ST_MASK << shift)) { \ case ST_INIT_VALUE << shift: \ fsb -> fsb_owned |= bit; \ fsb -> fsb_avail |= bit; \ break; \ \ case ST_RESP_VALUE << shift: \ fsb -> fsb_avail |= bit; \ break; \ \ default: \ result = fpktlose (fsb, fti, FS_PRO_ERRPROC, NULLCP, \ "%s token management botched", type); \ goto out2; \ } \ } dotokens (); #undef dotoken if (fsb -> fsb_owned != fsb -> fsb_avail) { result = fpktlose (fsb, fti, FS_PRO_ERRPROC, NULLCP, "token management botched"); goto out2; } fsb -> fsb_ssdusize = pc -> pc_ssdusize; pl = &pc -> pc_ctxlist; if (pl -> pc_nctx > 0 && pl -> pc_ctx[0].pc_result != PC_ACCEPT) { result = fpktlose (fsb, fti, FS_PRO_ERRPROC, NULLCP, "FTAM PCI rejected"); goto out2; } fsb -> fsb_prequirements &= pc -> pc_prequirements; if (rsp -> presentation__context__management) { if (!(fsb -> fsb_prequirements & PR_MANAGEMENT)) { result = fpktlose (fsb, fti, FS_PRO_ERRPROC, NULLCP, "presentation content management mismatch"); goto out2; } } else fsb -> fsb_prequirements &= ~PR_MANAGEMENT; if (rsp -> service__class) { if (fpm2bits (fsb, fclass_pairs, rsp -> service__class, &bits, fti) == NOTOK) goto out2; } else bits = FCLASS_TRANSFER; switch (fsb -> fsb_class = (bits & class)) { case FCLASS_TRANSFER: i = FUNITS_TRANSFER; break; case FCLASS_ACCESS: i = FUNITS_ACCESS; break; case FCLASS_MANAGE: i = FUNITS_MANAGE; break; case FCLASS_TM: i = FUNITS_TM; break; case FCLASS_UNCONS: i = FUNITS_UNCONS; break; default: result = fpktlose (fsb, fti, FS_PRO_ERRPROC, NULLCP, "service class mismatch, offered 0x%x received 0x%x", class, bits); goto out2; } if (fpm2bits (fsb, funit_pairs, rsp -> functional__units, &bits, fti) == NOTOK) goto out2; bits |= i; /* conservative... */ if ((fsb -> fsb_units = bits) & ~units) { result = fpktlose (fsb, fti, FS_PRO_ERRFUNIT, NULLCP, "functional unit mismatch"); goto out2; } if (!(fsb -> fsb_units & FUNIT_GROUPING)) { /* XXX: should be OPTIONAL */ result = fpktlose (fsb, fti, FS_PRO_ERRFUNIT, NULLCP, "insufficient functional units for service class"); goto out2; } switch (fsb -> fsb_class) { case FCLASS_TRANSFER: case FCLASS_TM: if (fsb -> fsb_units & (FUNIT_ACCESS | FUNIT_FADULOCK)) { too_many: ; result = fpktlose (fsb, fti, FS_PRO_ERRFUNIT, NULLCP, "illegal functional units for service class"); goto out2; } break; case FCLASS_MANAGE: if (fsb -> fsb_units & (FUNIT_READ | FUNIT_WRITE | FUNIT_ACCESS | FUNIT_FADULOCK | FUNIT_RECOVERY | FUNIT_RESTART)) goto too_many; break; } if (rsp -> attribute__groups) { if (fpm2bits (fsb, fattr_pairs, rsp -> attribute__groups, &bits, fti) == NOTOK) goto out2; } else bits = 0; if (bits & ~attrs) { result = fpktlose (fsb, fti, FS_PRO_ERRPROC, NULLCP, "attribute group mismatch"); goto out2; } fsb -> fsb_attrs = bits; if (rsp -> ftam__quality__of__service -> parm != MY_FQOS) { result = fpktlose (fsb, fti, FS_ACS_ROLLBACK, NULLCP, "class-%d-recovery not supported", rsp -> ftam__quality__of__service -> parm); goto out2; } fsb -> fsb_fqos = MY_FQOS; ftc -> ftc_sd = fsb -> fsb_fd; break; default: ftc -> ftc_sd = NOTOK; if (ftc -> ftc_state == FSTATE_SUCCESS && ftc -> ftc_action == FACTION_SUCCESS) { result = fpktlose (fsb, fti, FS_PRO_ERRPROC, NULLCP, "state/action mismatch"); goto out2; } { register struct FTAMabort *fta = &fti -> fti_abort; bzero ((char *) fta, sizeof *fta); fta -> fta_peer = 1; } break; } ftc -> ftc_respondtitle = acc -> acc_respondtitle; /* struct copy */ bzero ((char *) &acc -> acc_respondtitle, sizeof acc -> acc_respondtitle); ftc -> ftc_respondaddr = pc -> pc_responding; /* struct copy */ ftc -> ftc_context = acc -> acc_context; acc -> acc_context = NULLOID; ftc -> ftc_manage = (fsb -> fsb_prequirements & PR_MANAGEMENT) ? 1 : 0; ftc -> ftc_class = fsb -> fsb_class; ftc -> ftc_units = fsb -> fsb_units; ftc -> ftc_attrs = fsb -> fsb_attrs; if (rsp -> shared__ASE__information && fpm2shared (fsb, rsp -> shared__ASE__information, &ftc -> ftc_sharedASE, fti) == NOTOK) goto out2; ftc -> ftc_fqos = fsb -> fsb_fqos; if (contents) { register struct type_FTAM_Contents__Type__List *dtn; register struct FTAMcontent *fx2; fx2 = ftc -> ftc_contents.fc_contents; for (fx = contents -> fc_contents, i = contents -> fc_ncontent - 1; i >= 0; fx++, i--) { for (dtn = rsp -> contents__type__list; dtn; dtn = dtn -> next) if (oid_cmp (fx -> fc_dtn, dtn -> Document__Type__Name) == 0) break; if (dtn == NULL) continue; px = pl -> pc_ctx + 1 + (fx - contents -> fc_contents); fx2 -> fc_dtn = dtn -> Document__Type__Name; fx2 -> fc_id = px -> pc_id; fx2 -> fc_result = px -> pc_result; fx2++, ftc -> ftc_contents.fc_ncontent++; } for (dtn = rsp -> contents__type__list; dtn; dtn = dtn -> next) { for (fx2 = ftc -> ftc_contents.fc_contents, i = ftc -> ftc_contents.fc_ncontent - 1; i >= 0; fx2++, i--) if (dtn -> Document__Type__Name == fx2 -> fc_dtn) { dtn -> Document__Type__Name = NULLOID; break; } } } if (rsp -> diagnostic) (void) fpm2diag (fsb, rsp -> diagnostic, ftc -> ftc_diags, &ftc -> ftc_ndiag, fti); ftc -> ftc_ssdusize = fsb -> fsb_ssdusize; ftc -> ftc_qos = pc -> pc_qos; /* struct copy */ free_FTAM_PDU (pdu); ACCFREE (acc); if (acc -> acc_result != ACS_ACCEPT) freefsblk (fsb); return OK; out2: ; ACCFREE (acc); out1: ; if (pdu) free_FTAM_PDU (pdu); if (ctx) oid_free (ctx); if (pci) oid_free (pci); for (px = pl -> pc_ctx, i = pl -> pc_nctx - 1; i >= 0; px++, i--) { if (px -> pc_asn) oid_free (px -> pc_asn); if (px -> pc_atn) oid_free (px -> pc_atn); } freefsblk (fsb); return result; }