void gtcm_cn_disc(omi_conn *cptr, omi_conn_ll *cll) { time_t end; int i, nxact, nerrs; int rc; /* Cumulative statistics */ end = time((time_t *)0); cll->st_cn.start += end - cptr->stats.start; cll->st_cn.bytes_recv += cptr->stats.bytes_recv; cll->st_cn.bytes_send += cptr->stats.bytes_send; for (i = 0, nxact = 0; i < OMI_OP_MAX; i++) { cll->st_cn.xact[i] += cptr->stats.xact[i]; nxact += cptr->stats.xact[i]; } for (i = 0, nerrs = 0; i < OMI_ER_MAX; i++) { cll->st_cn.errs[i] += cptr->stats.errs[i]; nerrs += cptr->stats.errs[i]; } cll->stats.disc++; if (cptr->state != OMI_ST_DISC) cll->stats.clos++; OMI_DBG_STMP; OMI_DBG((omi_debug, "%s: connection %d to %s closed\n", SRVR_NAME, cptr->stats.id, gtcm_hname(&cptr->stats.sin))); OMI_DBG((omi_debug, "%s:\t%ld seconds connect time\n", SRVR_NAME, end - cptr->stats.start)); OMI_DBG((omi_debug, "%s:\t%d transactions\n", SRVR_NAME, nxact)); OMI_DBG((omi_debug, "%s:\t%d errors\n", SRVR_NAME, nerrs)); OMI_DBG((omi_debug, "%s:\t%d bytes recv'd\n", SRVR_NAME, cptr->stats.bytes_recv)); OMI_DBG((omi_debug, "%s:\t%d bytes sent\n", SRVR_NAME, cptr->stats.bytes_send)); #ifdef BSD_TCP /* Close out the network connection */ CLOSEFILE_RESET(cptr->fd, rc); /* resets "cptr->fd" to FD_INVALID */ #endif /* defined(BSD_TCP) */ if (FD_INVALID != cptr->pklog) CLOSEFILE_RESET(cptr->pklog, rc); /* resets "cptr->pklog" to FD_INVALID */ #ifdef GTCM_RC if (cptr->of) rc_oflow_fin(cptr->of); #endif /* defined(GTCM_RC) */ /* Release locks held on this connection */ omi_prc_unla(cptr, cptr->buff, cptr->buff, cptr->buff); /* Release the buffer and connection structure */ free(cptr->buff); free(cptr); return; }
/* On OSF/1 (Digital Unix), pointers are 64 bits wide; the only exception to this is C programs for which one may * specify compiler and link editor options in order to use (and allocate) 32-bit pointers. However, since C is * the only exception and, in particular because the operating system does not support such an exception, the argv * array passed to the main program is an array of 64-bit pointers. Thus the C program needs to declare argv[] * as an array of 64-bit pointers and needs to do the same for any pointer it sets to an element of argv[]. */ void gtcm_init(int argc, char_ptr_t argv[]) { char *ptr; struct sigaction ignore, act; void get_page_size(); int pid; char msg[256]; int save_errno, maxfds; /* Disassociate from the rest of the universe */ get_page_size(); gtm_wcswidth_fnptr = gtm_wcswidth; # ifndef GTCM_DEBUG_NOBACKGROUND FORK(pid); if (0 > pid) { save_errno = errno; SPRINTF(msg, "Unable to detach %s from controlling tty", SRVR_NAME); gtcm_rep_err(msg, save_errno); EXIT(-1); } else if (0 < pid) EXIT(0); (void) setpgrp(); # endif /* Initialize logging */ omi_pid = getpid(); /* Initialize signals */ sigemptyset(&act.sa_mask); act.sa_flags = 0; ignore = act; ignore.sa_handler = SIG_IGN; act.sa_handler = (void (*)()) gtcm_term; (void) sigaction(SIGTERM, &act, 0); act.sa_handler = (void (*)()) gtcm_dmpstat; (void) sigaction(SIGUSR1, &act, 0); (void) sigaction(SIGUSR2, &ignore, 0); (void) sigaction(SIGALRM, &ignore, 0); (void) sigaction(SIGPIPE, &ignore, 0); (void) sigaction(SIGINT, &ignore, 0); # ifdef GTCM_RC act.sa_handler = gtcm_fail; act.sa_flags = SA_RESETHAND; /* restore signal handler to default action upon receipt of signal */ (void) sigaction(SIGSEGV, &act, 0); (void) sigaction(SIGBUS, &act, 0); (void) sigaction(SIGILL, &act, 0); (void) sigaction(SIGTRAP, &act, 0); (void) sigaction(SIGABRT, &act, 0); # ifndef __linux__ (void) sigaction(SIGEMT, &act, 0); (void) sigaction(SIGSYS, &act, 0); # endif # endif /* Initialize the process flags */ if (0 != gtcm_prsopt(argc, argv)) EXIT(-1); /* Write down pid into log file */ OMI_DBG((omi_debug, "GTCM_SERVER pid : %d\n", omi_pid)); /* Initialize history mechanism */ if (history) { init_hist(); act.sa_handler = (void (*)())dump_rc_hist; act.sa_flags = 0; (void) sigaction(SIGUSR2, &act, 0); } /* Initialize the DBMS */ licensed = TRUE; getjobnum(); getzdir(); if ((maxfds = getmaxfds()) < 0) { gtcm_rep_err("Unable to get system resource limits", errno); EXIT(errno); } assert(SIZEOF(gtcm_ast_avail) == 2); /* check that short is size 2 bytes as following code relies on that */ gtcm_ast_avail = (maxfds > MAXINT2) ? MAXINT2 : maxfds; stp_init(STP_INITSIZE); rts_stringpool = stringpool; curr_pattern = pattern_list = &mumps_pattern; pattern_typemask = mumps_pattern.typemask; INVOKE_INIT_SECSHR_ADDRS; initialize_pattern_table(); /* Preallocate some timer blocks. */ prealloc_gt_timers(); gt_timers_add_safe_hndlrs(); /* Moved to omi_gvextnam, omi_lkextnam */ /* gvinit(); */ return; }
int omi_prc_conn(omi_conn *cptr, char *xend, char *buff, char *bend) { omi_si si, eightbit, chartran, ss_len, ext_cnt; omi_li li_min, li_max, ext; uns_short li_val; int len, i; char *bptr, *eptr; char *ag_name, *ag_pass, *s; bptr = buff; /* Version numbers */ OMI_SI_READ(&si, cptr->xptr); if (si.value != OMI_PROTO_MAJOR) return -OMI_ER_SE_VRSNOTSUPP; OMI_SI_WRIT(OMI_PROTO_MAJOR, bptr); /* XXX minor version numbers */ OMI_SI_READ(&si, cptr->xptr); OMI_SI_WRIT(OMI_PROTO_MINOR, bptr); /* Minimum and maximum parameters */ /* Data */ OMI_LI_READ(&li_min, cptr->xptr); if (OMI_MAX_DATA < li_min.value) { cptr->state = OMI_ST_CLOS; return -OMI_ER_SE_LENMIN; } OMI_LI_READ(&li_max, cptr->xptr); li_val = MIN(li_max.value, OMI_MAX_DATA); OMI_LI_WRIT(li_val, bptr); /* Subscript */ OMI_LI_READ(&li_min, cptr->xptr); if (OMI_MAX_SUBSCR < li_min.value) { cptr->state = OMI_ST_CLOS; return -OMI_ER_SE_LENMIN; } OMI_LI_READ(&li_max, cptr->xptr); li_val = MIN(li_max.value, OMI_MAX_SUBSCR); OMI_LI_WRIT(li_val, bptr); /* Reference */ OMI_LI_READ(&li_min, cptr->xptr); if (OMI_MAX_REF < li_min.value) { cptr->state = OMI_ST_CLOS; return -OMI_ER_SE_LENMIN; } OMI_LI_READ(&li_max, cptr->xptr); li_val = MIN(li_max.value, OMI_MAX_REF); OMI_LI_WRIT(li_val, bptr); /* Message */ OMI_LI_READ(&li_min, cptr->xptr); if (cptr->bsiz < li_min.value) { cptr->state = OMI_ST_CLOS; return -OMI_ER_SE_LENMIN; } OMI_LI_READ(&li_max, cptr->xptr); li_val = MIN(li_max.value, cptr->bsiz); OMI_LI_WRIT(li_val, bptr); /* Oustanding */ OMI_LI_READ(&li_min, cptr->xptr); if (1 < li_min.value) { cptr->state = OMI_ST_CLOS; return -OMI_ER_SE_LENMIN; } OMI_LI_READ(&li_max, cptr->xptr); li_val = MIN(li_max.value, 1); OMI_LI_WRIT(li_val, bptr); /* Other parameters */ OMI_SI_READ(&eightbit, cptr->xptr); OMI_SI_WRIT(eightbit.value, bptr); OMI_SI_READ(&chartran, cptr->xptr); OMI_SI_WRIT(chartran.value, bptr); /* Bounds checking */ if (cptr->xptr > xend || bptr >= bend) return -OMI_ER_PR_INVMSGFMT; /* Implementation ID (in) */ OMI_SI_READ(&ss_len, cptr->xptr); cptr->xptr += ss_len.value; /* Agent name (in) */ OMI_SI_READ(&ss_len, cptr->xptr); if ((ag_name = (char *) malloc(ss_len.value + 1)) == NULL) { OMI_DBG((omi_debug, "%s: memory allocation error (insufficient resources) while\n", SRVR_NAME)); OMI_DBG((omi_debug, "processing connect request from connection %d, %s.\n", cptr->stats.id, gtcm_hname(&cptr->stats.ai))); return -OMI_ER_DB_UNRECOVER; } assert(ss_len.value < MAX_USER_NAME && ss_len.value > 0); memcpy(ag_name, cptr->xptr, ss_len.value); ag_name[ss_len.value] = '\0'; strcpy(cptr->ag_name, ag_name); cptr->xptr += ss_len.value; /* Agent password (in) */ OMI_SI_READ(&ss_len, cptr->xptr); if ((ag_pass = (char *) malloc(ss_len.value + 1)) == NULL) { OMI_DBG((omi_debug, "%s: memory allocation error (insufficient resources) while\n", SRVR_NAME)); OMI_DBG((omi_debug, "processing connect request from connection %d, %s.\n", cptr->stats.id, gtcm_hname(&cptr->stats.ai))); return -OMI_ER_DB_UNRECOVER; } memcpy(ag_pass, cptr->xptr, ss_len.value); ag_pass[ss_len.value] = '\0'; cptr->xptr += ss_len.value; /* No support for authentication on SCO, Linux, Cygwin, or z/OS at the moment...*/ #if !(defined(SCO) || defined(__linux__) || defined(__CYGWIN__) || defined(__MVS__)) if (authenticate) /* verify password and user name */ { #ifdef SHADOWPW struct spwd *spass, *getspnam(); struct stat buf; #endif struct passwd *pass; char *pw, *syspw; /* lowercase agent name */ for(s = ag_name; *s; s++) if (ISUPPER_ASCII(*s)) *s = TOLOWER(*s); #ifdef SHADOWPW if (!Stat("/etc/shadow", &buf)) { if ((spass = getspnam(ag_name)) == NULL) { if (errno) { OMI_DBG((omi_debug, "%s: error opening /etc/shadow for input\n", SRVR_NAME, ag_name)); PERROR("/etc/shadow"); return -OMI_ER_DB_USERNOAUTH; } OMI_DBG((omi_debug, "%s: user %s not found in /etc/shadow\n", SRVR_NAME, ag_name)); return -OMI_ER_DB_USERNOAUTH; } syspw = spass->sp_pwdp; } else if ((pass = getpwnam(ag_name)) == NULL) { OMI_DBG((omi_debug, "%s: user %s not found in /etc/passwd\n", SRVR_NAME, ag_name)); return -OMI_ER_DB_USERNOAUTH; } else syspw = pass->pw_passwd; #else /* ndef SHADOWPW */ if ((pass = getpwnam(ag_name)) == NULL) { OMI_DBG((omi_debug, "%s: user %s not found in /etc/passwd\n", SRVR_NAME, ag_name)); return -OMI_ER_DB_USERNOAUTH; } else syspw = pass->pw_passwd; #endif /* SHADOWPW */ pw = (char *) crypt(ag_pass, syspw); if (strcmp(pw, syspw) != 0) { OMI_DBG((omi_debug, "%s: login attempt for user %s failed.\n", SRVR_NAME, ag_name)); return -OMI_ER_DB_USERNOAUTH; } } #endif /* SCO or linux or cygwin or z/OS */ /* Server name (in) */ OMI_SI_READ(&ss_len, cptr->xptr); cptr->xptr += ss_len.value; /* Implementation ID (out) */ len = SIZEOF(GTM_RELEASE_NAME) - 1; OMI_SI_WRIT(len, bptr); (void) memcpy(bptr, GTM_RELEASE_NAME, len); bptr += len; /* Server name (out) */ OMI_SI_WRIT(0, bptr); /* Server password (out) */ OMI_SI_WRIT(0, bptr); /* Bounds checking */ if (cptr->xptr > xend || bptr >= bend) return -OMI_ER_PR_INVMSGFMT; /* Extensions (in) -- count through them */ OMI_SI_READ(&ext_cnt, cptr->xptr); for (i = 0; i < ext_cnt.value; i++) { OMI_LI_READ(&ext, cptr->xptr); cptr->exts |= (1 << (ext.value - 1)); } /* Mask off extensions we don't support */ cptr->exts &= OMI_EXTENSIONS; /* Negotiate extension combinations */ if (cptr->exts & OMI_XTF_RC && cptr->exts & OMI_XTF_BUNCH) cptr->exts &= ~OMI_XTF_BUNCH; #ifdef GTCM_RC if (cptr->exts & OMI_XTF_RC) cptr->of = rc_oflow_alc(); #endif /* defined(GTCM_RC) */ /* Extensions (out) */ eptr = bptr; bptr += OMI_SI_SIZ; i = 0; if (cptr->exts & OMI_XTF_BUNCH) { OMI_LI_WRIT(OMI_XTN_BUNCH, bptr); i++; } if (cptr->exts & OMI_XTF_GGR) { OMI_LI_WRIT(OMI_XTN_GGR, bptr); i++; } if (cptr->exts & OMI_XTF_NEWOP) { OMI_LI_WRIT(OMI_XTN_NEWOP, bptr); i++; } if (cptr->exts & OMI_XTF_RC) { OMI_LI_WRIT(OMI_XTN_RC, bptr); i++; } /* Number of extensions */ OMI_SI_WRIT(i, eptr); /* Bounds checking */ if (cptr->xptr > xend || bptr >= bend) return -OMI_ER_PR_INVMSGFMT; /* Change the state of the connection */ cptr->state = OMI_ST_CONN; return (int)(bptr - buff); }
void gtcm_pktdmp(char *ptr, int length, char *msg) { char *end; char *chr; int buf[5]; int len; int j; int offset = 0; static int fileID = 0; char tbuf[16]; char fileName[256]; time_t ctim; struct tm *ltime; FILE *fp; char *gtm_dist; ctim = time(0); GTM_LOCALTIME(ltime, &ctim); SPRINTF(tbuf, "%02d%02d%02d%02d",ltime->tm_mon + 1,ltime->tm_mday, ltime->tm_hour,ltime->tm_min); if (gtm_dist=getenv("gtm_dist")) { char subdir[256]; struct stat buf; /* check for the subdirectory $gtm_dist/log/<omi_service> * If the subdirectory exists, place the log file there. * Otherwise...place the file in $gtm_dist/log. */ SPRINTF(subdir,"%s/log/%s", gtm_dist, omi_service); if (stat(subdir,&buf) == 0 && S_ISDIR(buf.st_mode)) { SPRINTF(fileName,"%s/%s_%s.%d", subdir, omi_service, tbuf, fileID++); } else { SPRINTF(fileName,"%s/log/%s_%s.%d", gtm_dist, omi_service, tbuf, fileID++); } } else SPRINTF(fileName,"/usr/tmp/%s_%s.%d", omi_service, tbuf, fileID++); #ifdef __MVS__ if (-1 == gtm_zos_create_tagged_file(fileName, TAG_EBCDIC)) { FPRINTF(stderr,"Could not create and tag new packet dump file (%s).\n", fileName); perror(fileName); } #endif fp = fopen(fileName, "w"); if (fp == NULL) { FPRINTF(stderr,"Could not open packet dump file (%s).\n", fileName); perror(fileName); return; } OMI_DBG((omi_debug, "%s\n", msg)); OMI_DBG((omi_debug, "Log dumped to %s.\n", fileName)); FPRINTF(fp,"%s\n", msg); buf[4] = '\0'; end = ptr + length; chr = (char *)buf; while (ptr < end) { fputc('\t', fp); if ((len = (int)(end - ptr)) > 16) len = 16; memcpy(chr, ptr, len); ptr += len; offset += len; for (j = len; j < 16; j++) chr[j] = '\0'; for (j = 0; j < 4; j++) FPRINTF(fp,"%08x ", buf[j]); for (j = 0; j < 16; j++) if (j >= len) chr[j] = ' '; else if (chr[j] < 32 || chr[j] > 126) chr[j] = '.'; FPRINTF(fp,"%16s %x\n", chr, offset); } FFLUSH(fp); fclose(fp); }
int gtcm_bgn_net(omi_conn_ll *cll) { extern int4 omi_nxact, omi_nerrs, omi_brecv, omi_bsent; omi_fd fd; int i; int save_errno; int rc; #ifdef NET_TCP struct servent *se; unsigned short port; char port_buffer[NI_MAXSERV]; #endif /* defined(NET_TCP) */ #ifdef BSD_TCP struct addrinfo *ai_ptr, hints; const boolean_t reuseaddr = TRUE; int errcode; #else /* defined(BSD_TCP) */ #ifdef SYSV_TCP struct t_bind *bind; #endif /* defined(SYSV_TCP) */ #endif /* !defined(BSD_TCP) */ /* The linked list of connections */ cll->head = cll->tail = (omi_conn *)0; /* The statistics */ cll->stats.conn = cll->stats.clos = cll->stats.disc = 0; cll->st_cn.bytes_recv = 0; cll->st_cn.bytes_send = 0; cll->st_cn.start = 0; for (i = 0; i < OMI_OP_MAX; i++) cll->st_cn.xact[i] = 0; for (i = 0; i < OMI_ER_MAX; i++) cll->st_cn.errs[i] = 0; omi_nxact = omi_nerrs = omi_brecv = omi_bsent = 0; /* Fall back on a compile time constant */ if (!omi_service) omi_service = SRVC_NAME; #ifdef NET_TCP /* NET_TCP is defined only when BSD_TCP is defined or SYSV_TCP is defined, but SYSV_TCP is never defined (a bug?) * so we move the code of obtaining port information from service down to #ifdef BSD_TCP */ #ifdef SYSV_TCP GTMASSERT; #endif #endif /* defined(NET_TCP) */ #ifdef BSD_TCP /* Create a socket always tries IPv6 first */ SERVER_HINTS(hints, ((GTM_IPV6_SUPPORTED && !ipv4_only) ? AF_INET6 : AF_INET)); if ((fd = socket(hints.ai_family, SOCK_STREAM, 0)) < 0) { if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { save_errno = errno; return save_errno; } hints.ai_family = AF_INET; } /* Bind an address to the socket */ if (0 != (errcode = getaddrinfo(NULL, omi_service, &hints, &ai_ptr))) { RTS_ERROR_ADDRINFO(NULL, ERR_GETADDRINFO, errcode); return errcode; } if (ISDIGIT_ASCII(*omi_service)) port = atoi(omi_service); else { if (0 != (errcode = getnameinfo(ai_ptr->ai_addr, ai_ptr->ai_addrlen, NULL, 0, port_buffer, NI_MAXSERV, NI_NUMERICSERV))) { assert(FALSE); RTS_ERROR_ADDRINFO(NULL, ERR_GETNAMEINFO, errcode); return errcode; } port = atoi(port_buffer); } /* Reuse a specified address */ if (port && setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&reuseaddr, SIZEOF(reuseaddr)) < 0) { save_errno = errno; CLOSEFILE_RESET(fd, rc); /* resets "fd" to FD_INVALID */ return save_errno; } if (bind(fd, ai_ptr->ai_addr, ai_ptr->ai_addrlen) < 0) { save_errno = errno; CLOSEFILE_RESET(fd, rc); /* resets "fd" to FD_INVALID */ return save_errno; } /* Initialize the listen queue */ if (listen(fd, 5) < 0) { save_errno = errno; CLOSEFILE_RESET(fd, rc); /* resets "fd" to FD_INVALID */ return save_errno; } /* set up raw socket for use with pinging option */ if (ping_keepalive) psock = init_ping(); /* Store the file descriptor away for use later */ cll->nve = fd; OMI_DBG_STMP; OMI_DBG((omi_debug, "%s: socket registered at port %d\n", SRVR_NAME, (int)port)); #ifdef GTCM_RC OMI_DBG((omi_debug, "RC server ID %d, Process ID %d\n", rc_server_id, omi_pid)); #endif if (authenticate) OMI_DBG((omi_debug, "Password verification on OMI connections enabled.\n")); if (!one_conn_per_inaddr) OMI_DBG((omi_debug, "Multiple connections from the same internet address allowed.\n")); if (psock > 0) OMI_DBG((omi_debug, "Keepalive option (-ping) enabled.\n")); return 0; #else /* defined(BSD_TCP) */ #ifdef SYSV_TCP GTMASSERT; if ((fd = t_open(SYSV_TCP, O_RDWR, NULL)) < 0) { save_errno = errno; return save_errno; } if (!(bind = (struct t_bind *)t_alloc(fd, T_BIND, T_ALL))) { save_errno = errno; (void) t_close(fd); return save_errno; } bind->qlen = 5; bind->addr.len = 0; bind->addr.buf = 0; if (t_bind(fd, bind, bind) < 0) { save_errno = errno; (void) t_free(bind, T_BIND); (void) t_close(fd); return save_errno; } /* Store the file descriptor away for use later */ cll->nve = fd; OMI_DBG_STMP; OMI_DBG((omi_debug, "%s: socket registered at port %d\n", SRVR_NAME, (int)port)); #ifdef GTCM_RC OMI_DBG((omi_debug, "RC server ID %d\n", rc_server_id)); #endif return 0; #else /* defined(SYSV_TCP) */ cll->nve = FD_INVALID; return -1; #endif /* !defined(SYSV_TCP) */ #endif /* !defined(BSD_TCP) */ }
int gtcm_cn_acpt(omi_conn_ll *cll, int now) /* now --> current time in seconds */ { int i; omi_conn *cptr; omi_fd fd; int rc; char *tmp_time; #ifdef BSD_TCP GTM_SOCKLEN_TYPE sln; struct sockaddr_storage sas; int optsize; const boolean_t keepalive = TRUE; /* Accept the connection from the network layer */ sln = SIZEOF(sas); if ((fd = accept(cll->nve, (struct sockaddr *)&sas, (GTM_SOCKLEN_TYPE *)&sln)) < 0) return -1; #endif /* defined(BSD_TCP) */ /* Build the client data structure */ if (!(cptr = (omi_conn *)malloc(SIZEOF(omi_conn))) || !(cptr->buff = (char *)malloc(OMI_BUFSIZ))) { if (cptr) free(cptr); CLOSEFILE_RESET(fd, rc); /* resets "fd" to FD_INVALID */ return -1; } /* Initialize the connection structure */ cptr->next = (omi_conn *)0; cptr->fd = fd; cptr->ping_cnt = 0; cptr->timeout = now + conn_timeout; cptr->bsiz = OMI_BUFSIZ; cptr->bptr = cptr->buff; cptr->xptr = (char *)0; cptr->blen = 0; cptr->exts = 0; cptr->state = OMI_ST_DISC; cptr->ga = (ga_struct *)0; /* struct gd_addr_struct */ cptr->of = (oof_struct *) malloc(SIZEOF(struct rc_oflow)); memset(cptr->of, 0, SIZEOF(struct rc_oflow)); cptr->pklog = FD_INVALID; /* Initialize the statistics */ memcpy(&cptr->stats.sas, &sas, sln); cptr->stats.ai.ai_addr = (struct sockaddr *)&cptr->stats.sas; cptr->stats.ai.ai_addrlen = sln; cptr->stats.bytes_recv = 0; cptr->stats.bytes_send = 0; cptr->stats.start = time((time_t *)0); for (i = 0; i < OMI_OP_MAX; i++) cptr->stats.xact[i] = 0; for (i = 0; i < OMI_ER_MAX; i++) cptr->stats.errs[i] = 0; /* if we only allowing one connection per internet address, close any existing ones with the same addr. */ if (one_conn_per_inaddr) { omi_conn *this, *prev; for (prev = NULL, this = cll->head; this; prev = this, this = this->next) { if (0 == memcmp((sockaddr_ptr)(&this->stats.sas), (sockaddr_ptr)&sas, sln)) { if (cll->tail == this) cll->tail = cptr; if (prev) prev->next = cptr; else cll->head = cptr; cptr->next = this->next; OMI_DBG_STMP; OMI_DBG((omi_debug, "%s: dropping old connection to %s\n", SRVR_NAME, gtcm_hname(&cptr->stats.ai))); gtcm_cn_disc(this, cll); break; } } /* not found - add to the end of the list */ if (!this) { if (cll->tail) { cll->tail->next = cptr; cll->tail = cptr; } else cll->head = cll->tail = cptr; } } else { /* Insert the client into the list of connections */ if (cll->tail) { cll->tail->next = cptr; cll->tail = cptr; } else cll->head = cll->tail = cptr; } cptr->stats.id = ++cll->stats.conn; DEBUG_ONLY( if (omi_pklog) { int errno_save; char pklog[1024]; (void)SPRINTF(pklog, "%s.%04d", omi_pklog, cptr->stats.id); if (INV_FD_P((cptr->pklog = OPEN3(pklog, O_WRONLY|O_CREAT|O_APPEND|O_TRUNC, 0644)))) { errno_save = errno; OMI_DBG_STMP; OMI_DBG((omi_debug, "%s: unable to open packet log \"%s\"\n\t%s\n", SRVR_NAME, pklog, STRERROR(errno_save))); } } )
short rc_fnd_file(rc_xdsid *xdsid) { gv_namehead *g; short dsid, node; gd_binding *map; char buff[1024], *cp, *cp1; mstr fpath1, fpath2; mval v; int i, keysize; int len, node2; GET_SHORT(dsid, &xdsid->dsid.value); GET_SHORT(node, &xdsid->node.value); if (!dsid_list) { /* open special database, set up entry */ dsid_list = (rc_dsid_list *)malloc(SIZEOF(rc_dsid_list)); dsid_list->dsid = RC_NSPACE_DSID; dsid_list->next = NULL; fpath1.addr = RC_NSPACE_PATH; fpath1.len = SIZEOF(RC_NSPACE_PATH); if (SS_NORMAL != TRANS_LOG_NAME(&fpath1, &fpath2, buff, SIZEOF(buff), do_sendmsg_on_log2long)) { char msg[256]; SPRINTF(msg, "Invalid DB filename, \"%s\"", fpath1.addr); gtcm_rep_err(msg, errno); return RC_BADFILESPEC; } if (fpath2.len > MAX_FN_LEN) return RC_BADFILESPEC; dsid_list->fname = (char *)malloc(fpath2.len + 1); memcpy(dsid_list->fname, fpath2.addr, fpath2.len); *((char*)(dsid_list->fname + fpath2.len)) = 0; gv_cur_region = (gd_region *)malloc(SIZEOF(gd_region)); memset(gv_cur_region, 0, SIZEOF(gd_region)); gv_cur_region->dyn.addr = (gd_segment *)malloc(SIZEOF(gd_segment)); memset(gv_cur_region->dyn.addr, 0, SIZEOF(gd_segment)); memcpy(gv_cur_region->dyn.addr->fname, fpath2.addr, fpath2.len); gv_cur_region->dyn.addr->fname_len = fpath2.len; gv_cur_region->dyn.addr->acc_meth = dba_bg; ESTABLISH_RET(rc_fnd_file_ch1, RC_SUCCESS); gvcst_init(gv_cur_region); REVERT; change_reg(); /* check to see if this DB has the reserved bytes field set * correctly. Global pages must always have some extra unused * space left in them (RC_RESERVED bytes) so that the page * will fit into the client buffer when unpacked by the * client. */ if (cs_data->reserved_bytes < RC_RESERVED) { OMI_DBG((omi_debug, "Unable to access database file: \"%s\"\nReserved_bytes field in the file header is too small for GT.CM\n", fpath2.addr)); free(dsid_list->fname); dsid_list->fname = NULL; free(dsid_list); dsid_list = NULL; free(gv_cur_region->dyn.addr); gv_cur_region->dyn.addr = NULL; free(gv_cur_region); gv_cur_region = NULL; return RC_FILEACCESS; } gv_keysize = DBKEYSIZE(gv_cur_region->max_key_size); GVKEY_INIT(gv_currkey, gv_keysize); GVKEY_INIT(gv_altkey, gv_keysize); cs_addrs->dir_tree = (gv_namehead *)malloc(SIZEOF(gv_namehead) + 2 * SIZEOF(gv_key) + 3 * (gv_keysize - 1)); g = cs_addrs->dir_tree; g->first_rec = (gv_key*)(g->clue.base + gv_keysize); g->last_rec = (gv_key*)(g->first_rec->base + gv_keysize); g->clue.top = g->last_rec->top = g->first_rec->top = gv_keysize; g->clue.prev = g->clue.end = 0; g->root = DIR_ROOT; dsid_list->gda = (gd_addr*)malloc(SIZEOF(gd_addr) + 3 * SIZEOF(gd_binding)); dsid_list->gda->n_maps = 3; dsid_list->gda->n_regions = 1; dsid_list->gda->n_segments = 1; dsid_list->gda->maps = (gd_binding*)((char*)dsid_list->gda + SIZEOF(gd_addr)); dsid_list->gda->max_rec_size = gv_cur_region->max_rec_size; map = dsid_list->gda->maps; map ++; memset(map->name, 0, SIZEOF(map->name)); map->name[0] = '%'; map->reg.addr = gv_cur_region; map++; map->reg.addr = gv_cur_region; memset(map->name, -1, SIZEOF(map->name)); dsid_list->gda->tab_ptr = (hash_table_mname *)malloc(SIZEOF(hash_table_mname)); init_hashtab_mname(dsid_list->gda->tab_ptr, 0, HASHTAB_NO_COMPACT, HASHTAB_NO_SPARE_TABLE); change_reg(); if (rc_overflow->top < cs_addrs->hdr->blk_size) { if (rc_overflow->buff) free(rc_overflow->buff); rc_overflow->top = cs_addrs->hdr->blk_size; rc_overflow->buff = (char*)malloc(rc_overflow->top); if (rc_overflow_size < rc_overflow->top) rc_overflow_size = rc_overflow->top; } } for (fdi_ptr = dsid_list; fdi_ptr && (fdi_ptr->dsid != dsid); fdi_ptr = fdi_ptr->next) ; if (!fdi_ptr) { /* need to open new database, add to list, set fdi_ptr */ gd_header = dsid_list->gda; gv_currkey->end = 0; v.mvtype = MV_STR; v.str.len = RC_NSPACE_GLOB_LEN-1; v.str.addr = RC_NSPACE_GLOB; GV_BIND_NAME_AND_ROOT_SEARCH(gd_header, &v.str); if (!gv_target->root) /* No namespace global */ return RC_UNDEFNAMSPC; v.mvtype = MV_STR; v.str.len = SIZEOF(RC_NSPACE_DSI_SUB)-1; v.str.addr = RC_NSPACE_DSI_SUB; mval2subsc(&v,gv_currkey); node2 = node; MV_FORCE_MVAL(&v,node2); mval2subsc(&v,gv_currkey); i = dsid / 256; MV_FORCE_MVAL(&v,i); mval2subsc(&v,gv_currkey); if (gvcst_get(&v)) return RC_UNDEFNAMSPC; for (cp = v.str.addr, i = 1; i < RC_FILESPEC_PIECE; i++) for (; *cp++ != RC_FILESPEC_DELIM; ) ; for (cp1 = cp; *cp1++ != RC_FILESPEC_DELIM; ) ; cp1--; len = (int)(cp1 - cp); if (len > MAX_FN_LEN) return RC_BADFILESPEC; fdi_ptr = (rc_dsid_list *)malloc(SIZEOF(rc_dsid_list)); fdi_ptr->fname = (char *)malloc(len+1); fdi_ptr->dsid = dsid; memcpy(fdi_ptr->fname, cp, len); *(fdi_ptr->fname + (len)) = 0; gv_cur_region = (gd_region *)malloc(SIZEOF(gd_region)); memset(gv_cur_region, 0, SIZEOF(gd_region)); gv_cur_region->dyn.addr = (gd_segment *)malloc(SIZEOF(gd_segment)); memset(gv_cur_region->dyn.addr, 0, SIZEOF(gd_segment)); memcpy(gv_cur_region->dyn.addr->fname, cp, len); gv_cur_region->dyn.addr->fname_len = len; gv_cur_region->dyn.addr->acc_meth = dba_bg; ESTABLISH_RET(rc_fnd_file_ch2, RC_SUCCESS); gvcst_init(gv_cur_region); REVERT; change_reg(); /* check to see if this DB has the reserved bytes field set * correctly. Global pages must always have some extra unused * space left in them (RC_RESERVED bytes) so that the page * will fit into the client buffer when unpacked by the * client. */ if (cs_data->reserved_bytes < RC_RESERVED) { OMI_DBG((omi_debug, "Unable to access database file: \"%s\"\nReserved_bytes field in the file header is too small for GT.CM\n", fdi_ptr->fname)); free(dsid_list->fname); dsid_list->fname = NULL; free(dsid_list); dsid_list = NULL; free(gv_cur_region->dyn.addr); gv_cur_region->dyn.addr = NULL; free(gv_cur_region); gv_cur_region = NULL; return RC_FILEACCESS; } assert(!cs_addrs->hold_onto_crit); /* this ensures we can safely do unconditional grab_crit and rel_crit */ grab_crit(gv_cur_region); cs_data->rc_srv_cnt++; if (!cs_data->dsid) { cs_data->dsid = dsid; cs_data->rc_node = node; } else if (cs_data->dsid != dsid || cs_data->rc_node != node) { cs_data->rc_srv_cnt--; rel_crit(gv_cur_region); OMI_DBG((omi_debug, "Dataset ID/RC node mismatch")); OMI_DBG((omi_debug, "DB file: \"%s\"\n", dsid_list->fname)); OMI_DBG((omi_debug, "Stored DSID: %d\tRC Node: %d\n", cs_data->dsid, cs_data->rc_node)); OMI_DBG((omi_debug, "RC Rq DSID: %d\tRC Node: %d\n", dsid,node)); free(fdi_ptr->fname); fdi_ptr->fname = NULL; free(fdi_ptr); fdi_ptr = NULL; free(gv_cur_region->dyn.addr); gv_cur_region->dyn.addr = NULL; free(gv_cur_region); gv_cur_region = NULL; return RC_FILEACCESS; } rel_crit(gv_cur_region); keysize = DBKEYSIZE(gv_cur_region->max_key_size); GVKEYSIZE_INCREASE_IF_NEEDED(keysize); cs_addrs->dir_tree = (gv_namehead *)malloc(SIZEOF(gv_namehead) + 2 * SIZEOF(gv_key) + 3 * (keysize - 1)); g = cs_addrs->dir_tree; g->first_rec = (gv_key*)(g->clue.base + keysize); g->last_rec = (gv_key*)(g->first_rec->base + keysize); g->clue.top = g->last_rec->top = g->first_rec->top = keysize; g->clue.prev = g->clue.end = 0; g->root = DIR_ROOT; fdi_ptr->gda = (gd_addr*)malloc(SIZEOF(gd_addr) + 3 * SIZEOF(gd_binding)); fdi_ptr->gda->n_maps = 3; fdi_ptr->gda->n_regions = 1; fdi_ptr->gda->n_segments = 1; fdi_ptr->gda->maps = (gd_binding*)((char*)fdi_ptr->gda + SIZEOF(gd_addr)); fdi_ptr->gda->max_rec_size = gv_cur_region->max_rec_size; map = fdi_ptr->gda->maps; map ++; memset(map->name, 0, SIZEOF(map->name)); map->name[0] = '%'; map->reg.addr = gv_cur_region; map++; map->reg.addr = gv_cur_region; memset(map->name, -1, SIZEOF(map->name)); fdi_ptr->gda->tab_ptr = (hash_table_mname *)malloc(SIZEOF(hash_table_mname)); init_hashtab_mname(fdi_ptr->gda->tab_ptr, 0, HASHTAB_NO_COMPACT, HASHTAB_NO_SPARE_TABLE); fdi_ptr->next = dsid_list->next; dsid_list->next = fdi_ptr; } gv_cur_region = fdi_ptr->gda->maps[1].reg.addr; change_reg(); if (rc_overflow->top < cs_addrs->hdr->blk_size) { if (rc_overflow->buff) free(rc_overflow->buff); rc_overflow->top = cs_addrs->hdr->blk_size; rc_overflow->buff = (char*)malloc(rc_overflow->top); if (rc_overflow_size < rc_overflow->top) rc_overflow_size = rc_overflow->top; } if (!rc_overflow -> top) { rc_overflow -> top = rc_overflow_size; rc_overflow->buff = (char *)malloc(rc_overflow->top); } gd_header = fdi_ptr->gda; return RC_SUCCESS; }