321 lines
7.3 KiB
C
321 lines
7.3 KiB
C
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <ctype.h>
|
|
#include <sys/types.h>
|
|
#include <sys/socket.h>
|
|
#include <netdb.h>
|
|
#include <netinet/in.h>
|
|
#include <arpa/inet.h>
|
|
#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
|