new six version M.Z.
This commit is contained in:
400
tecs/six.c
400
tecs/six.c
@ -6,11 +6,52 @@
|
||||
#include <netdb.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#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<n; i++) {
|
||||
chr=(buf[i] & 255) ^ (x % 32 + 128);
|
||||
if (chr & 128) cnt++;
|
||||
x=(x*13+5) % 256;
|
||||
buf[i]=chr;
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
getscrambled(char *buf, int size, FILE *fil) {
|
||||
term_fgets(buf, size, fil);
|
||||
if (scramble(buf) > 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; i++) {
|
||||
if (0==strcmp(argv[i], "-s")) {
|
||||
if (0==strcmp(argv[i], "-s") || 0==strcmp(argv[i], "s")) {
|
||||
port=1303; sim="-sim";
|
||||
} else if (0==strcmp(argv[i], "-w")) {
|
||||
} else if (0==strcmp(argv[i], "-w") || 0==strcmp(argv[i], "w")) {
|
||||
skip=0;
|
||||
} else if (0==strcmp(argv[i], "-a") || 0==strcmp(argv[i], "a")) {
|
||||
remember=0;
|
||||
} else if (0==strcmp(argv[i], "+")) {
|
||||
gotolevel=1;
|
||||
} else if (0==strcmp(argv[i], "-")) {
|
||||
gotolevel=3;
|
||||
} else if (0==strcmp(argv[i], "0")) {
|
||||
gotolevel=2;
|
||||
} else if (0==strcmp(argv[i], "++")) {
|
||||
gotolevel=1;
|
||||
deflevel=1;
|
||||
} else if (0==strcmp(argv[i], "--")) {
|
||||
gotolevel=3;
|
||||
deflevel=3;
|
||||
} else if (0==strcmp(argv[i], "00")) {
|
||||
gotolevel=2;
|
||||
deflevel=2;
|
||||
} else if (0==strcmp(argv[i], "help")) {
|
||||
Usage();
|
||||
return 0;
|
||||
} else if (0==strcmp(argv[i], "-h")) {
|
||||
i++;
|
||||
if (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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -4,11 +4,17 @@
|
||||
#include <sys/time.h>
|
||||
|
||||
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_ */
|
||||
|
@ -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') {
|
||||
|
124
tecs/term.c
124
tecs/term.c
@ -4,8 +4,9 @@
|
||||
#include <sys/time.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#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_<subdirectory> */
|
||||
|
||||
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_end<HISTORY_LINES-1 && !feof(fil)) {
|
||||
term_fgets(buf, sizeof(buf), fil);
|
||||
i=strlen(buf);
|
||||
if (i>0) {
|
||||
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<size-1) {
|
||||
|
16
tecs/term.h
16
tecs/term.h
@ -1,6 +1,8 @@
|
||||
#ifndef TERM_H_
|
||||
#define TERM_H_
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
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_ */
|
||||
|
Reference in New Issue
Block a user