#ifndef lint static char *sccsid = "@(#)osif_api_resp.c V3.2+ 26-SEP-1995"; #endif /* ** ** FTAM API Example code, for responder side. ** ** To use this code on your system, you may have to set the local and remote ** addresses correctly (see the macro definitions below). ** ***** ** ** Copyright (c) Digital Equipment Corporation 1995. All rights reserved. ** ** Restricted Rights: Use, duplication, or disclosure by the U.S. ** Government is subject to restrictions as set forth in subparagraph ** (c) (1) (ii) of DFARS 252.227-7013, or in FAR 52.227-19, or in FAR ** 52.227-14 Alt. III, as applicable. ** ** This software is proprietary to and embodies the confidential ** technology of Digital Equipment Corporation. Possession, use, or ** copying of this software and media is authorized only pursuant to a ** valid written license from Digital or an authorized sublicensor. ** ** MODIFICATION HISTORY ** 001 Mohamed S. Abd El-Mohsen 19-Feb-2003 ** Porting to OpenVMS for Itanium ** */ #define TRUE 1 #define FALSE 0 /* ** ** INCLUDE FILES ** */ #include /* FTAM API */ #include #include #if defined (unix) #include #include #include #elif defined (VMS) #include #include #include #endif #include /* ** ** TABLE OF CONTENTS ** */ extern int begin_group_response (); extern int change_attributes_response (); extern int close_response (); extern int create_response (); extern int delete_response (); extern int deselect_response (); extern int end_group_response (); extern int init_response (); extern int open_response (); extern int read_attributes_response (); extern int select_response (); extern int transfer_end_response (); extern int terminate_response (); extern int write_file (); extern int osif_assign_port(); /* [001] */ extern uint msg_print_stack(); /* [001] */ extern int osif_give_buffer(); /* [001] */ extern int print_error_message (); /* [001] */ extern int osif_get_event(); /* [001] */ extern int osif_deassign_port(); /* [001] */ extern int osif__init_scratch_pad (); /* [001] */ extern unsigned char *osif__malloc_scratch_pad (); /* [001] */ extern int osif_send(); /* [001] */ extern int open(); /* [001] */ extern int close(); /* [001] */ extern int write(); /* [001] */ extern int creat(); /* [001] */ extern void *malloc(); /* [001] */ extern void free(); /* [001] */ extern void exit(); /* [001] */ /* ** ** MACRO DEFINITIONS ** */ #define MAX_FTAM1_SIZE 132 #define MAX_FTAM2_SIZE 512 #define MAX_FTAM3_SIZE 8192 unsigned char ftam1_data[ MAX_FTAM1_SIZE ]; unsigned char ftam2_data[ MAX_FTAM2_SIZE ]; unsigned char ftam3_data[ MAX_FTAM3_SIZE ]; char ftamd_alias[255]; extern int state_logging; int print_primitives; int fn_mode; char dt[9]; char file_name_buffer[30]; /* ** ***** The following may need to be changed ***** ** ** The following macros are for the local presentation address. ** ** LOCAL_P_ADDRESS presentation selector, session selector, and ** transport selector (psel.ssel.tsel.) ** LOCAL_NSAP local NSAP ** LOCAL_TEMPLATE local transport template ** LOCAL_PROVIDER local transport provider ** ** To run this example responder with the example initiator, no modifications ** are required. If you wish, you may change any of the address information ** for your system (e.g. to use RFC1006 instead of CLNS, or to use a different ** psel.ssel.tsel). ** */ #if defined (VMS) #define LOCAL_P_ADDRESS "APIPPM.APISPM.APITPM." #define LOCAL_NSAP "" #define LOCAL_TEMPLATE "osit$loop_clns" #define LOCAL_PROVIDER "osi" #else #define LOCAL_P_ADDRESS "apippm.apispm.apitpm." #define LOCAL_NSAP "" #define LOCAL_TEMPLATE "default" #define LOCAL_PROVIDER "osi" #endif /* ** These are constants to describe the size and number ** of buffers passed down to the interface */ #define BUFFER_SIZE (8*1024) #define BUFFER_COUNT 1 #define ZERO(Thing) {memset((void *)&Thing,0x00,sizeof(Thing));} #define CHECK_STATUS { \ if (status) \ { \ msg_print_stack(0); \ exit (1); \ };} /* See comments in initiator example program for what these example programs do. */ main(argc, argv) int argc; char **argv; { unsigned status; unsigned event; unsigned error_status; unsigned port_id; int xfer_not_finished = 0; struct osifpb response_pb; struct osifpb indication_pb; struct osifpb assign_pb; struct osifpb init; struct osifpb begin_group; struct osifpb select; struct osifpb read_attribute; struct osifpb deselect; struct osifpb end_group; struct osifpb open; struct osifpb create; struct osifpb delete; struct osifpb change_attributes; struct osifpb close; struct osif_buffer_list *buffer_list; struct osif_buffer_list *buf_entry; /* Variable for buffer allocation */ int i; /* Variable for loop control */ int fd; /* File descriptor */ int forvar; int done = FALSE; int ftam_data_length = 0; int ind_pb_size; /* getop() external variables: */ extern int optind; /* argv index of next option */ extern int opterr; /* control getop() messages */ extern char *optarg; /* ptr to option argument */ int c; extern int optind; /* argv index of next option */ struct ae_entry *ae_entryptr; char pb_name[45]; printf("FTAM API example responder starting\n"); /* * Initialize structures. */ ZERO( assign_pb ); /* ** loop until the end of command options from perf call; ** set flags for each option found or set error flag */ while ( (c = getopt(argc, argv, "LPT:")) != EOF ) { switch (c) { case 'L': /** flag for state-logging **/ state_logging=1; break; case 'P': /* printing timer for primitives flag */ print_primitives = 1; break; } } for (i=0;inext = 0; buffer_list->buffer_length = BUFFER_SIZE; buffer_list->bufferptr = (char *) malloc( BUFFER_SIZE ); status = osif_give_buffer( port_id, buffer_list, &error_status ); if (status != 0) print_error_message("osif_give_buffer: ", error_status); } /* * Get the event */ bzero(&indication_pb, sizeof (struct osifpb)); status = osif_get_event( port_id, &indication_pb, -1, &error_status ); if (status != 0) print_error_message ("osif_get_event: ", error_status); /* * Based on the parameter block type, perform the corresponding * routine */ switch( indication_pb.osif_block_type ) { case OSIF_PBDEF_INIT_REQ: init = indication_pb; status = init_response( port_id, &init ); if (status != 0) printf("Error in init_response \n"); break; case OSIF_PBDEF_BG_REQ: begin_group = indication_pb; status = begin_group_response( port_id, &begin_group ); if (status != 0) printf("Error in begin_group_response \n"); break; case OSIF_PBDEF_DELETE_REQ: delete = indication_pb; status = delete_response( port_id, &begin_group ); if (status != 0) printf("Error in delete_response \n"); break; case OSIF_PBDEF_CHAT_REQ: change_attributes = indication_pb; status= change_attributes_response ( port_id, &change_attributes, &indication_pb.osif_filename->filename); if (status != 0) printf("Error in change_attributes_response \n"); break; case OSIF_PBDEF_SEL_REQ: select = indication_pb; status = select_response(port_id, &select, &indication_pb.osif_filename->filename); if (status != 0) printf("Error in select_response \n"); break; case OSIF_PBDEF_RAT_REQ: read_attribute = indication_pb; status = read_attributes_response ( port_id, &read_attribute, &create); if (status !=0 ) printf("Error in read_attributes_response \n"); break; case OSIF_PBDEF_DESELECT_REQ: deselect = indication_pb; status = deselect_response( port_id, &deselect ); if (status !=0 ) printf("Error in deselect_response \n"); break; case OSIF_PBDEF_OPEN_REQ: open = indication_pb; status = open_response ( port_id, &open); if (status !=0 ) printf("Error in open_response \n"); break; case OSIF_PBDEF_CRE_REQ: create = indication_pb; status = create_response(port_id, &create, &indication_pb.osif_filename->filename, &indication_pb.osif_contents_type.document_name); if (status !=0 ) printf("Error in create_response \n"); break; case OSIF_PBDEF_CLOSE_REQ: close = indication_pb; status = close_response(port_id, &close); if (status !=0 ) printf("Error in close_response \n"); break; case OSIF_PBDEF_EG_REQ: end_group = indication_pb; status = end_group_response( port_id, &end_group); if (status !=0 ) printf("Error in end_group_response \n"); break; case OSIF_PBDEF_P_ABORT: status = osif_deassign_port( port_id, &buffer_list, OSIF_ASSIGN_RESPONDER, &error_status ); if (status !=0 ) print_error_message("osif_deassign_port: ", error_status); done = TRUE; exit (); break; case OSIF_PBDEF_WRITE_REQ: write_file (port_id, &indication_pb); break; case OSIF_PBDEF_TRANSFER_END_REQ: status = transfer_end_response ( port_id, &indication_pb ); if (status !=0 ) printf("Error in transfer_end_response \n"); break; case OSIF_PBDEF_TERM_REQ: status = terminate_response( port_id, &indication_pb ); if (status !=0 ) printf("Error in terminate_response \n"); done = TRUE; break; } /* end of switch */ } printf("FTAM API example responder completed successfully\n"); } init_response( port_id, indication_pb ) /* **++ ** FUNCTIONAL DESCRIPTION: ** ** This routine builds an f-initialize-response from an ** f-initialize-request, and sends it to the initiator. ** ** FORMAL PARAMETERS: ** port_id - currently assigned port ** indication_pb - initialize request pb pointer ** ** IMPLICIT INPUTS: ** None ** ** IMPLICIT OUTPUTS: ** ** None ** ** COMPLETION CODES: ** ** ** ** SIDE EFFECTS: ** ** The 'osifpb' structure is filled in. ** **-- */ unsigned port_id; struct osifpb *indication_pb; { unsigned status; unsigned error_status; struct osifpb f_initialize_response; int i; struct osif_ctl *te,*qblk; /* Place holders for this entry */ struct osif_diagnostics_pb local_diag; printf("initializing connection...\n"); /* * Zero fill the parameter block * and initialize the scratchpad memory allocation aread */ bzero(&f_initialize_response, sizeof(f_initialize_response)); osif__init_scratch_pad( &f_initialize_response ); /* * Set the f-initialize function code in the parameter block */ f_initialize_response.osif_block_type = OSIF_PBDEF_INIT_RSP; f_initialize_response.osif_block_size = sizeof(f_initialize_response); /* * Set the Action result */ f_initialize_response.osif_action_result.value = 0; f_initialize_response.osif_action_result.length = 4; /* * The initiator had proposed the transfer, management, transfer * and management class to the responder. The responder chooses * the transfer management class since this is the highest service * class among those proposed by the initiator. * Note that the responder can only choose ONE of the service * classes proposed by the initiator. */ f_initialize_response.osif_service_class.value = OSIF_CLASS_XFR_MGMT; f_initialize_response.osif_service_class.length = 4; /* * The responder takes on the functional unit value as proposed * by the initiator. */ f_initialize_response.osif_functional_units.value = indication_pb->osif_functional_units.value; f_initialize_response.osif_functional_units.length = indication_pb->osif_functional_units.length; /* * Set the attribute groups */ f_initialize_response.osif_attribute_groups.value = indication_pb->osif_attribute_groups.value; f_initialize_response.osif_attribute_groups.length = indication_pb->osif_attribute_groups.length; /* * Set the ftam quality of service */ f_initialize_response.osif_ftam_qual_service.value = indication_pb->osif_ftam_qual_service.value; f_initialize_response.osif_ftam_qual_service.length = indication_pb->osif_ftam_qual_service.length; /* * Set the peer PSAP address and length */ f_initialize_response.osif_peer_p_addrs.p_address = indication_pb->osif_peer_p_addrs.p_address; for (i=0; i < OSIF_MAX_NSAPS; i++) { f_initialize_response.osif_peer_p_addrs.nsap_queue[i] = indication_pb->osif_peer_p_addrs.nsap_queue[i]; } /* * Just copy the initialize request contents type list into * the initialize response * * Initialize a Contents type list queue, * and add document type names to the queue */ f_initialize_response.osif_contents_type_list = 0; if ( indication_pb->osif_contents_type_list ) { for ( te = indication_pb->osif_contents_type_list; (0 != te) ; te = te->next ) { qblk = (struct osif_ctl *) osif__malloc_scratch_pad(&f_initialize_response, sizeof( struct osif_ctl )); qblk->document_name.address = te->document_name.address; qblk->document_name.length = te->document_name.length; qblk->next = f_initialize_response.osif_contents_type_list; f_initialize_response.osif_contents_type_list = qblk; } } /* * Send the f-initialize to the initiator */ status = osif_send( port_id, &f_initialize_response, &error_status ); if (status != OSIF_SUCCESS) print_error_message("osif_send: initialize response: ", error_status); return( status ); } open_response ( port_id, indication_pb ) /* **++ ** FUNCTIONAL DESCRIPTION: ** ** This routine builds an f-open-accept from an ** f-open-request, and sends it to the initiator. ** ** FORMAL PARAMETERS: ** ** chan - currently assigned port ** indication_pb - initialize request pb pointer ** ** IMPLICIT INPUTS: ** ** None ** ** IMPLICIT OUTPUTS: ** ** None ** ** COMPLETION CODES: ** ** ** SIDE EFFECTS: ** ** The 'osifpb' structure is filled in, and the file is opened. ** **-- */ unsigned port_id; struct osifpb *indication_pb; { unsigned status; unsigned error_status; struct osifpb f_open_response; struct osif_diagnostics_pb local_diag; int fd; printf("opening file...\n"); /* * Open the file */ if ((fd = open(file_name_buffer, 2)) == -1) printf("Error in opening file %s", file_name_buffer); close (fd); /* * Zero fill the parameter block * and initialize the scratchpad memory allocation aread */ bzero(&f_open_response, sizeof(struct osifpb)); osif__init_scratch_pad( &f_open_response ); /* * Set the open response function code in the parameter block */ f_open_response.osif_block_type = OSIF_PBDEF_OPEN_RSP; f_open_response.osif_block_size = sizeof(f_open_response); f_open_response.osif_action_result.value = 0; f_open_response.osif_action_result.length = sizeof( f_open_response.osif_action_result.value ); f_open_response.osif_contents_type.document_name.address = (unsigned char *)dt; f_open_response.osif_contents_type.document_name.length = strlen(dt); /* * Document Type Parameters */ f_open_response.osif_contents_type.document_param.string_significance.value = OSIF_STRSIG_NS; f_open_response.osif_contents_type.document_param.string_significance.length= 4; f_open_response.osif_contents_type.document_param.max_string_length.value = OSIF_MSL_UNLIMITED; f_open_response.osif_contents_type.document_param.max_string_length.length = 4; f_open_response.osif_contents_type.document_param.universal_class.value = OSIF_UC_GENERAL; f_open_response.osif_contents_type.document_param.universal_class.length = 4; status = osif_send( port_id, &f_open_response, &error_status ); if (status != OSIF_SUCCESS) print_error_message("osif_send: open response: ", error_status); return( status ); } select_response ( port_id, indication_pb, file_name_dscptr ) /* **++ ** FUNCTIONAL DESCRIPTION: ** ** This routine builds an f-select-accept from an ** f-select-request, and sends it to the initiator. ** ** FORMAL PARAMETERS: ** ** port_id - currently assigned port ** indication_pb - initialize request pb pointer ** ** IMPLICIT INPUTS: ** ** None ** ** IMPLICIT OUTPUTS: ** ** None ** ** COMPLETION CODES: ** ** ** ** SIDE EFFECTS: ** ** The 'osifpb' structure is filled in. ** structure ** **-- */ unsigned port_id; struct osifpb *indication_pb; struct osif_sdesc *file_name_dscptr; { unsigned status; unsigned error_status; struct osifpb f_select_response; int i; struct osif_ctl *te,*qblk; /* Place holders for this entry */ struct osif_fn select_filename; printf("selecting file...\n"); file_name_dscptr->address[file_name_dscptr->length] = '\0'; /* * Zero fill the parameter block * and initialize the scratchpad memory allocation aread */ bzero(&f_select_response, sizeof(f_select_response)); osif__init_scratch_pad( &f_select_response ); /* * Set the select response in the parameter block */ f_select_response.osif_block_type = OSIF_PBDEF_SEL_RSP; f_select_response.osif_block_size = sizeof(f_select_response); /* * Set the Action result in the parameter block */ f_select_response.osif_action_result.value = 0; f_select_response.osif_action_result.length = sizeof( f_select_response.osif_action_result.value ); /* * Set up the filename structure. */ select_filename.next = 0; select_filename.filename.address = (unsigned char *)file_name_dscptr->address; select_filename.filename.length = file_name_dscptr->length; /* * Store the address of the filename structure in the parameter block */ f_select_response.osif_filename = &select_filename; /* * Send to initiator */ status = osif_send( port_id, &f_select_response, &error_status ); if (status != OSIF_SUCCESS) print_error_message("osif_send: select response: ", error_status); return( status ); } write_file(port_id, indication_pb) /* **++ ** FUNCTIONAL DESCRIPTION: ** ** This routine writes the userdata to the file ** ** ** FORMAL PARAMETERS: ** ** port_id ** indication_pb ** ** IMPLICIT INPUTS: ** ** None ** ** IMPLICIT OUTPUTS: ** ** None ** ** COMPLETION CODES: ** ** ** ** SIDE EFFECTS: ** ** User data is written into the file ** **-- */ unsigned port_id; struct osifpb indication_pb; { unsigned status; int xfer_not_finished = 0; int n_written; struct osif_buffer_list *buffer_list; struct osif_buffer_list *buf_entry; /* Variable for buffer allocation */ unsigned error_status; int i; int fd; printf("writing file...\n"); /* * Open the file for writing */ if ((fd = open (file_name_buffer, 2)) == -1) printf("Error in opening file %s", file_name_buffer); /* * Continue writing until we receive a DATA_END request */ while (xfer_not_finished == 0) { /* * Give buffer */ for ( i=0; inext = 0; buffer_list->buffer_length = BUFFER_SIZE; buffer_list->bufferptr = (char *) malloc( BUFFER_SIZE ); status = osif_give_buffer( port_id, buffer_list, &error_status ); if (status != 0) print_error_message("osif_give_buffer: ", error_status); } /* * Get the event */ status = osif_get_event(port_id, &indication_pb, -1, &error_status ); if (status != 0) print_error_message("osif_get_event: write: ", error_status); /* * Write the data to the file */ if (indication_pb.osif_block_type == OSIF_PBDEF_DATA_REQ) { n_written = write (fd, indication_pb.osif_userdata.address, indication_pb.osif_userdata.length); if (n_written == -1) printf("Error in writing to file \n"); } if (indication_pb.osif_block_type == OSIF_PBDEF_DATA_END_REQ) xfer_not_finished = 1; free(indication_pb.osif_returned_buffer->bufferptr); } close (fd); } deselect_response ( port_id, indication_pb ) /* **++ ** FUNCTIONAL DESCRIPTION: ** ** This routine sends an f-deselect-reply from a f-deselect response ** and sends it to the initiator ** ** FORMAL PARAMETERS: ** ** port_id ** indication_pb ** ** IMPLICIT INPUTS: ** ** None ** ** IMPLICIT OUTPUTS: ** ** None ** ** COMPLETION CODES: ** ** ** ** SIDE EFFECTS: ** ** The 'osifpb' structure is filled in. ** structure ** **-- */ unsigned port_id; struct osifpb *indication_pb; { unsigned status; unsigned error_status; struct osifpb f_deselect_response; int i; struct osif_ctl *te,*qblk; /* Place holders for this entry */ printf("deselecting file...\n"); /* * Zero fill the parameter block * and initialize the scratchpad memory allocation aread */ bzero(&f_deselect_response, sizeof(f_deselect_response)); osif__init_scratch_pad( &f_deselect_response ); /* * Set the deselect function code in the parameter block */ f_deselect_response.osif_block_type = OSIF_PBDEF_DESELECT_RSP; f_deselect_response.osif_block_size = sizeof(f_deselect_response); /* * Set the action result in the parameter block */ f_deselect_response.osif_action_result.value = 0; f_deselect_response.osif_action_result.length = sizeof( f_deselect_response.osif_action_result.value ); /* * Send the deselect response to the initiator */ status = osif_send( port_id, &f_deselect_response, &error_status ); if (status != OSIF_SUCCESS) print_error_message("osif_send: deselect response: ", error_status); return( status ); } delete_response ( port_id, indication_pb ) /* **++ ** FUNCTIONAL DESCRIPTION: ** ** This routine sends an f-delete-reply from an an f-delete request, ** and sends it to the initiator. ** ** FORMAL PARAMETERS: ** ** port_id ** indication_pb ** ** IMPLICIT INPUTS: ** ** None ** ** IMPLICIT OUTPUTS: ** ** None ** ** COMPLETION CODES: ** ** ** ** SIDE EFFECTS: ** ** The file is deleted. ** **-- */ unsigned port_id; struct osifpb *indication_pb; { unsigned status; unsigned error_status; struct osifpb f_delete_response; int i; struct osif_ctl *te,*qblk; /* Place holders for this entry */ printf("deleting file...\n"); /* * Remove the file specified */ remove(file_name_buffer); /* * Zero fill the parameter block * and initialize the scratchpad memory allocation aread */ bzero(&f_delete_response, sizeof(f_delete_response)); osif__init_scratch_pad( &f_delete_response ); /* * Set the delete response function code in the parameter block */ f_delete_response.osif_block_type = OSIF_PBDEF_DELETE_RSP; f_delete_response.osif_block_size = sizeof(f_delete_response); /* * Set the action result value in the parameter block */ f_delete_response.osif_action_result.value = 0; f_delete_response.osif_action_result.length = sizeof( f_delete_response.osif_action_result.value ); /* * Send the delete response to the initiator */ status = osif_send( port_id, &f_delete_response, &error_status ); if (status != OSIF_SUCCESS) print_error_message("osif_send: delete response: ", error_status); return( status ); } change_attributes_response ( port_id, indication_pb, file_name_dscptr ) /* **++ ** FUNCTIONAL DESCRIPTION: ** ** This routine creates an f-change-attributes response from an ** f-change-attributes-request and sends it to the initiator. ** ** ** FORMAL PARAMETERS: ** ** port_id ** indication_pb ** ** IMPLICIT INPUTS: ** ** None ** ** IMPLICIT OUTPUTS: ** ** None ** ** COMPLETION CODES: ** ** ** ** SIDE EFFECTS: ** ** structure ** **-- */ unsigned port_id; struct osifpb *indication_pb; struct osif_sdesc *file_name_dscptr; { unsigned status; unsigned error_status; struct osifpb f_change_attributes_response; int i; struct osif_ctl *te,*qblk; /* Place holders for this entry */ struct osif_fn change_attributes_filename; printf("changing file attributes (name)...\n"); file_name_dscptr->address[file_name_dscptr->length] = '\0'; /* * Rename file name, and save the filename */ rename(file_name_buffer,(char *) file_name_dscptr->address); /* [001] */ strcpy(file_name_buffer,(char *) file_name_dscptr->address); /* [001] */ /* * Zero fill the parameter block * and initialize the scratchpad memory allocation aread */ bzero(&f_change_attributes_response, sizeof(f_change_attributes_response)); osif__init_scratch_pad( &f_change_attributes_response ); /* * Set the change_atttributes responde function code in the * parameter block */ f_change_attributes_response.osif_block_type = OSIF_PBDEF_CHAT_RSP; f_change_attributes_response.osif_block_size = sizeof(f_change_attributes_response); /* * Set up the filename structure */ change_attributes_filename.next = 0; change_attributes_filename.filename.address = (unsigned char *)file_name_dscptr->address; change_attributes_filename.filename.length = file_name_dscptr->length; /* * Store the address of the filename structure in the parameter block */ f_change_attributes_response.osif_filename = &change_attributes_filename; /* * Action result */ f_change_attributes_response.osif_action_result.value = 0; f_change_attributes_response.osif_action_result.length = sizeof( f_change_attributes_response.osif_action_result.value ); /* * Access control. */ f_change_attributes_response.osif_delete_values = indication_pb->osif_delete_values; f_change_attributes_response.osif_insert_values = indication_pb->osif_insert_values; /* * Send the change attribute response to the initiator */ status = osif_send( port_id, &f_change_attributes_response, &error_status ); if (status != OSIF_SUCCESS) print_error_message("osif_send: change attributes response: ", error_status); return( status ); } begin_group_response( port_id, indication_pb ) /* *++ ** FUNCTIONAL DESCRIPTION: ** ** This routine builds an f-begin-group-response from an ** f-begin-group-request, and sends it to the initiator. ** ** ** FORMAL PARAMETERS: ** port_id - currently assigned port ** indication_pb - initialize request pb pointer ** ** IMPLICIT INPUTS: ** ** None ** ** IMPLICIT OUTPUTS: ** ** None ** ** COMPLETION CODES: ** ** ** ** SIDE EFFECTS: ** ** **-- */ unsigned port_id; struct osifpb *indication_pb; { unsigned status; unsigned error_status; struct osifpb f_begin_group_response; int i; ZERO( f_begin_group_response ); /* * Set the begin group response function code in the parameter block */ f_begin_group_response.osif_block_type = OSIF_PBDEF_BG_RSP; f_begin_group_response.osif_block_size = sizeof(f_begin_group_response); /* * Send the begin group response to the initiator */ status = osif_send( port_id, &f_begin_group_response, &error_status ); if (status != OSIF_SUCCESS) print_error_message("osif_send: begin group response: ", error_status); return( status ); } close_response ( port_id, indication_pb ) /* **++ ** FUNCTIONAL DESCRIPTION: ** ** This routine SEND an f-close-reply from an f-close request ** ** ** FORMAL PARAMETERS: ** ** port_id ** indication_pb ** ** IMPLICIT INPUTS: ** ** None ** ** IMPLICIT OUTPUTS: ** ** None ** ** COMPLETION CODES: ** ** ** ** SIDE EFFECTS: ** ** **-- */ unsigned port_id; struct osifpb *indication_pb; { unsigned status; unsigned error_status; struct osifpb f_close_response; int i; struct osif_ctl *te,*qblk; /* Place holders for this entry */ printf("closing file...\n"); /* * Zero fill the parameter block * and initialize the scratchpad memory allocation aread */ bzero(&f_close_response, sizeof(f_close_response)); osif__init_scratch_pad( &f_close_response ); /* * Set the close response function code in the parameter block */ f_close_response.osif_block_type = OSIF_PBDEF_CLOSE_RSP; f_close_response.osif_block_size = sizeof(f_close_response); /* * Set the action result */ f_close_response.osif_action_result.value = 0; f_close_response.osif_action_result.length = sizeof( f_close_response.osif_action_result.value ); /* * Send the close response to the initiator */ status = osif_send( port_id, &f_close_response, &error_status ); if (status != OSIF_SUCCESS) print_error_message("osif_send: close response: ", error_status); return( status ); } end_group_response( port_id, indication_pb ) /* **++ ** FUNCTIONAL DESCRIPTION: ** ** This routine builds an f-end-group-response from an ** f-end-group-request, and sends it to the initiator. ** ** FORMAL PARAMETERS: ** port_id - currently assigned port ** indication_pb - initialize request pb pointer ** ** IMPLICIT INPUTS: ** ** None ** ** IMPLICIT OUTPUTS: ** ** None ** ** COMPLETION CODES: ** ** ** ** SIDE EFFECTS: ** ** structure ** **-- */ unsigned port_id; struct osifpb *indication_pb; { unsigned status; unsigned error_status; struct osifpb f_end_group_response; int i; ZERO( f_end_group_response ); osif__init_scratch_pad( &f_end_group_response ); /* * Set the end group response function code in the parameter block */ f_end_group_response.osif_block_type = OSIF_PBDEF_EG_RSP; f_end_group_response.osif_block_size = sizeof(f_end_group_response); /* * Send to initiator */ status = osif_send( port_id, &f_end_group_response, &error_status ); if (status != OSIF_SUCCESS) print_error_message("osif_send: end group response: ", error_status); return( status ); } read_attributes_response ( port_id, indication_pb, create_pb ) /* **++ ** FUNCTIONAL DESCRIPTION: ** This routine builds an f-read-attributes response ** ** FORMAL PARAMETERS: ** port_id - currently assigned port ** indication_pb - read attributes indication pb pointer ** create_pb - create indication pb pointer ** ** IMPLICIT INPUTS: ** ** None ** ** IMPLICIT OUTPUTS: ** ** None ** ** COMPLETION CODES: ** ** ** ** SIDE EFFECTS: ** ** **-- */ unsigned port_id; struct osifpb *indication_pb; struct osifpb *create_pb; { unsigned status; unsigned error_status; struct osifpb f_read_attributes_response; struct osif_fn read_attributes_filename; printf("reading file attributes...\n"); /* * Zero fill the parameter block * and initialize the scratchpad memory allocation aread */ bzero(&f_read_attributes_response, sizeof(f_read_attributes_response)); osif__init_scratch_pad( &f_read_attributes_response ); /* * Set the read attributes response in the parameter block */ f_read_attributes_response.osif_block_type = OSIF_PBDEF_RAT_RSP; f_read_attributes_response.osif_block_size = sizeof(f_read_attributes_response); /* * Set the action result */ f_read_attributes_response.osif_action_result.value = 0; f_read_attributes_response.osif_action_result.length = sizeof( f_read_attributes_response.osif_action_result.value ); /* * Set the filename structure */ read_attributes_filename.next = 0; read_attributes_filename.filename.address = (unsigned char *)file_name_buffer; read_attributes_filename.filename.length = strlen((char *) read_attributes_filename.filename.address ); /* [001] */ /* * store the address of the filename structure in the parameter block */ f_read_attributes_response.osif_filename = &read_attributes_filename; /* * Document Type Name */ f_read_attributes_response.osif_contents_type.document_name.address = (unsigned char *)"FTAM-3"; f_read_attributes_response.osif_contents_type.document_name.length = strlen((char *)f_read_attributes_response.osif_contents_type.document_name.address); /* [001] */ /* * Document Type Parameters */ f_read_attributes_response. osif_contents_type.document_param.string_significance.value = OSIF_STRSIG_NS; f_read_attributes_response. osif_contents_type.document_param.string_significance.length = 4; f_read_attributes_response. osif_contents_type.document_param.max_string_length.value = OSIF_MSL_UNLIMITED; f_read_attributes_response. osif_contents_type.document_param.max_string_length.length = 4; f_read_attributes_response. osif_contents_type.document_param.universal_class.value = OSIF_UC_GENERAL; f_read_attributes_response. osif_contents_type.document_param.universal_class.length = 4; /* * Permitted actions */ f_read_attributes_response.osif_permitted_actions.value = 1; f_read_attributes_response.osif_permitted_actions.length = 4; f_read_attributes_response.osif_access_control = create_pb->osif_access_control; /* * Send to initiator */ status = osif_send( port_id, &f_read_attributes_response, &error_status ); if (status != OSIF_SUCCESS) print_error_message("osif send: read attributes response: ", error_status); return( status ); } create_response ( port_id, indication_pb, file_name_dscptr, doc_type_dscptr ) /* **++ ** FUNCTIONAL DESCRIPTION: ** This routine builds an f-select-accept from an ** f-select-request, and sends it to the initiator. ** ** FORMAL PARAMETERS: ** port_id - currently assigned port ** indication_pb - initialize request pb pointer ** ** IMPLICIT INPUTS: ** ** None ** ** IMPLICIT OUTPUTS: ** ** None ** ** COMPLETION CODES: ** ** ** SIDE EFFECTS: ** ** **-- */ unsigned port_id; struct osifpb *indication_pb; struct osif_sdesc *file_name_dscptr; struct osif_sdesc *doc_type_dscptr; { unsigned status; unsigned error_status; struct osifpb f_create_response; int i; struct osif_ctl *te,*qblk; /* Place holders for this entry */ struct osif_fn create_filename; int fd; int mode = 0x1ff; /* [001] */ printf("creating file...\n"); file_name_dscptr->address[file_name_dscptr->length] = '\0'; doc_type_dscptr->address[doc_type_dscptr->length] = '\0'; /* * Save the filename and mode for further use */ strncpy(file_name_buffer,(char *) file_name_dscptr->address, file_name_dscptr->length); /* [001] */ file_name_buffer[file_name_dscptr->length] = '\0'; fn_mode = mode; /* * Set mode and create the file */ /* mode = 0x1ff; */ /* [001] */ fd = creat(file_name_buffer, mode); close (fd); /* * Zero fill the parameter block * and initialize the scratchpad memory allocation aread */ bzero(&f_create_response, sizeof(f_create_response)); osif__init_scratch_pad( &f_create_response ); /* * Block type and size */ f_create_response.osif_block_type = OSIF_PBDEF_CRE_RSP; f_create_response.osif_block_size = sizeof(f_create_response); /* * Action result value */ f_create_response.osif_action_result.value = 0; f_create_response.osif_action_result.length = sizeof( f_create_response.osif_action_result.value ); /* * Filename */ create_filename.next = 0; create_filename.filename.address = (unsigned char *)file_name_dscptr->address; create_filename.filename.length = file_name_dscptr->length; f_create_response.osif_filename = &create_filename; /* * Permitted actions */ f_create_response.osif_permitted_actions.value = (OSIF_PA_READ | OSIF_PA_INSERT | OSIF_PA_REPLACE | OSIF_PA_EXTEND | OSIF_PA_ERASE | OSIF_PA_READ_ATTRIBUTE | OSIF_PA_CHANGE_ATTRIBUTE | OSIF_PA_DELETE_FILE | OSIF_PA_TRAVERSAL | OSIF_PA_REVERSE_TRAVERSAL | OSIF_PA_RANDOM_ORDER); f_create_response.osif_permitted_actions.length = sizeof(int); /* * Document type */ f_create_response.osif_contents_type.document_name.address = (unsigned char *)doc_type_dscptr->address; f_create_response.osif_contents_type.document_name.length = doc_type_dscptr->length; /* * Save document type in case it's needed by another response pdu. */ strncpy(dt, (char *)doc_type_dscptr->address, doc_type_dscptr->length); /* [001] */ dt[doc_type_dscptr->length] = '\0'; /* * Access control. */ f_create_response.osif_access_control = indication_pb->osif_access_control; /* * Send to initiator */ status = osif_send( port_id, &f_create_response, &error_status ); if (status != OSIF_SUCCESS) print_error_message("osif_send: create response: ", error_status); return( status ); } terminate_response( port_id, indication_pb ) /* **++ ** FUNCTIONAL DESCRIPTION: ** ** ** This routine builds an f-terminate-response from an ** f-terminate-request, and sends it to the initiator. ** ** FORMAL PARAMETERS: ** port_id - currently assigned port ** indication_pb - initialize request pb pointer ** ** IMPLICIT INPUTS: ** ** None ** ** IMPLICIT OUTPUTS: ** ** None ** ** COMPLETION CODES: ** ** ** ** SIDE EFFECTS: ** **-- */ unsigned port_id; struct osifpb *indication_pb; { unsigned status; unsigned error_status; struct osifpb f_terminate_response; int i; printf("terminating connection...\n"); ZERO( f_terminate_response ); /* * Set the terminate response in the parameter block */ f_terminate_response.osif_block_type = OSIF_PBDEF_TERM_RSP; f_terminate_response.osif_block_size = sizeof(f_terminate_response); /* * Send the terminate response to the initiator */ status = osif_send( port_id, &f_terminate_response, &error_status ); if (status != OSIF_SUCCESS) print_error_message("osif_send: terminate response: ", error_status); return( status ); } transfer_end_response ( port_id ) /* **++ ** FUNCTIONAL DESCRIPTION: ** This routine builds an f-transfer-end-response from an ** f-transfer-end-request, and sends it to the initiator. ** ** FORMAL PARAMETERS: ** port_id - currently assigned port ** indication_pb - initialize request pb pointer ** ** ** IMPLICIT INPUTS: ** ** None ** ** IMPLICIT OUTPUTS: ** ** None ** ** COMPLETION CODES: ** ** ** ** SIDE EFFECTS: ** **-- */ unsigned port_id; { unsigned status; unsigned error_status; struct osifpb f_transfer_end_response; ZERO( f_transfer_end_response ); /* * Set the transfer end response function code in the parameter block */ f_transfer_end_response.osif_block_type = OSIF_PBDEF_TRANSFER_END_RSP; f_transfer_end_response.osif_block_size = sizeof( f_transfer_end_response ); /* * Set the action result value */ f_transfer_end_response.osif_action_result.value = 0; f_transfer_end_response.osif_action_result.length = sizeof( f_transfer_end_response.osif_action_result.value ); /* * Send the transfer end response to the initiator */ status = osif_send ( port_id, &f_transfer_end_response, &error_status ); if (status != OSIF_SUCCESS) print_error_message("osif_send: transfer end resposne: ", error_status); return( status ); } /* ** This structure is simply a list of parameter block type ** values, and their text names. */ static struct { int item_value; char *item_name; } error_names[] = { 0, "No Reason ", 1, "Responder error ", 2, "System shutdown ", 3, "FTAM management problem (unspecific) ", 4, "FTAM management, bad account ", 5, "FTAM management, security not passed ", 6, "Delay may be encountered ", 7, "Initiator Error, unspecific ", 8, "Subsequent Error ", 9, "Temporal insufficiency of resources", 10, "Access request violates VFS security", 11, "Access request violates local security", /* Protocol and supporting service related diagnostic definitions */ 1000, "Conflicting parameter values ", 1001, "Unsuported parameter values ", 1002, "Mandatory parameter not set ", 1003, "Unsupported parameter ", 1004, "Duplicated parameter ", 1005, "Illegal parameter type ", 1006, "Unsupported parameter types ", 1007, "FTAM protocol error (unspecific) ", 1008, "FTAM protocol error, procedure error ", 1009, "FTAM protocol error, functional unit error ", 1010, "FTAM protocol error, corruption error ", 1011, "Lower layer failure ", 1012, "Lower layer addressing error ", 1013, "Timeout", 1014, "System shutdown ", 1015, "Illegal grouping sequence ", 1016, "Grouping threshold violation ", 1017, "Specific PDU request inconsistent with current requested access", /* Association related diagnostics */ 2000, "Association with user not allowed ", 2001, "(not assigned) ", 2002, "Unsupported service class ", 2003, "Unsupported functional unit ", 2004, "Attribute group error (unspecific) ", 2005, "Attribute group not supported ", 2006, "Attribute group not allowed ", 2007, "Bad account ", 2008, "Association management (unspecifc) ", 2009, "Association management - bad address ", 2010, "Association management - bad acount ", 2011, "Checkpoint window error - too large ", 2012, "Checkpoint window error - too small ", 2013, "Checkpoint window unsupported ", 2014, "Communications QoS not supported ", 2015, "Initiator Identity unacceptable ", 2016, "Context management refused ", 2017, "Rollback not available ", 2018, "Contents-type list cut by responder ", 2019, "Contests-type list cut by presentation ", 2020, "Invalid filestore password ", 2021, "Incompatible service classes ", /* Selection related diagnostic definitions */ 3000, "File not found ", 3001, "Selection attributes not matched ", 3002, "Initial attributes not possible ", 3003, "Bad atrribute name ", 3004, "Nonexistent file ", 3005, "File already exists ", 3006, "File cannot be created ", 3007, "File cannot be deleted ", 3008, "Concurrency control not available ", 3009, "Concurrency control not supported ", 3010, "Concurrency control not possible ", 3011, "More restrictive lock ", 3012, "File busy ", 3013, "File not available ", 3014, "Access control not available ", 3015, "Access control not supported ", 3016, "Access control inconsistent ", 3017, "File name truncated ", 3018, "Initial attributes altered ", 3019, "Bad account ", 3020, "Override selected existing file ", 3021, "Override recreated file with old attributes ", 3022, "Override recreated file with new attributes", 3023, "Override not possible ", 3024, "Ambiguous file specification ", 3025, "Invalid create password ", 3026, "Invalid delete password ", 3027, "Bad attribute value ", 3028, "Requested access violates permitted actions", 3029, "Function unit not available for requested access ", 3030, "File was created, not selected ", /* File management realted diagnostic definitions */ 4000, "Attribute non-existent ", 4001, "Attribute cannot be read ", 4002, "Attribute cannot be changed ", 4003, "Attribute not supported ", 4004, "Bad attribute name ", 4005, "Bad attribute value ", 4006, "Attribute partialy supported ", 4007, "Additional set attribute value not distinct ", /* Access related diagnostic definitions */ 5000, "Bad FADU (unspecific) ", 5001, "Bad FADU - size error ", 5002, "Bad FADU - type error ", 5003, "Bad FADU - poorly specified ", 5004, "Bad FADU - bad location ", 5005, "FADU does not exist ", 5006, "FADU not available ", 5007, "FADU not available for reading ", 5008, "FADU not available for writing ", 5009, "FADU not available for location ", 5010, "FADU not available for erasure ", 5011, "FADU cannot be inserted ", 5012, "FADU cannot be replaced ", 5013, "FADU cannot be located ", 5014, "Bad data element type ", 5015, "Operation not available ", 5016, "Operation not supported ", 5017, "Operation inconsistent ", 5018, "Concurrency control not available ", 5019, "Concurrency control not supaported ", 5020, "Concurrency control inconsistent ", 5021, "Processing mode not available ", 5022, "Processing mode not supported ", 5023, "Processing mode inconsistent ", 5024, "Access context not available ", 5025, "Access context not supported ", 5026, "Bad write (unspecific) ", 5027, "Bad read (unspecific) ", 5028, "Local error (unspecific) ", 5029, "Local error - filespace exhausted ", 5030, "Local error - data corrupted ", 5031, "Local error - device failure ", 5032, "Future filesize exceeded ", 5033, " ", 5034, "Future filesize increased ", 5035, "Functional unit invalid in processing mode ", 5036, "Contents-type incosistent ", 5037, "Contents-type simplified ", 5038, "Duplicate FADU name ", 5039, "Damage to select/open regime ", 5040, "FADU locking not available on file ", 5041, "FADU locked by another user ", /* Recovery related diagnostics */ 6000, "Bad checkpoint (unspecific) ", 6001, "Activity not unique ", 6002, "Checkpoint outside of window ", 6003, "Activity no longer exists ", 6004, "Activity not recognized ", 6005, "No docket ", 6006, "Corrupt docket ", 6007, "File waiting restart ", 6008, "Bad recovery point ", 6009, "Non-existent recovery point ", 6010, "Recovery mode not available ", 6011, "Recovery mode inconsistent ", 6012, "Recovery mode reduced ", 6013, "Access control not available ", 6014, "Access control not supported ", 6015, "Access control inconsistent ", 6016, "Contents type inconsistent ", 6017, "Contents type simplified ", 9000, "OSIF_BAD_ACCCNTX ", 9001, "OSIF_BAD_ACCCNTRL ", 9002, "OSIF_BAD_ACCPWD ", 9003, "OSIF_BAD_ACCOUNT ", 9004, "OSIF_BAD_ACTRES ", 9005, "OSIF_BAD_ACTID ", 9006, "OSIF_BAD_APPCNTX ", 9007, "OSIF_BAD_ARCLEN ", 9008, "OSIF_BAD_ATTRGRP ", 9009, "OSIF_BAD_ATTNAME ", 9010, "OSIF_BAD_CHARGE ", 9011, "OSIF_BAD_CHKPWIN ", 9012, "OSIF_BAD_CCCNTRL ", 9013, "OSIF_BAD_CNTTYPE ", 9014, "OSIF_BAD_CNTTYLST ", 9015, "OSIF_BAD_CREPWD ", 9016, "OSIF_BAD_DTCRE ", /* Date time creation */ 9017, "OSIF_BAD_DTLATMD ", /* Date time last att mod */ 9018, "OSIF_BAD_DTLMOD ", /* Date time last mod */ 9019, "OSIF_BAD_DTLSTRD ", 9020, "OSIF_BAD_DELPWD ", 9021, "OSIF_BAD_DELVAL ", 9022, "OSIF_BAD_DELCNTX ", 9023, "OSIF_BAD_DIAG ", 9025, "OSIF_BAD_FADU ", 9026, "OSIF_BAD_FADULK ", 9027, "OSIF_BAD_FADULKG ", 9028, "OSIF_BAD_FADUOP ", 9029, "OSIF_BAD_FILENM ", 9030, "OSIF_BAD_FILESZ ", 9031, "OSIF_BAD_FILEAV ", 9032, "OSIF_BAD_FSPWD ", 9033, "OSIF_BAD_FQOS ", 9034, "OSIF_BAD_FUNITS ", /* Functional Units */ 9035, "OSIF_BAD_FUTFISZ ", 9036, "OSIF_BAD_INITID ", 9037, "OSIF_BAD_IDCRE ", 9038, "OSIF_BAD_IDLATMD ", 9039, "OSIF_BAD_IDLMOD ", 9040, "OSIF_BAD_IDLREAD ", 9041, "OSIF_BAD_IMPINFO ", /* Implementatin Information */ 9042, "OSIF_BAD_INVAL ", 9043, "OSIF_BAD_LAEQUAL ", 9044, "OSIF_BAD_LAPTITLE ", 9045, "OSIF_BAD_LPADDR ", /* Local Presenation Address */ 9046, "OSIF_BAD_LEQUAL ", /* legal qualifications */ 9047, "OSIF_BAD_OVRRIDE ", 9048, "OSIF_BAD_RAEQUAL ", 9049, "OSIF_BAD_RAPTITLE ", 9050, "OSIF_BAD_RPADDR ", /* Remote Presentation Address */ 9051, "OSIF_BAD_PERACT ", 9052, "OSIF_BAD_PCTXMGT ", 9053, "OSIF_BAD_PROMODE ", 9055, "OSIF_BAD_PROTID ", 9056, "OSIF_BAD_REMCNTX ", 9057, "OSIF_BAD_REQACC ", 9058, "OSIF_BAD_RECMODE ", 9059, "OSIF_BAD_SRVCLASS ", 9060, "OSIF_BAD_STRES ", /* State Result */ 9061, "OSIF_BAD_STOACC ", /* Storage Account */ 9062, "OSIF_BAD_THRES ", 9063, "OSIF_BAD_USRDATA ", 9065, "OSIF_BAD_CHATPWD ", 9067, "OSIF_BAD_ERAPWD ", 9068, "OSIF_BAD_EXTPWD ", 9069, "OSIF_BAD_INSPWD ", 9070, "OSIF_BAD_RDATPWD ", 9071, "OSIF_BAD_RDPWD ", 9072, "OSIF_BAD_RPLPWD ", 10000, "OSIF_BADITEMSIZE ", 10002, "OSIF_PROTOCOL_ERROR", 10003, "OSIF_INVPORT", 10004, "OSIF_NOPORT", 10005, "OSIF_PARAMNOWRT ", 10006, "OSIF_PARAMNORD ", 10007, "OSIF_NOBUFFS ", 10008, "OSIF_NOMEM ", 10009, "OSIF_XPORTFAILURE", 10010, "OSIF_NO_EVENT", -1,"Error not specified" }; print_error_message( txt, event ) /* **++ ** FUNCTIONAL DESCRIPTION: ** This routine prints out an error message corresponding to the ** error status ** ** FORMAL PARAMETERS: ** txt ** event ** ** ** IMPLICIT INPUTS: ** ** None ** ** IMPLICIT OUTPUTS: ** ** None ** ** COMPLETION CODES: ** ** ** ** SIDE EFFECTS: ** **-- */ char *txt; /* Input text pointer */ int event; /* Input parameter block type */ { int i; /* Temp for loop control */ for (i=0; (error_names[i].item_value >= 0 ) && (error_names[i].item_value != event); i++) ; printf( "ERROR: %s: %s\n", txt, error_names[i].item_name ); }