/* static rfc_char_t sccsid[] = "@(#) $Id: //bas/710_REL/src/krn/rfc/trfcserv.c#2 $ SAP"; */ /*====================================================================*/ /* */ /* PROGRAM : trfcserv.c (running on Windows_NT, Windows_95, */ /* OS/2 and R/3-platforms) */ /* */ /* */ /* DESCRIPTION : Sample Server-Program for transactional RFC */ /* Following function is available: */ /* */ /* - STFC_WRITE_TO_TCPIC */ /* */ /* and can only be called from R/3 >= 3.0 */ /* */ /* */ /* trfcserv.tid: TID-Management */ /* trfcserv.lck: Lock file for access TID-Mgm. */ /* trnn...n.dat: Received data from R/3-ABAP */ /* trnn...n.trc: Trace file for RFC-Protocol */ /* (nn...n: Process ID) */ /* */ /* These files will be created/appended in the */ /* directory defined via TRFC_WORK_DIR. If this */ /* Environment Variable is not defined these files*/ /* will be in the working directory of the user */ /* who started this program (mostly user from */ /* SAP Gateway). */ /* */ /* Trace files will only be written if the */ /* Environment Variable TRFC_TRACE is defined and */ /* not equal 0. */ /* */ /* On UNIX this program can be started via a */ /* sript with setting the required Environment */ /* Variable as follow: */ /* */ /* transrfc: */ /* #!/bin/csh */ /* setenv TRFC_WORK_DIR /usr/sap/rfctest */ /* setenv TRFC_TRACE 1 */ /* /usr/sap/rfctest/trfcserv $* */ /* */ /* Please do the same for other platforms. */ /* */ /* The entry in sm59 must contain the name of */ /* this script (transrfc) as name of program. */ /* */ /* Because of working with file system it is */ /* recommended to choose the working directory as */ /* a local directory and NOT mounted via NFS. */ /* */ /* */ /* SAP AG Walldorf */ /* Systeme, Anwendungen und Produkte in der Datenverarbeitung */ /* */ /* Copyright (C) SAP AG 1995 */ /* */ /*====================================================================*/ #if defined(SAPonOS400) #include "saptype.h" #endif #define _POSIX_SOURCE /* open(), O_*, fcntl(), close(), ... */ /*--------------------------------------------------------------------*/ /* Set up includes */ /*--------------------------------------------------------------------*/ /*CCQ_SECURE_LIB_FILE_OFF*/ #include "trfcserv.h" /*====================================================================*/ /* Function: main */ /* */ /* Accept RFC-Connection */ /* Install all offering functions */ /* Loop in waiting for Remote Function Call */ /* do function */ /* until client disconnects the RFC-Connection */ /* */ /*====================================================================*/ mainU (int argc, rfc_char_t **argv) { setbuf(stderr, NULL); if (argc == 1) { help(); return 0; } /*------------------------------------------------------------------*/ /* Output argument list */ /*------------------------------------------------------------------*/ fprintfU (stderr, cU("\nargc = %d"), argc); for (i=0; i Please update this function for your OS" #endif } } if (rfc_rc != RFC_OK) { if (rfc_rc != RFC_CLOSED) rfc_error(cU("RfcListen")); else break; } #endif rfc_rc = RfcDispatch(rfc_handle); sprintfU (tbuf, cU("\n<== RfcDispatch rfc_rc = %d"), rfc_rc); TRFC_trace(tbuf); } while (rfc_rc == RFC_OK); if (trace_fp != NULL) fclose(trace_fp); return 0; } /*====================================================================*/ /* */ /* Install the offered functions for RFC */ /* */ /*====================================================================*/ static RFC_RC install(void) { sprintfU (tbuf, cU("\n<== RfcInstallTransactionControl")); TRFC_trace(tbuf); RfcInstallTransactionControl ((RFC_ON_CHECK_TID) TID_check, (RFC_ON_COMMIT) TID_commit, (RFC_ON_ROLLBACK) TID_rollback, (RFC_ON_CONFIRM_TID) TID_confirm); #ifdef SAP_RFC_GETNAME /* Install USER_GLOBAL_SERVER for working with RfcGetName */ sprintfU (tbuf, cU("\n<== RfcInstallFunction '%s' rfc_rc = "), name_user_global_server); TRFC_trace(tbuf); rfc_rc = RfcInstallFunction(name_user_global_server, (RFC_ONCALL) user_global_server, user_global_server_docu()); sprintfU (tbuf, cU("%d"), rfc_rc); TRFC_trace(tbuf); if( rfc_rc != RFC_OK ) { sprintfU (abort_text, cU("\nERROR: Install %s rfc_rc = %d"), name_user_global_server, rfc_rc); function_abort(abort_text); } /* Necessary for access docu_function by sm59 (system information) */ sprintfU (tbuf, cU("\n<== RfcInstallFunction '%s' rfc_rc = "), name_transactional_test); TRFC_trace(tbuf); rfc_rc = RfcInstallFunction(name_transactional_test, (RFC_ONCALL) NULL, transactional_test_docu()); #else sprintfU (tbuf, cU("\n<== RfcInstallFunction 'STFC_WRITE_TO_TCPIC' rfc_rc = ")); TRFC_trace(tbuf); rfc_rc = RfcInstallFunction (name_transactional_test, (RFC_ONCALL) transactional_test, transactional_test_docu()); #endif sprintfU (tbuf, cU("%d"), rfc_rc); TRFC_trace(tbuf); if( rfc_rc != RFC_OK ) { sprintfU (abort_text, cU("\nERROR: Install %s rfc_rc = %d"), name_transactional_test, rfc_rc); function_abort (abort_text); } return RFC_OK; } #ifdef SAP_RFC_GETNAME /*====================================================================*/ /* */ /* RFC-FUNCTION: %%USER_GLOBAL_SERVER */ /* */ /* Global server function for working with RfcGetName */ /* */ /*====================================================================*/ static RFC_RC DLL_CALL_BACK_FUNCTION user_global_server(RFC_HANDLE rfc_handle) { sprintfU (tbuf, cU("\n\nStart Function %s"), name_user_global_server); TRFC_trace(tbuf); sprintfU (tbuf, cU("\n<== RfcGetName rfc_rc = ")); TRFC_trace(tbuf); rfc_rc = RfcGetName(rfc_handle, function_name); sprintfU (tbuf, cU("%d"), rfc_rc); TRFC_trace(tbuf); if (rfc_rc == RFC_OK) { sprintfU (tbuf, cU(" Function Name: '%s'"), function_name); if (strcmpU (function_name, name_transactional_test) == 0) rfc_rc = transactional_test(rfc_handle); else { sprintfU (abort_text, cU("'%s' ist not implemented in program trfcserv.c"), function_name); function_abort(abort_text); } } else rfc_error(cU("RfcGetName")); return rfc_rc; } #endif /*====================================================================*/ /* */ /* RFC-FUNCTION: STFC_WRITE_TO_TCPIC */ /* */ /* Received data from internal table will be write in a file */ /* */ /*====================================================================*/ static RFC_RC DLL_CALL_BACK_FUNCTION transactional_test(RFC_HANDLE rfc_handle) { sprintfU (tbuf, cU("\n\nStart Function %s"), name_transactional_test); TRFC_trace(tbuf); memsetR (¶meters[0], 0, sizeofR(parameters)); /* Prepare internal table TCPICDAT */ tables[0].name = cU("TCPICDAT"); tables[0].nlen = 8; tables[0].type = TYPC; tables[0].leng = TCPICDAT_ENTRY_SIZE*sizeofR(SAP_UC); tables[0].itmode = RFC_ITMODE_BYREFERENCE; /* terminate array */ tables[1].name = NULL; /* receive data */ sprintfU (tbuf, cU("\n<== RfcGetData rfc_rc = ")); TRFC_trace(tbuf); rfc_rc = RfcGetData (rfc_handle, parameters, tables); sprintfU (tbuf, cU("%d"), rfc_rc); TRFC_trace(tbuf); if (rfc_rc != RFC_OK) rfc_error(cU("RfcGetData")); sprintfU (tbuf, cU("\n<== RfcGetAttributes rc = ")); TRFC_trace(tbuf); rc = RfcGetAttributes(rfc_handle, &rfc_attributes); sprintfU (tbuf, cU("%d"), rc); TRFC_trace(tbuf); if (rc) rfc_error(cU("RfcGetAttributes")); sprintfU (tbuf, cU("\n\nAttributes of this RFC connection")); sprintfU (tbuf+strlenU (tbuf), cU("\n---------------------------------")); sprintfU (tbuf+strlenU (tbuf), cU("\nDestination : %s"), rfc_attributes.dest); sprintfU (tbuf+strlenU (tbuf), cU("\nMy Host : %s"), rfc_attributes.own_host); if (rfc_attributes.rfc_role == RFC_ROLE_CLIENT) { if (rfc_attributes.partner_type == RFC_SERVER_EXT) sprintfU (tbuf+strlenU (tbuf), cU("\nServer Program Name : %s"), rfc_attributes.partner_host); else if (rfc_attributes.partner_type == RFC_SERVER_EXT_REG) sprintfU (tbuf+strlenU (tbuf), cU("\nServer Program ID : %s"), rfc_attributes.partner_host); else sprintfU (tbuf+strlenU (tbuf), cU("\nPartner Host : %s"), rfc_attributes.partner_host); } else { sprintfU (tbuf+strlenU (tbuf), cU("\nPartner Host : %s"), rfc_attributes.partner_host); } sprintfU (tbuf+strlenU (tbuf), cU("\nSystem No. : %s"), rfc_attributes.systnr); sprintfU (tbuf+strlenU (tbuf), cU("\nSystem Name : %s"), rfc_attributes.sysid); sprintfU (tbuf+strlenU (tbuf), cU("\nClient : %s"), rfc_attributes.client); sprintfU (tbuf+strlenU (tbuf), cU("\nUser : %s"), rfc_attributes.user); sprintfU (tbuf+strlenU (tbuf), cU("\nLanguage : %s"), rfc_attributes.language); sprintfU (tbuf+strlenU (tbuf), cU("\nISO-Language : %s"), rfc_attributes.ISO_language); if (rfc_attributes.trace == cU('X')) sprintfU (tbuf+strlenU (tbuf), cU("\nRFC Trace : ON")); else sprintfU (tbuf+strlenU (tbuf), cU("\nRFC Trace : OFF")); sprintfU (tbuf+strlenU (tbuf), cU("\nMy Codepage : %s"), rfc_attributes.own_codepage); sprintfU (tbuf+strlenU (tbuf), cU("\nPartner Codepage : %s"), rfc_attributes.partner_codepage); sprintfU (tbuf+strlenU (tbuf), cU("\nReal Partner Codepage : %s"), rfc_attributes.real_partner_codepage); if (rfc_attributes.rfc_role == RFC_ROLE_CLIENT) sprintfU (tbuf+strlenU (tbuf), cU("\nRFC Role : External RFC Client")); else if (rfc_attributes.own_type == RFC_SERVER_EXT) sprintfU (tbuf+strlenU (tbuf), cU("\nRFC Role : External RFC Server, started by SAP gateway")); else sprintfU (tbuf+strlenU (tbuf), cU("\nRFC Role : External RFC Server, registered at SAP gateway")); sprintfU (tbuf+strlenU (tbuf), cU("\nRFC Library Release : %s"), rfc_attributes.own_rel); if (rfc_attributes.partner_type == RFC_SERVER_R3) sprintfU (tbuf+strlenU (tbuf), cU("\nRFC Partner : SAP R/3")); else if (rfc_attributes.partner_type == RFC_SERVER_R2) sprintfU (tbuf+strlenU (tbuf), cU("\nRFC Partner : SAP R/2")); else if (rfc_attributes.rfc_role == RFC_ROLE_CLIENT) { if (rfc_attributes.partner_type == RFC_SERVER_EXT) sprintfU (tbuf+strlenU (tbuf), cU("\nRFC Partner : External RFC Server, started by SAP gateway")); else sprintfU (tbuf+strlenU (tbuf), cU("\nRFC Partner : External RFC Server, registered at SAP gateway")); } else { sprintfU (tbuf+strlenU (tbuf), cU("\nRFC Partner : External RFC Client")); } sprintfU (tbuf+strlenU (tbuf), cU("\nPartner System Release : %s"), rfc_attributes.partner_rel); sprintfU (tbuf+strlenU (tbuf), cU("\nR/3 Kernel Release : %s"), rfc_attributes.kernel_rel); sprintfU (tbuf+strlenU (tbuf), cU("\nCPI-C Conversation ID : %s\n"), rfc_attributes.CPIC_convid); sprintfU (tbuf+strlenU (tbuf), cU("\nProgram Name : %s\n"), rfc_attributes.progname); TRFC_trace(tbuf); /* get call info for this trfc connection */ rfc_call_info.call_type = cU('T'); rfc_rc = RfcGetCallInfo (rfc_handle, &rfc_call_info); if (rfc_rc != RFC_OK) rfc_error (cU("RfcGetCallInfo")); fprintfU (stderr, cU("\nCall Info: function name: %s\n"), rfc_call_info.function_name); fprintfU (stderr, cU(" call type : %c\n"), rfc_call_info.call_type); fprintfU (stderr, cU(" function counter: %s\n"), rfc_call_info.function_counter); fprintfU (stderr, cU(" tid: %s\n"), rfc_call_info.tid); { /* Demonstrate a call to RfcGetAttachedContext on a play back handle */ int fFromCarrier; void *pContext; SAP_CHAR *pCtx; sprintfU (tbuf, cU("\n<== RfcGetAttachedContext rfc_rc = ")); TRFC_trace(tbuf); rfc_rc = RfcGetAttachedContext(rfc_handle, &pContext, &fFromCarrier); sprintfU (tbuf, cU("%d\n"), rfc_rc); TRFC_trace(tbuf); if (rfc_rc == RFC_OK) { pCtx = (SAP_CHAR*)pContext; sprintfU (tbuf, cU("User context %s\n"), pCtx); TRFC_trace(tbuf); sprintfU (tbuf, cU("From Carrier %d\n\n"), fFromCarrier); TRFC_trace(tbuf); } } /* Put the name of data file in trace file */ sprintfU (tbuf, cU("\nDATA FILE: '%s'"), data_file); TRFC_trace(tbuf); rc = write_itab_to_file(tables[0].ithandle, data_file, (rfc_char_t*)tables[0].name); if (rc) { sprintfU (abort_text, cU("Can not write user data in file system")); function_abort(abort_text); } /*------------------------------------------------------------------*/ /* Return parameters and tables */ /*------------------------------------------------------------------*/ memsetR (¶meters[0], 0, sizeofR(parameters)); /* return to the caller */ sprintfU (tbuf, cU("\n<== RfcSendData rfc_rc = ")); TRFC_trace(tbuf); rfc_rc = RfcSendData (rfc_handle, parameters, tables); sprintfU (tbuf, cU("%d"), rfc_rc); TRFC_trace(tbuf); if (rfc_rc != RFC_OK) rfc_error (cU("RfcSendData")); return rfc_rc; } /*--------------------------------------------------------------------*/ /* TID_CHECK-Function for transactional RFC */ /*--------------------------------------------------------------------*/ static int DLL_CALL_BACK_FUNCTION TID_check(RFC_TID tid) { sprintfU (tbuf, cU("\n\nStart Function TID_CHECK TID = %s"), tid); TRFC_trace(tbuf); strcpyU (TransID, tid); /* Check TID from TID Management */ tid_rc = check_TID(tid, data_file); if (tid_rc == TID_OK) { create_file_name(data_file); strcpyU (data_file+strlenU (data_file), cU(".dat")); return 0; } if (tid_rc == TID_FOUND) return 1; if (tid_rc == TID_ERROR_LOCK) function_abort(tid_etext01); else function_abort(tid_etext02); return 1; } /*--------------------------------------------------------------------*/ /* TID_COMMIT-Function for transactional RFC */ /*--------------------------------------------------------------------*/ static void DLL_CALL_BACK_FUNCTION TID_commit(RFC_TID tid) { sprintfU (tbuf, cU("\n\nStart Function TID_COMMIT TID = %s"), tid); TRFC_trace(tbuf); strcpyU (TransID, tid); /* Commit TID from TID Management */ tid_rc = update_TID(tid, EXECUTED, data_file); if (tid_rc == TID_OK) return; if (tid_rc == TID_ERROR_LOCK) function_abort(tid_etext03); else function_abort(tid_etext04); return; } /*--------------------------------------------------------------------*/ /* CONFIRM-Function for transactional RFC */ /*--------------------------------------------------------------------*/ static void DLL_CALL_BACK_FUNCTION TID_confirm(RFC_TID tid) { sprintfU (tbuf, cU("\n\nStart Function TID_CONFIRM TID = %s"), tid); TRFC_trace(tbuf); strcpyU (TransID, tid); /* Confirm TID from TID Management */ tid_rc = update_TID(tid, CONFIRMED, data_file); if (tid_rc == TID_OK) return; if (tid_rc == TID_ERROR_LOCK) function_abort(tid_etext05); else function_abort(tid_etext06); return; } /*--------------------------------------------------------------------*/ /* TID_ROLLBACK-Function for transactional RFC */ /*--------------------------------------------------------------------*/ static void DLL_CALL_BACK_FUNCTION TID_rollback(RFC_TID tid) { sprintfU (tbuf, cU("\n\nStart Function TID_ROLLBACK TID = %s"), tid); TRFC_trace(tbuf); strcpyU (TransID, tid); /* Rollback TID from TID Management */ tid_rc = update_TID(tid, ROLLBACK, data_file); if (tid_rc == TID_OK) return; if (tid_rc == TID_ERROR_LOCK) function_abort(tid_etext07); else function_abort(tid_etext08); return; } /*--------------------------------------------------------------------*/ /* Initialize the TID-Management */ /*--------------------------------------------------------------------*/ static void init_TID(void) { FILE *fp; /* Read TID-file for check and update */ fp = fopenU (tid_file, cU("rb+")); if (fp == NULL) { /* TID-Management not existent */ fp = fopenU (tid_file, cU("ab")); if (fp == NULL) { /* ERROR: Create file for TID-Management failed */ unlock_TID(lock_file); strcpyU (tbuf, tid_etext00); TRFC_trace(tbuf); exit(1); } memsetU (tbuf, cU('\0'), LINE_SIZE_CHAR); strcpyU (tbuf, cU("*** TID-MANAGEMENT FOR TRANSACTIONAL RFC (Server Program) ***\n")); if (fputsU (tbuf, fp) < 0) { /* ERROR: Write in TID-Management failed */ unlock_TID(lock_file); fclose(fp); strcpyU (tbuf, tid_etext02); TRFC_trace(tbuf); exit(1); } } else { while ((ptr = fgetsU (tbuf, LINE_SIZE_CHAR+1, fp)) != NULL) { if (memcmpU (tbuf+52, cU("CREATED"), 7) == 0) { /* Auf ROLLBACK setzen */ memcpyU (TransID, tbuf+26, 24); TransID[24] = 0; tid_rc = update_TID(TransID, ROLLBACK, data_file); if (tid_rc == TID_OK) continue; if (tid_rc == TID_ERROR_LOCK) strcpyU (tbuf, tid_etext01); else strcpyU (tbuf, tid_etext02); TRFC_trace(tbuf); exit(1); } } } return; } /*--------------------------------------------------------------------*/ /* Check and Update TID in the TID-Management */ /*--------------------------------------------------------------------*/ static TID_RC check_TID(RFC_TID tid, rfc_char_t *datafile) { TID_RC tidrc; FILE *fp; /* Try to lock TID-Management */ if (lock_TID(lock_file, tid)) return TID_ERROR_UPDATE; /* Read TID-file for check and update */ fp = fopenU (tid_file, cU("rb+")); if (fp == NULL) tidrc = TID_ERROR_UPDATE; while ((ptr = fgetsU (tbuf, LINE_SIZE_CHAR, fp)) != NULL) { if ((memcmpU (tbuf+26, tid, 24) == 0) && (memcmpU (tbuf+52, cU("ROLLBACK"), 8) != 0)) break; } if (ptr != NULL) { /* Previous TID found: Inform the RFC-Library about EXECUTED RFC-functions */ unlock_TID(lock_file); fclose(fp); return TID_FOUND; } /* Write new TID at the end of the tid_file */ tid_state = CREATED; if (write_TID(fp, tid, tid_state, datafile)) tidrc = TID_ERROR_UPDATE; else tidrc = TID_OK; /* Unlock TID-Management */ unlock_TID(lock_file); fclose(fp); return tidrc; } /*--------------------------------------------------------------------*/ /* Update TID in the TID-Management */ /*--------------------------------------------------------------------*/ static TID_RC update_TID(RFC_TID tid, TID_STATE tid_state, rfc_char_t *datafile) { TID_RC tidrc; long offset = 0; FILE *fp; /* Try to lock TID-Management */ if (lock_TID(lock_file, tid)) return TID_ERROR_UPDATE; /* Open TID-file for update */ fp = fopenU (tid_file, cU("rb+")); if (fp == NULL) { /* ERROR: Open TID-Management failed */ unlock_TID(lock_file); return TID_ERROR_UPDATE; } while ((ptr = fgetsU (tbuf, LINE_SIZE_CHAR+1, fp)) != NULL) { if ((memcmpU (tbuf+26, tid, 24) == 0) && (memcmpU (tbuf+52, cU("ROLLBACK"), 8) != 0)) break; offset = offset + strlenU (tbuf); } if ((ptr != NULL) && (fseek(fp, offset, SEEK_SET) == 0) && (write_TID(fp, tid, tid_state, datafile) == 0)) tidrc = TID_OK; else /* ERROR: Update TID-Management failed */ tidrc = TID_ERROR_UPDATE; /* Unlock TID-Management */ unlock_TID(lock_file); fclose(fp); return tidrc; } /*--------------------------------------------------------------------*/ /* Write TID in the TID-Management */ /*--------------------------------------------------------------------*/ static int write_TID(FILE *fp, RFC_TID tid, TID_STATE tid_state, rfc_char_t *datafile) { memsetU (tbuf, cU('\0'), LINE_SIZE_CHAR); actutime = time(NULL); /*CCQ_CLIB_LOCTIME_OK*/ time_ptr = localtime(&actutime); memcpyU (datetime, asctimeU (time_ptr), 24); switch(tid_state) { case CREATED: sprintfU (tbuf, cU("%s %s CREATED %s\n"), datetime, tid, datafile); break; case EXECUTED: sprintfU (tbuf, cU("%s %s EXECUTED %s\n"), datetime, tid, datafile); break; case CONFIRMED: sprintfU (tbuf, cU("%s %s CONFIRMED %s\n"), datetime, tid, datafile); break; case ROLLBACK: sprintfU (tbuf, cU("%s %s ROLLBACK %s\n"), datetime, tid, datafile); break; } if (fputsU (tbuf, fp) < 0) return 1; else return 0; } /*--------------------------------------------------------------------*/ /* Lock the TID-Management */ /*--------------------------------------------------------------------*/ static int lock_TID (rfc_char_t *lockfile, RFC_TID tid) { int try_lock = 60; #ifdef SAPonUNIX struct flock lck; while (try_lock) { if ((lock_fd = openU (lockfile, O_CREAT|O_RDWR, 0777)) == -1) return 1; lck.l_type = F_WRLCK; lck.l_whence = 0; lck.l_start = 0l; lck.l_len = 0l; if (fcntl(lock_fd, F_SETLK, &lck) < 0) { close(lock_fd); sleep(1); try_lock--; } else { memsetU (tbuf, cU('\0'), LINE_SIZE_CHAR); actutime = time(NULL); /*CCQ_CLIB_LOCTIME_OK*/ time_ptr = localtime(&actutime); memcpyU (datetime, asctimeU (time_ptr), 24); sprintfU (tbuf, cU("%s %s EXECUTING \n"), datetime, tid); write(lock_fd, tbuf, LINE_SIZE_RAW); return 0; } } return 1; #elif defined(SAPonNT) while (try_lock) { lock_fd = openU (lockfile, O_CREAT|O_TEMPORARY|O_RDWR, 0777); if (lock_fd == -1) { Sleep(1000); try_lock--; } else { memsetU (tbuf, cU('\0'), LINE_SIZE_CHAR); actutime = time(NULL); /*CCQ_CLIB_LOCTIME_OK*/ time_ptr = localtime(&actutime); memcpyU (datetime, asctimeU (time_ptr), 24); sprintfU (tbuf, cU("%s %s EXECUTING \n"), datetime, tid); write(lock_fd, tbuf, LINE_SIZE_RAW); return 0; } } return 1; #elif defined(SAPonVMS) while (try_lock) { lock_fd = openU (lockfile, O_CREAT|O_RDWR, 0777, cU("fop=dlt"), cU("shr=nil")); if (lock_fd == -1) { sleep(1); try_lock--; } else { memsetU (tbuf, cU('\0'), LINE_SIZE_CHAR); actutime = time(NULL); /*CCQ_CLIB_LOCTIME_OK*/ time_ptr = localtime(&actutime); memcpyU (datetime, asctimeU (time_ptr), 24); sprintfU (tbuf, cU("%s %s EXECUTING \n"), datetime, tid); write(lock_fd, tbuf, LINE_SIZE_RAW); return 0; } } return 1; #elif defined(SAPonOS2_2x) while (try_lock) { lock_fd = openU (lockfile, O_CREAT|O_RDWR, S_IREAD|S_IWRITE ); if (lock_fd == -1) { DosSleep(1000); try_lock--; } else { memsetU (tbuf, cU('\0'), LINE_SIZE_CHAR); actutime = time(NULL); /*CCQ_CLIB_LOCTIME_OK*/ time_ptr = localtime(&actutime); memcpyU (datetime, asctimeU (time_ptr), 24); sprintfU (tbuf, cU("%s %s EXECUTING \n"), datetime, tid); write(lock_fd, tbuf, LINE_SIZE_RAW); return 0; } } return 1; #elif defined(SAPonOS400) struct flock lck; while (try_lock) { if ((lock_fd = openU (lockfile, O_CREAT|O_RDWR)) == -1) return 1; lck.l_type = F_WRLCK; lck.l_whence = 0; lck.l_start = 0l; lck.l_len = 0l; if (fcntl(lock_fd, F_SETLK, &lck) < 0) { close(lock_fd); sleep(1); try_lock--; } else { memsetU (tbuf, cU('\0'), LINE_SIZE_CHAR); actutime = time(NULL); /*CCQ_CLIB_LOCTIME_OK*/ time_ptr = localtime(&actutime); memcpyU (datetime, asctimeU (time_ptr), 24); sprintfU (tbuf, cU("%s %s EXECUTING \n"), datetime, tid); write(lock_fd, (void*)tbuf, LINE_SIZE_RAW); return 0; } } return 1; #elif SAPonOS390 struct flock lck; while (try_lock) { if ((lock_fd = openU (lockfile, O_CREAT|O_RDWR, 0777)) == -1) return 1; lck.l_type = F_WRLCK; lck.l_whence = 0; lck.l_start = 0l; lck.l_len = 0l; if (fcntl(lock_fd, F_SETLK, &lck) < 0) { close(lock_fd); sleep(1); try_lock--; } else { memsetU (tbuf, cU('\0'), LINE_SIZE_CHAR); actutime = time(NULL); /*CCQ_CLIB_LOCTIME_OK*/ time_ptr = localtime(&actutime); memcpyU (datetime, asctimeU (time_ptr), 24); sprintfU (tbuf, cU("%s %s EXECUTING \n"), datetime, tid); write(lock_fd, tbuf, LINE_SIZE_RAW); return 0; } } return 1; #else #error "Error Message > Please update this function for your OS" #endif } /*--------------------------------------------------------------------*/ /* Unlock the TID-Management */ /*--------------------------------------------------------------------*/ static int unlock_TID(rfc_char_t *lockfile) { #if defined(SAPonUNIX) || defined(SAPonOS400) || defined(SAPonOS390) close (lock_fd); unlinkU (lockfile); return 1; #elif defined(SAPonNT) || defined(SAPonVMS) || defined(SAPonOS2_2x) close (lock_fd); return 0; #else #error "Error Message > Please update this function for your OS" #endif } /*--------------------------------------------------------------------*/ /* Move internal table to file */ /*--------------------------------------------------------------------*/ int write_itab_to_file(ITAB_H itab_h, rfc_char_t *datafile, rfc_char_t *itab_name) { FILE *fp; unsigned k, it_leng; if (itab_h == NULL) return 0; /* Open data_file */ fp = fopenU (datafile, cU("a")); if (fp == NULL) return 1; it_leng = ItLeng(itab_h); /* it_leng is number of bytes */ sprintfU (tbuf, cU("Table Name=%s\nTable Line=%u\nTable Fill=%u\n"), itab_name, it_leng, ItFill(itab_h)); if (fwriteU (tbuf, 1, strlenU (tbuf), fp) < strlenU (tbuf)) function_abort(tid_etext10); it_leng = it_leng/sizeofR(SAP_UC); /* it_leng is number of chars now */ for (k = 1; ; k++) { ptr = (rfc_char_t *) ItGetLine(itab_h, k); if (ptr == NULL) break; /* write into file with end of line */ memcpyU (tbuf, ptr, it_leng); tbuf[it_leng] = cU('\n'); if (fwriteU (tbuf, 1, it_leng+1, fp) < it_leng+1) function_abort(tid_etext10); } /* Close data_file */ fclose(fp); return 0; } /*====================================================================*/ /* */ /* Documentation for function STFC_WRITE_TO_TCPIC */ /* */ /*====================================================================*/ static rfc_char_t *transactional_test_docu(void) { static rfc_char_t docu[] = iU("RFC-Client can send data via tRFC in one internal table.") NL_AR iU("") NL_AR iU("TABLES") NL_AR iU(" TCPICDAT C(0072)") NL_AR ; return docu; } #ifdef SAP_RFC_GETNAME /*====================================================================*/ /* */ /* Documentation for function %%USER_GLOBAL_SERVER */ /* */ /*====================================================================*/ static rfc_char_t *user_global_server_docu(void) { static rfc_char_t docu[] = cU("The RFC library will call this function if any unknown") NL_AR cU("RFC function should be executed in this RFC server program.") NL_AR ; return docu; } #endif /*--------------------------------------------------------------------*/ /* set up RFC parameters */ /*--------------------------------------------------------------------*/ void rfc_param (RFC_PARAMETER *rfc_param, rfc_char_t *abap_field_name, unsigned data_type, void *data_addr, unsigned data_len) { RFC_PARAMETER *p = rfc_param; p->name = abap_field_name; p->nlen = abap_field_name == NULL ? 0 : strlenU (abap_field_name); p->type = data_type; p->addr = data_addr; p->leng = data_len; /* init next parameter for no more parameter */ p++; p->name = NULL; p->nlen = 0; p->type = 0; p->addr = NULL; p->leng = 0; return; } /*--------------------------------------------------------------------*/ /* Error Cleanup because of an RFC-Error */ /* Because of Windows DLL function must not be defined as static */ /*--------------------------------------------------------------------*/ void DLL_CALL_BACK_FUNCTION rfc_error (rfc_char_t *operation ) { RFC_ERROR_INFO_EX error_info; sprintfU (tbuf, cU("\n<== RfcLastErrorEx\n")); sprintfU (tbuf+strlenU (tbuf), cU("\nRFC Call/Exception: %s\n"), operation); TRFC_trace(tbuf); RfcLastErrorEx(&error_info); sprintfU (tbuf+strlenU (tbuf), cU("Group Error group %d\n"), error_info.group); sprintfU (tbuf+strlenU (tbuf), cU("Key %s\n"), error_info.key); sprintfU (tbuf+strlenU (tbuf), cU("Message %s\n"), error_info.message); TRFC_trace(tbuf); sprintfU (tbuf, cU("\n<== RfcClose\n")); TRFC_trace(tbuf); RfcClose(RFC_HANDLE_NULL); if (trace_fp != NULL) fclose(trace_fp); exit(1); } /*--------------------------------------------------------------------*/ /* Issue RfcAbort with Abort Text because of an Application Error */ /*--------------------------------------------------------------------*/ void function_abort (rfc_char_t *atext) { sprintfU (tbuf, cU("\nRfcAbort '%s'\n"), atext); TRFC_trace(tbuf); RfcAbort(rfc_handle, atext); if (trace_fp != NULL) fclose(trace_fp); exit(1); } /*--------------------------------------------------------------------*/ /* Write Trace Info into trace_file */ /*--------------------------------------------------------------------*/ void TRFC_trace (rfc_char_t *text) { if (trace_fp != NULL) { fputsU (text, trace_fp); fflush (trace_fp); } fprintfU (stderr, cU("%s"), text); fflush (stderr); return; } /*--------------------------------------------------------------------*/ /* Create file name */ /*--------------------------------------------------------------------*/ static void create_file_name (rfc_char_t *filename) { if (file_nr == 0) { file_nr = time(NULL); znr = (unsigned int) file_nr/2; srand(znr); file_nr = getpid() + rand(); } else file_nr++; strcpyU (filename, working_dir); #if defined(SAPonUNIX) || defined(SAPonNT) || defined(SAPonOS2_2x) || defined(SAPonOS400) || defined(SAPonOS390) sprintfU (filename+strlenU (filename), cU("tr%ld"), file_nr); #elif defined(SAPonVMS) sprintfU (filename+strlenU (filename), cU("tr_%X"), file_nr); #else #error "Error Message > Please update this function for your OS" #endif return; } /*--------------------------------------------------------------------*/ /* Output help for starting program */ /*--------------------------------------------------------------------*/ static void help(void) { printfU ( NL ); printfU (cU("Syntax for start and run in register mode:") NL ); printfU (cU(" ") NL ); printfU (cU(" trfcserv [options]") NL ); printfU (cU(" ") NL ); printfU (cU(" with") NL ); printfU (cU(" options = -D") NL ); printfU (cU(" = -t RFC-Trace on") NL ); printfU (cU(" or") NL ); printfU (cU(" options = -a e.g. .trfcserv") NL ); printfU (cU(" = -g e.g. hs0311") NL ); printfU (cU(" = -x e.g. sapgw53") NL ); printfU (cU(" = -t RFC-Trace on") NL ); printfU (cU(" = -L e.g./krb5/hpux/lib/libkrb5.sl") NL ); printfU (cU(" = -S e.g. s:sample@hw1145") NL ); printfU (cU(" ") NL ); printfU (cU(" Option L and S are only necessary if working with SNC") NL ); printfU (cU(" (Secure Network Communication).") NL ); printfU (cU(" ") NL ); return; }