void dollar_system_init(struct startup_vector *svec) { uint4 status; mstr val, tn; char buf[MAX_TRANS_NAME_LEN]; error_def(ERR_TRNLOGFAIL); dollar_system.mvtype = MV_STR; dollar_system.str.addr = (char *)stringpool.free; dollar_system.str.len = STR_LIT_LEN("47,"); memcpy(stringpool.free, "47,", dollar_system.str.len); stringpool.free += dollar_system.str.len; val.addr = SYSID; val.len = STR_LIT_LEN(SYSID); if (SS_NORMAL == (status = trans_log_name(&val, &tn, buf))) { dollar_system.str.len += tn.len; memcpy(stringpool.free, tn.addr, tn.len); stringpool.free += tn.len; } else if (SS_NOLOGNAM == status) { dollar_system.str.len += svec->sysid_ptr->len; memcpy(stringpool.free, svec->sysid_ptr->addr, svec->sysid_ptr->len); stringpool.free += dollar_system.str.len; } else rts_error(VARLSTCNT(5) ERR_TRNLOGFAIL, 2, LEN_AND_LIT(SYSID), status); assert(stringpool.free < stringpool.top); /* it's process initialization after all */ return; }
int op_open(mval *device, mval *devparms, int timeout, mval *mspace) { LITREF unsigned char io_params_size[]; char buf1[MAX_TRANS_NAME_LEN]; /* buffer to hold translated name */ io_log_name *naml; /* logical record for passed name */ io_log_name *tl; /* logical record for translated name */ io_log_name *prev; /* logical record for removal search */ uint4 stat; /* status */ mstr tn; /* translated name */ error_def(LP_NOTACQ); /* bad license */ MV_FORCE_STR(device); MV_FORCE_STR(devparms); if (mspace) MV_FORCE_STR(mspace); if (timeout < 0) timeout = 0; assert((unsigned char)*devparms->str.addr < n_iops); naml = get_log_name(&device->str, INSERT); if (naml->iod != 0) tl = naml; else { #ifdef NOLICENSE licensed= TRUE; #else CRYPT_CHKSYSTEM; if (!licensed || LP_CONFIRM(lid, lkid)==LP_NOTACQ) licensed= FALSE; #endif switch(stat = trans_log_name(&device->str, &tn, &buf1[0])) { case SS_NORMAL: tl = get_log_name(&tn, INSERT); break; case SS_NOLOGNAM: tl = naml; break; default: for (prev = io_root_log_name, tl = prev->next; tl != 0; prev = tl, tl = tl->next) { if (naml == tl) { prev->next = tl->next; free(tl); break; } } rts_error(VARLSTCNT(1) stat); } } stat = io_open_try(naml, tl, devparms, timeout, mspace); return (stat); }
condition_code dcp_get_circuit(mval *logical) { condition_code status; error_def(ERR_DDPINVCKT); status = trans_log_name(&logical->str, &my_circuit_name, cktnam_buff); if (SS$_NORMAL == status) { if (DDP_CIRCUIT_NAME_LEN == my_circuit_name.len && is_five_bit(my_circuit_name.addr)) my_circuit = five_bit(my_circuit_name.addr); else status = ERR_DDPINVCKT; } return status; }
uint4 trans_numeric(mstr *log, boolean_t *is_defined, boolean_t ignore_errors) { /* return * - 0 on error if ignore_errors is set (otherwise error is raised and no return is made) or * if logical/envvar is undefined. * - an unsigned int containing the numeric value (or as much as could be determined) from * the logical/envvar string value (up to the first non-numeric digit. Characters accepted * are those read by the strtoul() function. */ int4 status; uint4 value; mstr tn; char buf[MAX_TRANS_NAME_LEN], *endptr; error_def(ERR_TRNLOGFAIL); *is_defined = FALSE; if (SS_NORMAL == (status = trans_log_name(log, &tn, buf))) { /* Translation was successful */ *is_defined = TRUE; assert(tn.len < sizeof(buf)); endptr = tn.addr + tn.len; *endptr = '\0'; value = STRTOUL(buf, &endptr, 0); /* Base 0 allows base 10, 0x or octal input */ /* At this point, if '\0' == *endptr, the entire string was successfully consumed as a numeric string. If not, endptr has been updated to point to the errant chars. We currently have no clients who care about this so there is no expansion on this but this could be added at this point. For now we just return whatever numeric value (if any) was gleened.. */ return value; } else if (SS_NOLOGNAM == status) /* Not defined */ return 0; if (!ignore_errors) /* Only give errors if we can handle them */ rts_error(VARLSTCNT(5) ERR_TRNLOGFAIL, 2, log->len, log->addr, status); return 0; }
boolean_t logical_truth_value(mstr *log, boolean_t *is_defined) { /* return * TRUE if the env variable/logical log is defined and evaluates to "TRUE" (or part thereof), or "YES" (or part thereof), * or a non zero integer * FALSE otherwise */ uint4 status; mstr tn; char buf[1024]; boolean_t zero, is_num; int index; error_def(ERR_TRNLOGFAIL); tn.addr = buf; if (NULL != is_defined) *is_defined = FALSE; if (SS_NORMAL == (status = trans_log_name(log, &tn, buf))) { if (NULL != is_defined) *is_defined = TRUE; for (is_num = TRUE, zero = TRUE, index = 0; index < tn.len; index++) { if (!isdigit(buf[index])) { is_num = FALSE; break; } zero = (zero && ('0' == buf[index])); } return (!is_num ? (0 == STRNCASECMP(buf, LOGICAL_TRUE, MIN(sizeof(LOGICAL_TRUE) - 1, tn.len)) || 0 == STRNCASECMP(buf, LOGICAL_YES, MIN(sizeof(LOGICAL_YES) - 1, tn.len))) : !zero); } else if (SS_NOLOGNAM == status) return (FALSE); rts_error(VARLSTCNT(5) ERR_TRNLOGFAIL, 2, log->len, log->addr, status); return (FALSE); }
void mutex_sock_init(void) { mstr mutex_sock_dir_lognam, mutex_sock_dir_transnam; int mutex_sock_path_len; uint4 mutex_sock_trans_status; char mutex_sock_path[MAX_TRANS_NAME_LEN]; int mutex_sock_len, save_errno; struct stat mutex_sock_stat_buf; int status; unsigned char pid_str[2 * sizeof(pid_t) + 1]; error_def(ERR_MUTEXERR); error_def(ERR_TEXT); error_def(ERR_MUTEXRSRCCLNUP); if (mutex_sock_fd != -1) /* Initialization done already */ return; /* Create the socket used for sending and receiving mutex wake mesgs */ if ((mutex_sock_fd = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1) rts_error(VARLSTCNT(7) ERR_MUTEXERR, 0, ERR_TEXT, 2, RTS_ERROR_TEXT("Error with mutex socket create"), errno); memset((char *)&mutex_sock_address, 0, sizeof(mutex_sock_address)); /* Get the socket path */ mutex_sock_dir_lognam.len = sizeof(MUTEX_SOCK_DIR) - 1; mutex_sock_dir_lognam.addr = MUTEX_SOCK_DIR; mutex_sock_trans_status = trans_log_name(&mutex_sock_dir_lognam, &mutex_sock_dir_transnam, mutex_sock_path); if (mutex_sock_trans_status != SS_NORMAL) { strcpy(mutex_sock_path, DEFAULT_MUTEX_SOCK_DIR); mutex_sock_path_len = sizeof(DEFAULT_MUTEX_SOCK_DIR) - 1; } else mutex_sock_path_len = mutex_sock_dir_transnam.len; /* If the path doesn't already end with a '/' pad a '/' */ if (mutex_sock_path[mutex_sock_path_len - 1] != '/') { mutex_sock_path[mutex_sock_path_len++] = '/'; mutex_sock_path[mutex_sock_path_len] = '\0'; } strcpy(mutex_sock_path + mutex_sock_path_len, MUTEX_SOCK_FILE_PREFIX); mutex_sock_path_len += (sizeof(MUTEX_SOCK_FILE_PREFIX) - 1); mutex_wake_this_proc_prefix_len = mutex_sock_path_len; /* Extend mutex_sock_path with pid */ strcpy(mutex_sock_path + mutex_sock_path_len, (char *)pid2ascx(pid_str, process_id)); mutex_sock_path_len += strlen(pid_str); if (mutex_sock_path_len > sizeof(mutex_sock_address.sun_path)) rts_error(VARLSTCNT(6) ERR_MUTEXERR, 0, ERR_TEXT, 2, RTS_ERROR_TEXT("Mutex socket path too long")); mutex_sock_address.sun_family = AF_UNIX; strcpy(mutex_sock_address.sun_path, mutex_sock_path); mutex_sock_len = sizeof(mutex_sock_address.sun_family) + mutex_sock_path_len + 1; /* Include NULL byte in length */ if (UNLINK(mutex_sock_address.sun_path) == -1) /* in case it was left from last time */ { if (errno != ENOENT) { if ((status = send_mesg2gtmsecshr(REMOVE_FILE, (unsigned int)-1, mutex_sock_address.sun_path, mutex_sock_path_len + 1)) == 0) send_msg(VARLSTCNT(8) ERR_MUTEXRSRCCLNUP, 2, mutex_sock_path_len, mutex_sock_path, ERR_TEXT, 2, LEN_AND_LIT("Resource removed by gtmsecshr")); else if (status != ENOENT) /* don't bother if somebody removed the file before gtmsecshr got to it */ rts_error(VARLSTCNT(11) ERR_MUTEXERR, 0, ERR_TEXT, 2, LEN_AND_LIT("gtmsecshr failed to remove leftover mutex resource"), ERR_TEXT, 2, mutex_sock_path_len, mutex_sock_path, status); } } else /* unlink succeeded */ send_msg(VARLSTCNT(4) ERR_MUTEXRSRCCLNUP, 2, mutex_sock_path_len, mutex_sock_path); if (BIND(mutex_sock_fd, (struct sockaddr *)&mutex_sock_address, mutex_sock_len) < 0) rts_error(VARLSTCNT(7) ERR_MUTEXERR, 0, ERR_TEXT, 2, RTS_ERROR_TEXT("Error with mutex socket bind"), errno); /* * Set the socket permissions to override any umask settings. * Allow owner and group read and write access. */ STAT_FILE(mutex_sock_address.sun_path, &mutex_sock_stat_buf, status); if (-1 == status) rts_error(VARLSTCNT(7) ERR_MUTEXERR, 0, ERR_TEXT, 2, RTS_ERROR_TEXT("Error with mutex socket stat"), errno); mutex_sock_stat_buf.st_mode |= (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); if (-1 == CHMOD(mutex_sock_address.sun_path, mutex_sock_stat_buf.st_mode)) rts_error(VARLSTCNT(7) ERR_MUTEXERR, 0, ERR_TEXT, 2, RTS_ERROR_TEXT("Error with mutex socket chmod"), errno); /* Clear the descriptor set used to sense wake up message */ FD_ZERO(&mutex_wait_on_descs); /* * To make mutex_wake_proc faster, pre-initialize portions of * mutex_wake_this_proc which are invariant of the pid to be woken up. */ memset((char *)&mutex_wake_this_proc, 0, sizeof(mutex_wake_this_proc)); mutex_wake_this_proc.sun_family = AF_UNIX; strcpy(mutex_wake_this_proc.sun_path, mutex_sock_path); mutex_wake_this_proc_len = mutex_sock_len; }
int gtmrecv_upd_proc_init(boolean_t fresh_start) { /* Update Process initialization */ mstr upd_proc_log_cmd, upd_proc_trans_cmd; char upd_proc_cmd[UPDPROC_CMD_MAXLEN]; int status; int upd_status, save_upd_status; #ifdef UNIX pid_t upd_pid, waitpid_res; #elif defined(VMS) uint4 upd_pid; uint4 cmd_channel; $DESCRIPTOR(cmd_desc, UPDPROC_CMD_STR); #endif error_def(ERR_RECVPOOLSETUP); error_def(ERR_TEXT); /* Check if the update process is alive */ if ((upd_status = is_updproc_alive()) == SRV_ERR) { gtm_putmsg(VARLSTCNT(7) ERR_RECVPOOLSETUP, 0, ERR_TEXT, 2, RTS_ERROR_LITERAL("Receive pool semctl failure"), REPL_SEM_ERRNO); repl_errno = EREPL_UPDSTART_SEMCTL; return(UPDPROC_START_ERR); } else if (upd_status == SRV_ALIVE && !fresh_start) { gtm_putmsg(VARLSTCNT(4) ERR_TEXT, 2, RTS_ERROR_LITERAL("Update process already exists. Not starting it")); return(UPDPROC_EXISTS); } else if (upd_status == SRV_ALIVE) { gtm_putmsg(VARLSTCNT(6) ERR_RECVPOOLSETUP, 0, ERR_TEXT, 2, RTS_ERROR_LITERAL("Update process already exists. Please kill it before a fresh start")); return(UPDPROC_EXISTS); } save_upd_status = recvpool.upd_proc_local->upd_proc_shutdown; recvpool.upd_proc_local->upd_proc_shutdown = NO_SHUTDOWN; #ifdef UNIX if (0 > (upd_pid = fork())) { recvpool.upd_proc_local->upd_proc_shutdown = save_upd_status; gtm_putmsg(VARLSTCNT(7) ERR_RECVPOOLSETUP, 0, ERR_TEXT, 2, RTS_ERROR_LITERAL("Could not fork update process"), errno); repl_errno = EREPL_UPDSTART_FORK; return(UPDPROC_START_ERR); } if (0 == upd_pid) { /* Update Process */ upd_proc_log_cmd.len = sizeof(UPDPROC_CMD) - 1; upd_proc_log_cmd.addr = UPDPROC_CMD; status = trans_log_name(&upd_proc_log_cmd, &upd_proc_trans_cmd, upd_proc_cmd); if (status != SS_NORMAL) { gtm_putmsg(VARLSTCNT(6) ERR_RECVPOOLSETUP, 0, ERR_TEXT, 2, RTS_ERROR_LITERAL("Could not find path of Update Process. Check value of $gtm_dist")); repl_errno = EREPL_UPDSTART_BADPATH; return(UPDPROC_START_ERR); } upd_proc_cmd[upd_proc_trans_cmd.len] = '\0'; if (EXECL(upd_proc_cmd, upd_proc_cmd, UPDPROC_CMD_ARG1, UPDPROC_CMD_ARG2, NULL) < 0) { gtm_putmsg(VARLSTCNT(7) ERR_RECVPOOLSETUP, 0, ERR_TEXT, 2, RTS_ERROR_LITERAL("Could not exec Update Process"), errno); repl_errno = EREPL_UPDSTART_EXEC; return(UPDPROC_START_ERR); } } #elif defined(VMS) /* Create detached server and write startup commands to it */ status = repl_create_server(&cmd_desc, "GTMU", &cmd_channel, &upd_pid, ERR_RECVPOOLSETUP); if (SS_NORMAL != status) { gtm_putmsg(VARLSTCNT(7) ERR_RECVPOOLSETUP, 0, ERR_TEXT, 2, RTS_ERROR_LITERAL("Unable to spawn Update process"), status); recvpool.upd_proc_local->upd_proc_shutdown = save_upd_status; repl_errno = EREPL_UPDSTART_FORK; return(UPDPROC_START_ERR); } #endif if (recvpool.upd_proc_local->upd_proc_pid) recvpool.upd_proc_local->upd_proc_pid_prev = recvpool.upd_proc_local->upd_proc_pid; else recvpool.upd_proc_local->upd_proc_pid_prev = upd_pid; recvpool.upd_proc_local->upd_proc_pid = upd_pid; /* Receiver Server; wait for the update process to startup */ REPL_DPRINT2("Waiting for update process %d to startup\n", upd_pid); while (get_sem_info(RECV, UPD_PROC_COUNT_SEM, SEM_INFO_VAL) == 0 && is_proc_alive(upd_pid, 0)) { /* To take care of reassignment of PIDs, the while condition should be && with the * condition (PPID of pid == process_id) */ REPL_DPRINT2("Waiting for update process %d to startup\n", upd_pid); UNIX_ONLY(WAITPID(upd_pid, &status, WNOHANG, waitpid_res);) /* Release defunct update process if dead */ SHORT_SLEEP(GTMRECV_WAIT_FOR_SRV_START); }
gtcm_server() { static readonly int4 reptim[2] = {-100000, -1}; /* 10ms */ static readonly int4 wait[2] = {-1000000, -1}; /* 100ms */ void gtcm_ch(), gtcm_exi_handler(), gtcm_init_ast(), gtcm_int_unpack(), gtcm_mbxread_ast(), gtcm_neterr(), gtcm_read_ast(), gtcm_remove_from_action_queue(), gtcm_shutdown_ast(), gtcm_write_ast(), la_freedb(); bool gtcm_link_accept(); bool alid; char buff[512]; char *h = NULL; char *la_getdb(); char nbuff[256]; char *pak = NULL; char reply; unsigned short outlen; int4 closewait[2] = {0, -1}; int4 inid = 0, mdl = 0, nid = 0, days = 0; int4 lic_status; int4 lic_x; int4 lm_mdl_nid(); uint4 status; int i, receive(), value; mstr name1, name2; struct NTD *cmu_ntdroot(); connection_struct *prev_curr_entry; struct dsc$descriptor_s dprd; struct dsc$descriptor_s dver; $DESCRIPTOR(node_name, nbuff); $DESCRIPTOR(proc_name, "GTCM_SERVER"); $DESCRIPTOR(timout, buff); DCL_THREADGBL_ACCESS; GTM_THREADGBL_INIT; assert(0 == EMPTY_QUEUE); /* check so dont need gdsfhead everywhere */ common_startup_init(GTCM_GNP_SERVER_IMAGE); /* Side-effect: Sets skip_dbtriggers to TRUE for non-trigger platforms */ gtm_env_init(); /* read in all environment variables */ name1.addr = "GTCMSVRNAM"; name1.len = SIZEOF("GTCMSVRNAM") - 1; status = trans_log_name(&name1, &name2, nbuff); if (SS$_NORMAL == status) { proc_name.dsc$a_pointer = nbuff; proc_name.dsc$w_length = node_name.dsc$w_length = name2.len; } else if (SS$_NOLOGNAM == status) { MEMCPY_LIT(nbuff, "GTCMSVR"); node_name.dsc$w_length = SIZEOF("GTCMSVR") - 1; } else rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) status); sys$setprn(&proc_name); status = lib$get_foreign(&timout, 0, &outlen, 0); if ((status & 1) && (6 > outlen)) { for (i = 0; i < outlen; i++) { value = value * 10; if (buff[i] <= '9' && buff[i] >= '0') value += buff[i] - 48; else break; } if (outlen && (i == outlen)) { cm_timeout = TRUE; closewait[0] = value * -10000000; } } dprd.dsc$w_length = cm_prd_len; dprd.dsc$b_dtype = DSC$K_DTYPE_T; dprd.dsc$b_class = DSC$K_CLASS_S; dprd.dsc$a_pointer= cm_prd_name; dver.dsc$w_length = cm_ver_len; dver.dsc$b_dtype = DSC$K_DTYPE_T; dver.dsc$b_class = DSC$K_CLASS_S; dver.dsc$a_pointer= cm_ver_name; ast_init(); licensed = TRUE; lkid = 2; # ifdef NOLICENSE lid = 1; # else /* this code used to be scattered to discourage reverse engineering, but since it now disabled, that seems pointless */ lic_status = ((NULL == (h = la_getdb(LMDB))) ? LP_NOCNFDB : SS$_NORMAL); lic_status = ((1 == (lic_status & 1)) ? lm_mdl_nid(&mdl, &nid, &inid) : lic_status); lic_status = ((1 == (lic_status & 1)) ? lp_licensed(h, &dprd, &dver, mdl, nid, &lid, &lic_x, &days, pak) : lic_status); if (LP_NOCNFDB != lic_status) la_freedb(h); if (1 == (lic_status & 1)) { licensed = TRUE; if (days < 14) rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_WILLEXPIRE); } else { licensed = FALSE; sys$exit(lic_status); } # endif gtcm_ast_avail = astq_dyn_avail - GTCM_AST_OVRHD; stp_init(STP_INITSIZE); rts_stringpool = stringpool; cache_init(); procnum = 0; get_proc_info(0, TADR(login_time), &image_count); memset(proc_to_clb, 0, SIZEOF(proc_to_clb)); status = cmi_init(&node_name, 0, 0, gtcm_init_ast, gtcm_link_accept); if (!(status & 1)) { rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ((status ^ 3) | 4)); sys$exit(status); } ntd_root = cmu_ntdroot(); ntd_root->mbx_ast = gtcm_mbxread_ast; ntd_root->err = gtcm_neterr; gtcm_connection = FALSE; lib$establish(gtcm_ch); gtcm_exi_blk.exit_hand = >cm_exi_handler; gtcm_exi_blk.arg_cnt = 1; gtcm_exi_blk.cond_val = >cm_exi_condition; sys$dclexh(>cm_exi_blk); INVOKE_INIT_SECSHR_ADDRS; initialize_pattern_table(); assert(run_time); /* Should have been set by common_startup_init */ while (!cm_shutdown) { if (blkdlist) gtcml_chkreg(); assert(!lib$ast_in_prog()); status = sys$dclast(>cm_remove_from_action_queue, 0, 0); if (SS$_NORMAL != status) rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) CMERR_CMSYSSRV, 0, status, 0); if (INTERLOCK_FAIL == curr_entry) rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) CMERR_CMINTQUE); if (EMPTY_QUEUE != curr_entry) { switch (*curr_entry->clb_ptr->mbf) { case CMMS_L_LKCANALL: reply = gtcmtr_lkcanall(); break; case CMMS_L_LKCANCEL: reply = gtcmtr_lkcancel(); break; case CMMS_L_LKREQIMMED: reply = gtcmtr_lkreqimmed(); break; case CMMS_L_LKREQNODE: reply = gtcmtr_lkreqnode(); break; case CMMS_L_LKREQUEST: reply = gtcmtr_lkrequest(); break; case CMMS_L_LKRESUME: reply = gtcmtr_lkresume(); break; case CMMS_L_LKACQUIRE: reply = gtcmtr_lkacquire(); break; case CMMS_L_LKSUSPEND: reply = gtcmtr_lksuspend(); break; case CMMS_L_LKDELETE: reply = gtcmtr_lkdelete(); break; case CMMS_Q_DATA: reply = gtcmtr_data(); break; case CMMS_Q_GET: reply = gtcmtr_get(); break; case CMMS_Q_KILL: reply = gtcmtr_kill(); break; case CMMS_Q_ORDER: reply = gtcmtr_order(); break; case CMMS_Q_PREV: reply = gtcmtr_zprevious(); break; case CMMS_Q_PUT: reply = gtcmtr_put(); break; case CMMS_Q_QUERY: reply = gtcmtr_query(); break; case CMMS_Q_ZWITHDRAW: reply = gtcmtr_zwithdraw(); break; case CMMS_S_INITPROC: reply = gtcmtr_initproc(); break; case CMMS_S_INITREG: reply = gtcmtr_initreg(); break; case CMMS_S_TERMINATE: reply = gtcmtr_terminate(TRUE); break; case CMMS_E_TERMINATE: reply = gtcmtr_terminate(FALSE); break; case CMMS_U_LKEDELETE: reply = gtcmtr_lke_clearrep(curr_entry->clb_ptr, curr_entry->clb_ptr->mbf); break; case CMMS_U_LKESHOW: reply = gtcmtr_lke_showrep(curr_entry->clb_ptr, curr_entry->clb_ptr->mbf); break; case CMMS_B_BUFRESIZE: reply = CM_WRITE; value = *(unsigned short *)(curr_entry->clb_ptr->mbf + 1); if (value > curr_entry->clb_ptr->mbl) { free(curr_entry->clb_ptr->mbf); curr_entry->clb_ptr->mbf = malloc(value); } *curr_entry->clb_ptr->mbf = CMMS_C_BUFRESIZE; curr_entry->clb_ptr->mbl = value; curr_entry->clb_ptr->cbl = 1; break; case CMMS_B_BUFFLUSH: reply = gtcmtr_bufflush(); break; case CMMS_Q_INCREMENT: reply = gtcmtr_increment(); break; default: reply = FALSE; if (SS$_NORMAL == status) rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_BADGTMNETMSG, 1, (int)*curr_entry->clb_ptr->mbf); break; } if (curr_entry) /* curr_entry can be NULL if went through gtcmtr_terminate */ { status = sys$gettim(&curr_entry->lastact[0]); if (SS$_NORMAL != status) rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) status); /* curr_entry is used by gtcm_mbxread_ast to determine if it needs to defer the interrupt message */ prev_curr_entry = curr_entry; if (CM_WRITE == reply) { /* if ast == gtcm_write_ast, let it worry */ curr_entry->clb_ptr->ast = gtcm_write_ast; curr_entry = EMPTY_QUEUE; cmi_write(prev_curr_entry->clb_ptr); } else { curr_entry = EMPTY_QUEUE; if (1 == (prev_curr_entry->int_cancel.laflag & 1)) { /* valid interrupt cancel msg, handle in gtcm_mbxread_ast */ status = sys$dclast(gtcm_int_unpack, prev_curr_entry, 0); if (SS$_NORMAL != status) rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) status); } else if (CM_READ == reply) { prev_curr_entry->clb_ptr->ast = gtcm_read_ast; cmi_read(prev_curr_entry->clb_ptr); } } } } else if (1 < astq_dyn_avail) { # ifdef GTCM_REPTIM /* if reptim is not needed - and smw doesn't know why it would be - remove this */ status = sys$schdwk(0, 0, &wait[0], &reptim[0]); # else status = sys$schdwk(0, 0, &wait[0], 0); # endif sys$hiber(); sys$canwak(0, 0); } if (cm_timeout && (0 == gtcm_users)) sys$setimr(efn_ignore, closewait, gtcm_shutdown_ast, &cm_shutdown, 0); } }
int gtm_event_log_init(void) { /* External log initializations */ mstr name, trans_name; char log_name[MAX_TRANS_NAME_LEN], shared_lib[MAX_TRANS_NAME_LEN], log_func[MAX_TRANS_NAME_LEN]; int status, index, save_errno; char print_msg[1024], *args; error_def(ERR_EVENTLOGERR); error_def(ERR_TEXT); if (gtm_do_event_log) /* Already initialized */ return(SS_NORMAL); name.len = sizeof(GTM_EVENT_LOG_LIB_ENV) - 1; name.addr = GTM_EVENT_LOG_LIB_ENV; if ((status = trans_log_name(&name, &trans_name, log_name)) != SS_NORMAL || trans_name.len == 0) return(status); memcpy(shared_lib, trans_name.addr, trans_name.len); shared_lib[trans_name.len] = '\0'; if (NULL == (gtm_event_log_handle = fgn_getpak(shared_lib, INFO))) { SPRINTF(print_msg, "Could not open shared library specified in %s - %s. No event logging done", GTM_EVENT_LOG_LIB_ENV, shared_lib); gtm_putmsg(VARLSTCNT(6) ERR_EVENTLOGERR, 0, ERR_TEXT, 2, LEN_AND_STR(print_msg)); return(-1); } #ifdef GTM_EVENT_LOG_HARDCODE_RTN_NAME trans_name.len = sizeof(GTM_EVENT_LOG_RTN) - 1; trans_name.addr = GTM_EVENT_LOG_RTN; #else name.len = sizeof(GTM_EVENT_LOG_RTN_ENV) - 1; name.addr = GTM_EVENT_LOG_RTN_ENV; if ((status = trans_log_name(&name, &trans_name, log_name)) != SS_NORMAL || trans_name.len == 0) { SPRINTF(print_msg, "%s not set or null. No event logging done", GTM_EVENT_LOG_RTN_ENV); gtm_putmsg(VARLSTCNT(6) ERR_EVENTLOGERR, 0, ERR_TEXT, 2, LEN_AND_STR(print_msg)); return(status); } #endif memcpy(log_func, trans_name.addr, trans_name.len); log_func[trans_name.len] = '\0'; if (NULL == (gtm_event_log_func = fgn_getrtn(gtm_event_log_handle, &trans_name, INFO))) { #ifdef GTM_EVENT_LOG_HARDCODE_RTN_NAME SPRINTF(print_msg, "Could not find function %s in shared library %s. No event logging done", log_func, shared_lib); #else SPRINTF(print_msg, "Could not find function specified in %s - %s in shared library %s. No event logging done", GTM_EVENT_LOG_RTN_ENV, log_func, shared_lib); #endif gtm_putmsg(VARLSTCNT(6) ERR_EVENTLOGERR, 0, ERR_TEXT, 2, LEN_AND_STR(print_msg)); return(-1); } gtm_do_event_log = TRUE; return(SS_NORMAL); }