#include #include #include #include #include #include #include #include #include #include #include "instr_hosts.h" static char *service; static char *crit; static char *input; static int foundcount; static int home; static char hostport[128]; static char *instr; static int instr_len; static char *host; static int host_len; static int port; static char remoteinstrument[128]; static char hostname[128]; static char remotehostbuf[128]; static char *remotehost; static char *getItem(char *line, char *name, char *value, int value_len) { /* get the named item for line, or check if the name/value pair is present * the found value is returned, if found * if value_len != 0, the result is copied to value * if value is not empty, it must be matched */ char find[64]; char *found, *p, *sp, *result; int l; if (value == NULL) value="(NULL)"; p = strchr(value, '.'); if (p) { l = p - value; } else { l = strlen(value); } snprintf(find, sizeof find, "%s=%.*s", name, l, value); for (p = find; *p; p++) *p = tolower(*p); found = strstr(line, find); if (found && *value != '\0' && found[strlen(find)] > ' ' && found[strlen(find)] != '.') { /* when value is given, it must be complete, (a dot or a space terminates the value) */ found = NULL; } if (found) { found += strlen(name)+1; if (value_len == 0) { result = found; } else { sp = strchr(found, ' '); if (sp && sp < found + value_len) { l = sp - found; } else { l = strlen(found); } if (l < value_len) { strncpy(value, found, l); value[l] = '\0'; result = value; } else { value[0] = '\0'; result = NULL; } } } else { if (value_len > 0) { *value = '\0'; } result = NULL; } return result; } void scanHostList(void (*func)(char *)) { int i; FILE *fil, *lfil; char *hostlist; char localhostlist[512]; char line[512], lline[512]; int dirty; hostlist = getenv("InstrumentHostList"); if (!hostlist) { hostlist="/afs/psi.ch/project/sinq/common/lib/sea/hostlist"; } fil = fopen(hostlist, "r"); snprintf(localhostlist, sizeof localhostlist, "%s/.six/hostlist", getenv("HOME")); lfil = fopen(localhostlist, "r"); dirty = 0; if (fil) { if (!lfil) dirty = 1; } else { if (!lfil) return; fil = lfil; lfil = NULL; } while (NULL != fgets(line, sizeof line, fil)) { if (!dirty && lfil && (fgets(lline, sizeof lline, lfil) == NULL || strcmp(line, lline) != 0)) { dirty = 1; } if (line[0] != '#' && line[0] != 0) { i = strlen(line) - 1; if (line[i] == '\n') line[i] = 0; func(line); } } if (fil) fclose(fil); if (lfil) fclose(lfil); if (dirty) { fil = fopen(hostlist, "r"); if (fil) { lfil = fopen(localhostlist, "w"); if (lfil) { while( EOF != (i = getc(fil)) ) { /* copy file to local file */ putc(i, lfil); } fclose(lfil); } fclose(fil); } } } char *GetHostName(void) { char *pend; if (!hostname[0]) { gethostname(hostname, sizeof hostname); hostname[sizeof hostname - 1] = 0; pend = strchr(hostname, '.'); if (pend) *pend = 0; } return hostname; } char *InstrHostRemoteName(void) { struct hostent *res; struct in_addr inadr; char *pend; if (remotehost == NULL) { remotehost = getenv("REMOTEHOST"); if (!remotehost) { remotehost = getenv("SSH_CLIENT"); if (remotehost) { snprintf(remotehostbuf, sizeof remotehostbuf, "%s", remotehost); pend = strchr(remotehostbuf, ' '); if (pend) *pend = 0; remotehost = remotehostbuf; } } if (!remotehost) { remotehost = GetHostName(); } if (!remotehost) { remotehost = ""; } else { if (inet_aton(remotehost, &inadr)) { if ((res = gethostbyaddr(&inadr, sizeof inadr, AF_INET))) { remotehost = res->h_name; } } } if (remotehost != remotehostbuf) { snprintf(remotehostbuf, sizeof remotehostbuf, "%s", remotehost); remotehost = remotehostbuf; } pend = strchr(remotehostbuf, '.'); if (pend) { if (strcmp(pend, ".psi.ch") == 0) { *pend = 0; } else { strcpy(remotehostbuf, ""); } } } return remotehost; } static void findCrit(char *line) { char *colon; int i; char *h; if (getItem(line, crit, input, 0) != NULL) { hostport[0]='\0'; if (getItem(line, service, hostport, sizeof hostport) != NULL) { instr[0] = '\0'; if (foundcount == 0) { getItem(line, "instr", instr, instr_len); } colon = strchr(hostport, ':'); if (colon) { i = atoi(colon+1); if (i > 0) { *colon='\0'; if (foundcount == 0) { snprintf(host, host_len, "%s", hostport); port = i; } foundcount++; GetHostName(); if (getItem(line, "host", hostname, sizeof hostname)) { home = 1; } } } } } h = getItem(line, "host", remotehost, 0); if (h) { if (remoteinstrument[0]) { /* more than one entry: no real instrument */ strcpy(remoteinstrument, "-"); } else { getItem(line, "instr", remoteinstrument, sizeof remoteinstrument); } } } int InstrHost(char *serviceArg, char *inputArg, char *instrArg, int instr_lenArg, char *hostArg, int host_lenArg, int *portArg) { service = serviceArg; input = inputArg; instr = instrArg; instr_len = instr_lenArg; host = hostArg; host_len = host_lenArg; port = 0; home = 0; foundcount = 0; remoteinstrument[0] = 0; if (input == NULL || input[0] <= ' ') { crit = "host"; input = GetHostName(); } else { crit = "instr"; } InstrHostRemoteName(); scanHostList(findCrit); if (strcmp(remoteinstrument, "-") == 0) { remoteinstrument[0] = 0; } *portArg = port; return home * foundcount; } char *InstrHostRemoteInstr(void) { return strdup(remoteinstrument); } char *InstrHostName(void) { return strdup(hostname); } static char *list; static int list_len; static void listInstr(char *line) { int l; *list='\0'; if (getItem(line, service, "", 0) && getItem(line, "instr", list, list_len)) { l = strlen(list); list += l; list_len -= l; } else if (line[0] > ' ') { return; } if (list_len > 0) { *list = ' '; list++; list_len--; } } void InstrList(char *serviceArg, char *listArg, int list_lenArg) { service = serviceArg; list = listArg; list_len = list_lenArg; scanHostList(listInstr); if (list > listArg) list--; /* remove trailing blank */ *list = '\0'; } #ifdef MYC_FORTRAN /* compile only when fortran c interface stuff is defined */ #include "myc_fortran.h" int F_FUN(instr_host)(F_CHAR(service), F_CHAR(input), F_CHAR(instr), F_CHAR(host), int *port , int service_len, int input_len, int instr_len, int host_len) { char buf[256], in[256], ho[256], sv[256]; int iRet; STR_TO_C(sv, service); STR_TO_C(buf, input); iRet=InstrHost(sv, buf, in, sizeof(in), ho, sizeof(ho), port); if (*port>0) { STR_TO_F(instr, in); STR_TO_F(host, ho); } return iRet; } #endif