diff --git a/tecs/six.c b/tecs/six.c index 6b04cff..f3f1d48 100644 --- a/tecs/six.c +++ b/tecs/six.c @@ -6,11 +6,52 @@ #include #include #include -#include +#include "term.h" #include "coc_util.h" #include "myc_err.h" #include "myc_str.h" -#include "term.h" + +static char *host; +static char instr[32]; +static int fd; +static int level=3; +static int deflevel=0; +static int remember=1; +static char user1[32]=""; +static char pswd1[32]=""; +static char user2[32]=""; +static char pswd2[32]=""; + +void Usage(void) { + printf("\n"); + printf(" six commandline options:\n"); + printf(" - login as spy\n"); + printf(" + login as manager\n"); + printf(" 0 login as user\n"); + printf(" -- set spy as default\n"); + printf(" 00 set user as default\n"); + printf(" ++ set manager as default\n"); + printf(" help show this help text\n"); + printf(" -a or a ask always for username/password, forget passwords\n"); + printf(" -s or s simulation mode (on some instruments)\n"); + printf(" -w or w do not skip welcome message\n"); + printf(" -h \"host\" connect to a SICServer on a different host\n"); + printf(" no option login with default privilege\n"); + printf("\n"); + printf(" Special commands treated by six (these are no SICS commands!)\n"); + printf("\n"); + printf(" quit exit six\n"); + printf(" exit exit six\n"); + printf(" stop interrupt SICS\n"); + printf(" + increase privilege\n"); + printf(" - decrease privilege\n"); + printf("\n"); + printf(" The SICS status is shown, if it is not 'Eager to execute commands'.\n"); + printf(" A shown status does not prohibit to enter commands.\n"); + printf("\n"); + printf(" Markus Zolliker, Oct. 2003\n"); + printf("\n"); +} int CocCreateSockAdr( struct sockaddr_in *sockaddrPtr, /* Socket address */ @@ -144,62 +185,280 @@ int sendCmd(int fd, char *cmd) { OnError: return -1; } -void Usage(void) { - printf(" Usage:\n\n"); - printf(" six [options] [\"username\" \"password\"]\n\n"); - printf(" Options: -s simulation mode (on some instruments)\n"); - printf(" -w do not skip welcome message\n\n"); +int scramble(char *buf) { + int i, n, cnt, chr, new; + int x; +/* Scrambles a string. Twice scramble gives original. + It does never convert a plain char to a ctrl char + and all standard ascii-codes to special chars and vice versa. + returns the number of special chars on output +*/ + + n=strlen(buf); + x=23; + cnt=0; + for (i=0; i 0) scramble(buf); +} + +putscrambled(char *buf, FILE *fil) { + char cvt[256]; + str_copy(cvt, buf); + scramble(cvt); + fprintf(fil, "%s\n", cvt); +} + +int setrights(int gotolevel) { + char user[32]; + char pswd[32]; + char *pw, *us, *p; + char prefhead[128], buf[128]; + FILE *fil; + int ask; + + us=""; + user[0]='\0'; + pw=pswd; + pswd[0]='\0'; + + p=getenv("HOME"); + if (p != NULL) str_copy(prefhead, p); + str_append(prefhead, "/.six."); + str_append(prefhead, instr); + str_append(prefhead, "."); + + if (0==strcmp(host, "0") && remember) { + fil=term_open_pref(prefhead, "r"); + if (fil != NULL) { + term_fgets(buf, sizeof(buf), fil); + getscrambled(user1, sizeof(user1), fil); + getscrambled(pswd1, sizeof(pswd1), fil); + getscrambled(user2, sizeof(user2), fil); + getscrambled(pswd2, sizeof(pswd2), fil); + fclose(fil); + } + if (deflevel==0) { + deflevel=buf[0]-'0'; + if (deflevel<1 || deflevel>3) deflevel=2; + } + } else { + deflevel=2; + } + if (NULL != strstr(instr, "TASP")) { + if (user1[0]=='\0') { + str_copy(user1,"Spy"); + str_copy(pswd1,"007"); + } + if (user2[0]=='\0') { + str_copy(user2,"Spy"); + str_copy(pswd2,"007"); + } + } + if (gotolevel==0) gotolevel=deflevel; + if (gotolevel==1) { + if (user1[0]=='\0') { + str_copy(user1, "lnsmanager"); + } + us=user1; + pw=pswd1; + } else if (gotolevel==2) { + if (user2[0]=='\0') { + str_copy(user2, instr); + str_lowcase(user2, user2); + str_append(user2, "user"); + } + us=user2; + pw=pswd2; + } else if (gotolevel==3) { + us="Spy"; + pw="007"; + } + ask=1; + if (us[0]!='\0' && pw[0]!='\0' && remember) { + sprintf(buf, "config rights %s %s", us, pw); + ERR_I(sendCmd(fd, buf)); + ERR_P(p=readWrite(fd,10000,0,"Acknowledged")); + if (*p=='\0') { + if (0==strcmp(us, user1)) { + user1[0]='\0'; + pswd1[0]='\0'; + } + if (0==strcmp(us, user2)) { + user2[0]='\0'; + pswd2[0]='\0'; + } + } else { + ask=0; + pw=NULL; + } + } + if (ask) { + printf("SICS username"); + if (us[0]!='\0') { + printf(" [%s]", us); + } + printf(": "); + term_fgets(user, sizeof(user), stdin); + if (0==strcmp(user, "quit")) return 1; + if (0==strcmp(user, "exit")) return 1; + if (user[0]=='\0') { + str_copy(user, us); + } + printf("password: "); + term_fgets(pswd, sizeof(pswd), stdin); + if (0==strcmp(pswd, "quit")) return 1; + if (0==strcmp(pswd, "exit")) return 1; + if (pswd[0]!='\0') { + sprintf(buf, "config rights %s %s", user, pswd); + ERR_I(sendCmd(fd, buf)); + ERR_P(p=readWrite(fd,10000,0,"Acknowledged")); + if (*p=='\0') { + gotolevel=3; + if (0==strcmp(user, user1)) { + user1[0]='\0'; + pswd1[0]='\0'; + } + if (0==strcmp(user, user2)) { + user2[0]='\0'; + pswd2[0]='\0'; + } + pw=NULL; + } else { + if (0==strcmp(user, user1)) { + str_copy(pswd1, pswd); + } + if (0==strcmp(user, user2)) { + str_copy(pswd2, pswd); + } + us=user; + pw=pswd; + } + } else { + gotolevel=3; + } + } + level=gotolevel; + ERR_I(sendCmd(fd, "config list")); + ERR_P(p=readWrite(fd,10000,1,"UserRights = ")); + if (p!=NULL) { + level=*p-'0'; + } + if (level==3) { + us="Spy"; + } + if (pw!=NULL) { + if (level==1) { + str_copy(user1, us); + str_copy(pswd1, pw); + if (0==strcmp(user1, user2)) { + user2[0]='\0'; + pswd2[0]='\0'; + } + } else if (level==2) { + str_copy(user2, us); + str_copy(pswd2, pw); + if (0==strcmp(user2, user1)) { + user1[0]='\0'; + pswd1[0]='\0'; + } + } + } + if (0==strcmp(host, "0")) { + fil=term_open_pref(prefhead, "w"); + if (fil!=NULL) { + fprintf(fil, "%d\n", deflevel); + if (remember) { + putscrambled(user1, fil); + putscrambled(pswd1, fil); + putscrambled(user2, fil); + putscrambled(pswd2, fil); + } + fclose(fil); + } + } + return 0; + OnError: return -1; } int main (int argc, char *argv[]) { int iret, pos; fd_set mask; - int fd, l, i, j, port, skip; - char buf[128], lbuf[16], ibuf[64], ilow[64]; - char stdPrompt[128], prompt[256], instr[32]; - char *rights, *sim="", *us, *ps; + int l, i, j, port, skip, gotolevel; + char buf[128], lbuf[16], ilow[64]; + char stdPrompt[128], prompt[256]; + char *sim=""; char *p, *statusMatch; + char *pnam[4]={"0", "MANAGER", "user", "spy"}; struct sockaddr_in sadr; + printf("---------------------------------------------------\n"); + printf("six, a fast SICS commandline client (doc: six help)\n"); + printf("---------------------------------------------------\n"); port=1301; skip=1; j=0; + deflevel=0; + gotolevel=0; + host="0"; /* localhost by default */ for (i=1; i=argc) { + printf("missing host\n"); + Usage(); return 0; + } + host=argv[i]; } else { if (strlen(argv[i])>=32) { printf("argument too long\n"); Usage(); return 0; + } else if (argv[i][0]!='-') { + if (j==0) { + printf("syntax has changed, username can not be given as argument\n"); + Usage(); j=1; + } } else { - if (j==0) { - us=argv[i]; - j=1; - } else if (j==1) { - ps=argv[i]; - j=2; - } else { - printf("too many arguments\n"); - Usage(); return 0; - } + printf("unknown option: %s\n", argv[i]); + Usage(); return 0; } } } - if (j==1) { - printf("missing password\n"); - Usage(); return 0; - } -/* - instr=getenv("Instrument"); - if (instr==NULL || instr[0]=='\0') { - printf("Instrument is undefined\n"); - Usage(); return 0; - } -*/ - ERR_I(CocCreateSockAdr(&sadr, "0", port)); + ERR_I(CocCreateSockAdr(&sadr, host, port)); ERR_SI(fd=socket(AF_INET, SOCK_STREAM, 0)); term_reg_socket(fd); ERR_SI(connect(fd, (struct sockaddr *)&sadr, sizeof(sadr))); @@ -211,6 +470,9 @@ int main (int argc, char *argv[]) { } if (skip) printf("reading welcome message ...\n"); + ERR_I(sendCmd(fd, "status interest")); + ERR_P(readWrite(fd,10000,0,"OK")); + ERR_I(sendCmd(fd, "Instrument")); ERR_P(p=readWrite(fd,10000,0,"Instrument = ")); str_copy(instr, p); @@ -218,44 +480,27 @@ int main (int argc, char *argv[]) { printf("can not detect instrument\n"); return 0; } - if (j==0) { - rights=getenv("six_rights"); - if (rights!=NULL && 0==strcmp(rights, instr)) { - us="lnsmanager"; - ps="lnsSICSlns"; - } else { - sprintf(ibuf, "%suser", instr); - str_lowcase(ibuf, ibuf); - us=ibuf; - ps="03lns1"; - } + p=strchr(instr,' '); + if (p!=NULL) *p='\0'; + if (0==strcmp(instr,"SANS-II")) { + str_copy(instr, "SANS2"); } - if (NULL == strstr(instr, "TASP")) { - sprintf(buf, "config Rights %s %s", us, ps); - ERR_I(sendCmd(fd, buf)); - ERR_P(p=readWrite(fd,10000,0,"Acknowledged")); - if (*p=='\0') { - printf("password guess failed, logged in as Spy\n\n"); - Usage(); - us="Spy"; - } - } else { - us="Spy"; - } - printf("\rlogged in to SICS as %s on %s\n", us, instr); + ERR_I(i=setrights(gotolevel)); + if (i==1) return 0; + printf("\rlogged in to SICS as %s on %s\n", pnam[level], instr); str_lowcase(ilow,instr); sprintf(stdPrompt, "six[%s] ", ilow); - ERR_I(sendCmd(fd, "status interest")); - ERR_P(readWrite(fd,10000,0,"OK")); ERR_I(sendCmd(fd, "status")); ERR_P(p=readWrite(fd,10000,0,"status = ")); - + iret=1; buf[0]='\0'; pos=0; + term_read_hist("six"); + while (1) { if (*p=='E') { /* Eager to ... */ strcpy(prompt, stdPrompt); @@ -270,14 +515,40 @@ int main (int argc, char *argv[]) { if (0==strcmp(lbuf,"quit")) break; if (0==strcmp(lbuf,"exit")) break; statusMatch="status = "; + skip=0; + printf("\n"); if (0==strcmp(lbuf,"stop")) { strcpy(buf, "INT1712 3"); + } else if (0==strcmp(buf, "-") || + 0==strcmp(buf, "--") || + 0==strcmp(buf, "+") || + 0==strcmp(buf, "++")) { + j=level; + if (buf[0]=='-') { + if (level<3) level++; + } else { + if (level>1) level--; + } + if (strlen(buf)==2) { + deflevel=level; + } + term_off(); + ERR_I(i=setrights(level)); /* level might be changed */ + if (i==1) return 0; + if (j!=level) { + printf("\rswitched to %s privilege\n", pnam[level]); + } else { + printf("\rremain at %s privilege\n", pnam[level]); + } + skip=1; + strcpy(buf, "status"); + } else if (0==strcmp(buf, "six help")) { + Usage(); + strcpy(buf, "status"); } else if (0==strcmp(buf, "")) { strcpy(buf, "status"); statusMatch=NULL; } - fputs("\n", stdout); - skip=0; ERR_I(sendCmd(fd, buf)); ERR_P(p=readWrite(fd,1000,skip,statusMatch)); @@ -291,6 +562,7 @@ int main (int argc, char *argv[]) { } } fputs("\n", stdout); + term_save_hist(1); /* save history wihtout last line */ return 0; Usage: return 0; diff --git a/tecs/sys_select.c b/tecs/sys_select.c index 6f9e87d..5c81698 100644 --- a/tecs/sys_select.c +++ b/tecs/sys_select.c @@ -5,38 +5,41 @@ static int lastFd=-1; static struct termios atts; +static echo=1; void sys_keys_on(void) { int iret; struct termios attr; - iret=tcgetattr(STDIN_FILENO,&attr); - atts=attr; /* save term. attr. */ - if (iret!=0) { perror("***\n");} - attr.c_lflag &= ~(ICANON) & ~(ECHO); /* canonical mode off, echo off */ - attr.c_cc[VMIN]=0; - attr.c_cc[VTIME]=1; /* 0.1 sec */ - iret= tcsetattr(STDIN_FILENO,TCSANOW,&attr); - if (iret!=0) {perror("***\n");} + if (echo) { + iret=tcgetattr(STDIN_FILENO,&attr); + atts=attr; /* save term. attr. */ + if (iret!=0) { perror("***\n");} + attr.c_lflag &= ~(ICANON) & ~(ECHO); /* canonical mode off, echo off */ + attr.c_cc[VMIN]=0; + attr.c_cc[VTIME]=1; /* 0.1 sec */ + iret= tcsetattr(STDIN_FILENO,TCSANOW,&attr); + if (iret!=0) {perror("***\n");} + echo=0; + } } void sys_keys_off(void) { int iret; - - iret=tcsetattr(STDIN_FILENO,TCSANOW,&atts); /* restore term. attributes */ - if (iret!=0) {perror("***\n");}; + + if (!echo) { + iret=tcsetattr(STDIN_FILENO,TCSANOW,&atts); /* restore term. attributes */ + if (iret!=0) {perror("***\n");}; + echo=1; + } } int sys_select_or_key(fd_set *mask, int msecTmo, char *key) { int chan, fd, iret, fd1, m, chr; struct timeval tmo, tmo0={0,0}; fd_set rmask; - static int init=1; - if (init) { - sys_keys_on(); - init=0; - } + sys_keys_on(); rmask=*mask; iret=select(FD_SETSIZE, &rmask, NULL, NULL, &tmo0); if (iret<0) { @@ -84,8 +87,5 @@ int sys_select_or_key(fd_set *mask, int msecTmo, char *key) { } *mask=rmask; *key=chr; - /* - sys_keys_off(); - */ return(fd1); } diff --git a/tecs/sys_select.h b/tecs/sys_select.h index ac18468..645532b 100644 --- a/tecs/sys_select.h +++ b/tecs/sys_select.h @@ -4,11 +4,17 @@ #include int sys_select_or_key(fd_set *mask, int msecTmo, char *key); - -/* wait for read event on sockets included in mask or from keyboard or a timeout +/* + wait for read event on sockets included in mask or from keyboard or a timeout result is negative for timeout, STDIN_FILENO for a key pressed, else socket number + switches the terminal to no-echo no-canonical +*/ + +void sys_keys_off(void); +/* + switch back terminal to normal state */ #endif /* SYS_SELECT_H_ */ diff --git a/tecs/tecs.c b/tecs/tecs.c index b823a98..5dc8884 100644 --- a/tecs/tecs.c +++ b/tecs/tecs.c @@ -283,6 +283,7 @@ int InstalCurve(SensorT *sensor, char *dev) { sens=sensor; str_copy(chan, sens->ch); + ERR_P(LscCmd(ser, "FILTER [chan]:1,64,10")); sens->present=0; if (sens->type=='x' || sens->type=='h' || sens->type=='f') { if (chan[0]>='C') { diff --git a/tecs/term.c b/tecs/term.c index ccad309..2bc761f 100644 --- a/tecs/term.c +++ b/tecs/term.c @@ -4,8 +4,9 @@ #include #include #include -#include +#include "term.h" #include "myc_mem.h" +#include "myc_str.h" #include "sys_select.h" #define ESC_TMO 1000 @@ -138,7 +139,110 @@ static char *history[HISTORY_LINES]={NULL}; static int hist_pos=0; /* position when scrolling through the history */ static int hist_end=0; /* end of history. Always history[hist_end]==NULL */ -static int dirty=0; /* line is to be cleared through a call of term_clear_line */ +static char filehead[256]=""; + +FILE *term_open_pref(char *head, char *mode) { + char buf[PATH_MAX], hom[PATH_MAX]; + char *cret, *home, usr[256]; + int i; + + cret=getenv("USER"); + if (cret == NULL || *cret == '\0') return NULL; + str_copy(usr, cret); + if (strcmp(usr, "lnsg") == 0) { /* special case lnsg */ + cret=getcwd(buf, sizeof(buf)); + if (cret == NULL) return NULL; + home=getenv("HOME"); + realpath(home, hom); + cret=strstr(buf,hom); + if (cret == buf) { /* cwd starts with HOME, take subdirectory as usr */ + cret+=strlen(hom)+1; + str_copy(usr, "lnsg_"); + str_append(usr, cret); + cret=strchr(usr, '/'); + if (cret != NULL) *cret='\0'; + } + } + /* usr is now the username, or lnsg_ */ + + str_copy(buf, head); + str_append(buf, usr); + return fopen(buf, mode); +} + +char *term_fgets(char *buf, int size, FILE *fil) { + char *p, *ret; + char skipbuf[256]; + + buf[0]='\0'; + ret=fgets(buf, size, fil); + if (ret==NULL) { + return NULL; + } + p=strchr(buf,'\n'); + if (p==NULL) { + while (p==NULL) { /* skip rest of line */ + ret=fgets(skipbuf, sizeof(skipbuf), fil); + if (ret==NULL) { + return NULL; + } + p=strchr(skipbuf,'\n'); + } + } else { + *p='\0'; + } + return ret; +} + +void term_save_hist(int +trimlast) { + FILE *fil; + int i,n; + if (filehead[0]=='\0') return; + fil=term_open_pref(filehead, "w"); + if (fil==NULL) return; + n=HISTORY_LINES-1; + if (trimlast) { + n--; + } + i=hist_end; + while (n>0) { + n--; + i++; if (i>=HISTORY_LINES) i=0; + if (history[i]!=NULL) { + fputs(history[i], fil); fputs("\n", fil); + } + } + fclose(fil); +} + +void term_read_hist(char *id) { + FILE *fil; + int i; + char buf[1024], *lin; + + str_copy(filehead, "/tmp/"); + str_append(filehead, id); + str_append(filehead, "_hist."); + fil=term_open_pref(filehead, "r"); + if (fil==NULL) return; + hist_end=0; + while (hist_end0) { + lin=MALLOC(i+1); + strncpy(lin, buf, i+1); + history[hist_end]=lin; + hist_end++; + } + } + fclose(fil); + history[hist_end]=NULL; + hist_pos=hist_end; +} + +static int dirty=0; /* line is to be cleared through a call of term_clear */ void term_clear(void) { if (dirty) { @@ -147,10 +251,17 @@ void term_clear(void) { } } +void term_off(void) { + dirty=1; + term_clear(); + sys_keys_off(); +} + int term_get_line(char *buf, int size, int *pos, char *prompt, fd_set *mask) { char key, *lin; int i,j,l,iret,buflen; char tmp[512]; + static int init=1; buf[size-1]='\0'; /* make sure buf is null terminated */ l=strlen(buf); @@ -200,6 +311,7 @@ int term_get_line(char *buf, int size, int *pos, char *prompt, fd_set *mask) { history[hist_end]==NULL; } hist_pos=hist_end; + term_save_hist(0); return(STDIN_FILENO); /* normal EXIT */ @@ -232,8 +344,14 @@ int term_get_line(char *buf, int size, int *pos, char *prompt, fd_set *mask) { buf[size-1]='\0'; hist_pos=i; l=strlen(buf); - *pos=l; + } else { + buf[0]='\0'; + l=0; + if (history[hist_pos]!=NULL) { + hist_pos=i; + } } + *pos=l; break; default: if (l + void term_reg_socket(int fd); /* register socket */ @@ -18,4 +20,18 @@ void term_clear(void); int term_get_line(char *buf, int size, int *pos, char *prompt, fd_set *mask); +FILE *term_open_pref(char *head, char *mode); +/* open a user specific preferences file */ + +char *term_fgets(char *buf, int size, FILE *fil); +/* fgets without newline */ + +void term_read_hist(char *id); +/* read history from temporary file with id */ + +void term_save_hist(int trimlast); +/* store history (without last line if trimlast) */ + +void term_off(void); + #endif /* TERM_H_ */