275 lines
6.5 KiB
C
Executable File
275 lines
6.5 KiB
C
Executable File
#include <sys/stat.h>
|
|
#include <sys/types.h>
|
|
#include <termios.h>
|
|
#include <unistd.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <time.h>
|
|
#include <utmp.h>
|
|
#include "myc_tmp.h"
|
|
#include "myc_str.h"
|
|
#include "sys_util.h"
|
|
|
|
#define ENAM_LEN 128
|
|
#define EVAL_LEN 1024
|
|
|
|
void usleep_(int *usec) { usleep(*usec); }
|
|
int getppid_(void) { return getppid(); }
|
|
int lnblnk_(const char *str, int len);
|
|
#ifdef __alpha
|
|
int setenv(char *p1, char *p2, int ow);
|
|
#endif
|
|
|
|
typedef struct _EnvList { struct _EnvList *next; char *name; char *value; } EnvList;
|
|
static EnvList *envlist;
|
|
static char tmpfil[128];
|
|
static char senv_id[16];
|
|
static char *empty="";
|
|
static int loaded=0;
|
|
static int dirty=0;
|
|
|
|
EnvList *sys_findenv(char *name) {
|
|
EnvList *p;
|
|
for (p=envlist; p!=NULL; p=p->next) {
|
|
if (0==strcmp(name, p->name)) {
|
|
return p;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void F_FUN(sys_check_system)(F_CHAR(code) F_CLEN(code)) {
|
|
#if defined __alpha
|
|
STR_TO_F(code, "TRU64");
|
|
#elif defined __GNUC__
|
|
STR_TO_F(code, "GNU");
|
|
#elif defined __INTEL_COMPILER
|
|
STR_TO_F(code, "IFORT");
|
|
#else
|
|
"sys_check_system: unsupported machine"
|
|
#endif
|
|
}
|
|
|
|
int F_FUN(sys_loadenv)(void) {
|
|
FILE *fil;
|
|
char buf[ENAM_LEN+EVAL_LEN+10];
|
|
char old[EVAL_LEN], userid[32];
|
|
char *nam, *val, *pold, *u, *ret, *v;
|
|
int l;
|
|
EnvList *p;
|
|
|
|
if (!loaded) {
|
|
loaded=-1; /* assume failure */
|
|
/* u=cuserid(userid); */
|
|
u=getenv("USER");
|
|
if (u==NULL) {
|
|
strcpy(userid, "Anonymous");
|
|
} else {
|
|
strncpy(userid, u, sizeof(userid));
|
|
}
|
|
val=getenv("senv_id");
|
|
if (val==NULL) {
|
|
sprintf(senv_id, "%d", getppid());
|
|
} else {
|
|
strcpy(senv_id, val);
|
|
}
|
|
|
|
sprintf(tmpfil, "%s/.senv_%s.%s",TEMP_PATH, userid, senv_id);
|
|
fil=fopen(tmpfil, "r");
|
|
|
|
if (fil==NULL) {
|
|
loaded=1;
|
|
return 1;
|
|
}
|
|
while (1) {
|
|
|
|
ret=fgets(buf, sizeof(buf), fil);
|
|
if (!ret || buf[0]=='#') break;
|
|
l=strlen(buf);
|
|
if (l<10 || buf[l-1]!='\n') return -1;
|
|
buf[l-1]='\0';
|
|
buf[6]='\0';
|
|
if (0!=strcmp(buf, "setenv")) return -1;
|
|
nam=buf+7;
|
|
val=strchr(nam, ' ');
|
|
if (val==NULL) return -1;
|
|
*val='\0'; val++;
|
|
if (*val=='"') {
|
|
if (buf[l-2]!='"') return -1;
|
|
buf[l-2]='\0';
|
|
val++;
|
|
}
|
|
|
|
ret=fgets(old, sizeof(old), fil);
|
|
if (!ret) break;
|
|
l=strlen(old);
|
|
if (l==0 || old[0]!='#' || old[l-1]!='\n') return -1;
|
|
old[l-1]='\0';
|
|
pold=old+1;
|
|
|
|
v=getenv(nam);
|
|
if (v==NULL) v=empty;
|
|
if (0==strcmp(v,pold)) { /* take value from file only if env. variable not changed in the meantime */
|
|
p = malloc(sizeof(*p)); if (p == NULL) goto senv;
|
|
if (NULL==(p->name = strdup(nam))) goto senv;
|
|
if (NULL==(p->value = strdup(v))) goto senv;
|
|
p->next = envlist;
|
|
envlist=p;
|
|
senv:
|
|
setenv(nam, val, 1);
|
|
}
|
|
}
|
|
if (0>fclose(fil)) return -1;
|
|
loaded=1;
|
|
}
|
|
return loaded;
|
|
}
|
|
|
|
int F_FUN(sys_setenv)(char *enam, char *eval, int snam, int sval) {
|
|
int lnam, lval;
|
|
char *v, nam[ENAM_LEN], val[EVAL_LEN];
|
|
EnvList *p=NULL;
|
|
|
|
lnam = lnblnk_(enam,snam);
|
|
if (lnam>=sizeof(nam)) lnam=sizeof(nam)-1;
|
|
strncpy(nam,enam,lnam); nam[lnam] = '\0';
|
|
|
|
lval = lnblnk_(eval,sval);
|
|
if (lval>=sizeof(val)) lval=sizeof(val)-1;
|
|
strncpy(val,eval,lval); val[lval] = '\0';
|
|
|
|
if (loaded>0) {
|
|
v=getenv(nam);
|
|
if (v == NULL) v=empty;
|
|
if (!dirty) {
|
|
dirty = 0 != strcmp(val,v);
|
|
}
|
|
p=sys_findenv(nam);
|
|
if (p==NULL) {
|
|
p = malloc(sizeof(*p)); if (p == NULL) goto senv;
|
|
if (NULL==(p->name = strdup(nam))) goto senv;
|
|
if (NULL==(p->value = strdup(v))) goto senv;
|
|
p->next = envlist;
|
|
envlist=p;
|
|
}
|
|
}
|
|
senv:
|
|
return setenv(nam, val, 1);
|
|
}
|
|
|
|
int F_FUN(sys_saveenv)(void) {
|
|
FILE *fil;
|
|
char *v;
|
|
EnvList *p;
|
|
|
|
if (F_FUN(sys_loadenv)()<0 || !dirty) return loaded;
|
|
|
|
fil=fopen(tmpfil, "w");
|
|
if (fil==NULL) return -1;
|
|
|
|
for (p=envlist; p!=NULL; p=p->next) {
|
|
v=getenv(p->name);
|
|
if (0!=strcmp(v, p->value)) {
|
|
if (0>fputs("setenv ", fil)) return -1;
|
|
if (0>fputs(p->name, fil)) return -1;
|
|
if (0>fputs(" \"", fil)) return -1;
|
|
if (0>fputs(v, fil)) return -1;
|
|
if (0>fputs("\"\n#", fil)) return -1;
|
|
if (0>fputs(p->value, fil)) return -1;
|
|
if (0>fputs("\n", fil)) return -1;
|
|
}
|
|
}
|
|
if (0>fputs("#\nif ($$ == ", fil)) return -1;
|
|
if (0>fputs(senv_id, fil)) return -1;
|
|
if (0>fputs(") then\n /bin/rm ", fil)) return -1;
|
|
if (0>fputs(tmpfil, fil)) return -1;
|
|
/*
|
|
if (0>fputs("\n echo \"#\" > ", fil)) return -1;
|
|
if (0>fputs(tmpfil, fil)) return -1;
|
|
*/
|
|
if (0>fputs("\nendif\n", fil)) return -1;
|
|
if (0>fclose(fil)) return -1;
|
|
dirty=0;
|
|
return 0;
|
|
}
|
|
|
|
struct termios atts;
|
|
|
|
void F_FUN(sys_rd_tmo)(char *prompt, char *result, int *reslen, int p_len, int r_len) {
|
|
struct termios attr;
|
|
int ires, i, ntmo, chr;
|
|
|
|
ires=tcgetattr(STDIN_FILENO,&attr);
|
|
atts=attr; /* save term. attr. */
|
|
if (ires!=0) {
|
|
perror("error in terinq/tcgetattr ");
|
|
(*reslen)=0;
|
|
*result='\0';
|
|
return;
|
|
}
|
|
attr.c_lflag &= ~(ICANON) & ~(ECHO); /* canonical mode off, echo off */
|
|
attr.c_cc[VMIN]=0;
|
|
ires= tcsetattr(STDIN_FILENO,TCSANOW,&attr);
|
|
if (ires!=0) {perror("error in terinq/tcsetattr ");}
|
|
|
|
do { chr=fgetc(stdin); } while (chr!=EOF);
|
|
|
|
for (i=0; i<p_len; i++)
|
|
{ fputc(prompt[i], stderr);
|
|
};
|
|
|
|
ires=fflush(stdin);
|
|
ires=fflush(stderr);
|
|
|
|
*reslen=0;
|
|
if (prompt[0]=='\0') { ntmo=10; }
|
|
else { ntmo=200; }; /* wait 2 sec. for the first char */
|
|
while (*reslen<r_len)
|
|
{ chr=fgetc(stdin);
|
|
if (chr==EOF)
|
|
{ while ((chr==EOF) & (ntmo>0))
|
|
{ usleep(10000); /* wait 10 ms */
|
|
chr=fgetc(stdin);
|
|
ntmo--;
|
|
};
|
|
if (chr==EOF) break;
|
|
if (chr==10) {ntmo=10;} else {ntmo=100;}; /* wait 0.1 sec after LF, 1 sec else */
|
|
};
|
|
result[(*reslen)++]=(char)chr;
|
|
if (chr==24) {(*reslen)=0;}; /* ctrl-X purges buffer */
|
|
};
|
|
if (result[(*reslen)-1]==10) {(*reslen)--;}; /* strip trailing LF */
|
|
|
|
ires=tcsetattr(STDIN_FILENO,TCSANOW,&atts); /* restore term. attributes */
|
|
clearerr(stdin);
|
|
if (ires!=0) {
|
|
perror("error in terinq/tcsetattr ");
|
|
}
|
|
}
|
|
|
|
|
|
int mkdir_(const char *path, int p_len) {
|
|
int i;
|
|
char *p;
|
|
|
|
i = lnblnk_(path,p_len);
|
|
p = malloc((unsigned) i+1); if( p == NULL ) return (-1);
|
|
strncpy(p,path,i); p[i] = '\0';
|
|
i = mkdir(p, 0777);
|
|
free(p);
|
|
return(i);
|
|
}
|
|
|
|
|
|
void F_FUN(sys_cmd)(char *command, int clen) {
|
|
int rc, l;
|
|
char *p;
|
|
|
|
l = lnblnk_(command, clen);
|
|
p = malloc((unsigned) l+1); if( p == NULL ) return;
|
|
strncpy(p,command,l); p[l] = '\0';
|
|
rc = system(p);
|
|
free(p);
|
|
}
|