/* Copyright (C) 1995 EGLE Magic, New Zealand, All rights reserved. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "emsg.h" #include "lib.h" #define false 0 #define true (!false) typedef struct {unsigned short len; unsigned char type, class; char *ptr;} Str; #define DEFSTR(NAME,BUFF,LEN) Str NAME = {LEN, DSC$K_DTYPE_T, DSC$K_CLASS_S, BUFF} #define DEFSTR1(NAME,XX,YY) Str NAME #define DEFSTR2(NAME,BUFF,LEN) NAME.len = LEN, NAME.type = DSC$K_DTYPE_T,NAME.class = DSC$K_CLASS_S, NAME.ptr = BUFF #define DEFSTRV(NAME,BUFF,LEN) Str NAME = {LEN, DSC$K_DTYPE_T, DSC$K_CLASS_VS, BUFF} char *lib_logical(char *logical_name); void lib_nowrap(void); void lib_spawn(char *s); void vmessage(int r); char *lib_message(int r); int lib_keypad(void); void lib_createdir(char *s) { char bf[80]; int r; DEFSTR1(v,bf,0); DEFSTR2(v,bf,0); strcpy(bf,s); s = strchr(bf,']'); if (s != NULL) *(s+1) = 0; else { s = strchr(bf,':'); if (s != NULL) *(s+1) = 0; } v.len = strlen(bf); r = LIB$CREATE_DIR(&v); if (r != 1) dmsg("createdir,{%s} %s\n",bf,lib_message(r)); dmsg("createdir,{%s} %s\n",bf,lib_message(r)); } void lib_symbol_set(char *name, char *value) { int r; DEFSTR1(namstr,name,strlen(name)); DEFSTR1(valuestr,value,strlen(value)); DEFSTR2(namstr,name,strlen(name)); DEFSTR2(valuestr,value,strlen(value)); r = lib$set_symbol(&namstr,&valuestr,&2); if (r!=1) lib$signal(r); } char *get_symbol(char *sym); void lib_symbol_get(char *name, char *result) { strcpy(result,get_symbol(name)); } char *get_symbol(char *sym) { static char mystr[200],*s; int r; short teklen=80; int stype=1; DEFSTR1(symname,sym,strlen(sym)); DEFSTR1(tekval,mystr,80); DEFSTR2(symname,sym,strlen(sym)); DEFSTR2(tekval,mystr,80); mystr[0] = 0; /* symname.dsc$w_length = strlen(sym); tekval.dsc$w_length = 80; */ r = lib$get_symbol(&symname,&tekval,&teklen,&stype); if (r!=1) { /* (r!=1409892) lib$signal(r); */ teklen = 0; } mystr[teklen] = 0; return mystr; } /* The translog function attempts to find a translation for a logical name in a specific name_table. The syntax of the translog function is as follows: char * translog(char *table, char *logical_name) Additional information The translog function returns a char * to the translation if it is successfully completed otherwise it returns a char * pointing to a null byte. */ /* #include stdio #include ssdef #include descrip #include lnmdef #include syidef */ typedef struct { /* Item_list_3 */ unsigned short int Size; /* Item Buffer Size */ unsigned short int Type; /* Item Type (below)*/ char *Buffer; /* Buffer Pointer */ int *Resultant_Size; /* Final Size Ptr */ } item_list; char *sys_logical(char *table,char *logical_name); char *lib_logical(char *logical_name) { static char bf[255],*s; DEFSTR1(logical,logical_name,strlen(logical_name)); DEFSTR1(result,bf,254); DEFSTR2(logical,logical_name,strlen(logical_name)); DEFSTR2(result,bf,254); memset(bf,0,250); lib$sys_trnlog(&logical,0,&result); bf[result.len] = 0; s = strstr(bf," "); if (s!=NULL) *s = 0; return bf; } char *sys_logical(char *table,char *logical_name) { item_list item; /* descriptors to interface */ /* C nullterminated strings */ /* to VMS string-format */ struct dsc$descriptor log_nam_des, /* descriptor for logical_name*/ table_des; /* descriptor for table */ int ret, /* return value of sys$trnlnm */ len = 0, /* Resulting length of translation */ attr = 0; /* Attributes for sys$trnlnm */ char translation[256], null_str = '\0', msg[256]; item.Size = 255; /* Maximum length of a logical name */ item.Type = LNM$_STRING; /* The item list describes a string */ item.Buffer = translation; /* Ptr to the result string */ item.Resultant_Size = &len; /* Ptr to the resulting length */ log_nam_des.dsc$w_length = strlen(logical_name); log_nam_des.dsc$b_dtype = DSC$K_DTYPE_Z; log_nam_des.dsc$b_class = DSC$K_CLASS_S; log_nam_des.dsc$a_pointer = logical_name; table_des.dsc$w_length = strlen(table); table_des.dsc$b_dtype = DSC$K_DTYPE_Z; table_des.dsc$b_class = DSC$K_CLASS_S; table_des.dsc$a_pointer = table; /* system call that makes the translation */ ret = sys$trnlnm(&attr,&table_des,&log_nam_des,0,&item); if(ret != SS$_NORMAL) { return(&null_str); } else { translation[len] = '\0'; return(translation); } } char *lib_username(int *pid) { int r; int rvalue,rlen=0; char *s; static char bf[40]; DEFSTR1(rstr,bf,39); DEFSTR2(rstr,bf,39); r = lib$getjpi(&JPI$_USERNAME,pid,NULL,&rvalue,&rstr,&rlen); if (r != 1) lib$signal(r) ; bf[rlen] = 0; s = strstr(bf," "); if (s!=NULL) *s = 0; return bf; } /* s = time in 100/s of seconds */ void lib_sleep(int s) { int mask,r; int btime[2]; char bf[10]; static int efn; DEFSTR1(bfstr,bf,9); DEFSTR2(bfstr,bf,9); sprintf(bf,"0 ::00.%02d",s); r = sys$bintim(&bfstr, &btime); if (r != 1) lib$signal(r); if (efn==0) r = lib$get_ef(&efn); if (r != 1) lib$signal(r); r = sys$clref(efn); if ((r&1) != 1) lib$signal(r); r = sys$setimr(efn,&btime,NULL,NULL); if (r != 1) lib$signal(r); mask = efn; if (mask>31) mask -= 32; mask = 1 << mask; s = sys$wflor(efn,mask); if (r != 1) lib$signal(r); } char *lib_message(int r) { char bf[200]; int bflen=0; DEFSTR1(bfstr,bf,199); DEFSTR2(bfstr,bf,199); SYS$GETMSG(r,&bflen,&bfstr,15,0); bf[bflen] = 0; return bf; } extern int lib$put_output(); extern int lib$get_input(); static int do_keypad = false; /* s1% = sys$getmsg(s% by value,msglen%,msg$,15% by value,) */ static int tt_chan; static short tt_iosb[4]; void tt_open(void) { int st; static $DESCRIPTOR(tt_desc,"tt"); st = SYS$ASSIGN(&tt_desc,&tt_chan,0,0); lib_nowrap(); } void lib_puts(char *s) { int write_mask,st; if (tt_chan==0) tt_open(); write_mask = IO$_WRITELBLK | IO$M_NOFILTR; st = SYS$QIOW(0,tt_chan,write_mask ,tt_iosb,0,0 ,s,strlen(s),0,0,0,0); if ((st & 1) != 1) lib$signal(st); st = tt_iosb[0]; if ((st & 1) != 1) lib$signal(st); } typedef struct {char class, type; short bsize; long code;} TTCHAR; TTCHAR tt_save_char; void lib_nowrap(void) { int write_mask,st; TTCHAR buff; if (tt_chan==0) tt_open(); st = SYS$QIOW(0,tt_chan,IO$_SENSEMODE ,tt_iosb,0,0 ,&buff,8,0,0,0,0); if ((st & 1) != 1) lib$signal(st); tt_save_char = buff; buff.code = buff.code & ~TT$M_WRAP; st = SYS$QIOW(0,tt_chan,IO$_SETMODE ,tt_iosb,0,0 ,&buff,8,0,0,0,0); if ((st & 1) != 1) lib$signal(st); } void lib_ttrestore(void) { int st; if (tt_chan==0) return; st = SYS$QIOW(0,tt_chan,IO$_SETMODE ,tt_iosb,0,0 ,&tt_save_char,8,0,0,0,0); if ((st & 1) != 1) lib$signal(st); } int lib_cputime(void) { int r; int pid=0; int rvalue,rlen=0; char *s; static char bf[40]; DEFSTR1(rstr,bf,39); DEFSTR2(rstr,bf,39); r = lib$getjpi(&JPI$_CPUTIM,&pid,NULL,&rvalue,&rstr,&rlen); if (r != 1) lib$signal(r) ; return rvalue; } char *lib_procname(void) { int r; int rvalue,rlen=0; char *s; static char bf[40]; DEFSTR1(rstr,bf,39); DEFSTR2(rstr,bf,39); r = lib$getjpi(&JPI$_PRCNAM,NULL,NULL,&rvalue,&rstr,&rlen); if (r != 1) lib$signal(r) ; bf[rlen] = 0; return bf; } struct {long forward; void (*fn)(void); int narg; int *pstatus; int fill2[4]; } exit_block; /* this routine doesn't work, used atexit instead */ void lib_atexit(void (*exit_fn)(void) ) { int r; static int status; exit_block.narg = 1; exit_block.fn = exit_fn; exit_block.pstatus = &status; r = sys$dclexh(&exit_block); if (r != 1) lib$signal(r) ; } void fdl_create(char *fname, char *fdl) { int st; int sts=0,stv=0; int flags=FDL$M_FDL_STRING; DEFSTR1(fdlstr,fdl,strlen(fdl)); DEFSTR1(filestr,fname,strlen(fname)); DEFSTR2(fdlstr,fdl,strlen(fdl)); DEFSTR2(filestr,fname,strlen(fname)); st = fdl$create(&fdlstr,&filestr,NULL,NULL,NULL,&flags,NULL,NULL,&sts,&stv); if ((st&1)!=1) { dmsg("sts, %s",lib_message(sts)); dmsg("stv, %s",lib_message(stv)); lib$signal(st); } } void lib_delete(char *s) { int r; DEFSTR1(wildstr,s,strlen(s)); DEFSTR2(wildstr,s,strlen(s)); r = lib$delete_file(&wildstr); /* if ((r&1)!=1) if (r!=RMS$_FNF) lib$signal(r); */ } void lib_opermsg(char *s) { struct {char type; char target[3]; int id; char text[200];} msgbuf; DEFSTR1(msgstr,(char *) &msgbuf,8+strlen(s)); DEFSTR2(msgstr,(char *) &msgbuf,8+strlen(s)); strcpy(msgbuf.text,s); msgbuf.type = OPC$_RQ_RQST; msgbuf.target[0] = OPC$M_NM_CENTRL | OPC$M_NM_NTWORK; msgbuf.target[1] = 0; msgbuf.target[2] = 0; msgbuf.id = 123; sys$sndopr(&msgstr,NULL); } /*----------------------------------------------------------------------*/ char *lib_findfile(char *s) { static char wild[200],buff[201]; static DEFSTR1(wild_str,wild,0); DEFSTR1(buff_str,buff,200); static int r,context; int i; int flags=1; if (s!=NULL) strcpy(wild,s); DEFSTR2(wild_str,wild,strlen(wild)); DEFSTR2(buff_str,buff,200); strcpy(buff,""); r = lib$find_file(&wild_str, &buff_str, &context); if ((r&1)!=1) { r = lib$find_file_end(&context); if (r&1 != 1) wmsg("lib: %s\n",lib_message(r)); return NULL; } s = strchr(buff,' '); if (s!=NULL) *s = 0; return buff; } /* Mail a file using the vms callable mail interface */ typedef struct itmlst { short len; short code; char *buff; int *rlen; } Itmlst; Itmlst nulllist[] = { {0,0,0,0} }; void mail_setrec(Itmlst *x,int code, char *bf, int *rlen); void mail_setrec(Itmlst *x,int code, char *bf, int *rlen) { x->len = strlen(bf); x->buff = bf; x->code = code; x->rlen = rlen; } int mail_good(void) { emsg("Mail good \n"); return TRUE; } int mail_bad(void) { emsg("Mail bad \n"); return TRUE; } int lib_mail_file(char *to, char *subj, char *fname) { int r; int context; char realto[200]; int to_len,fname_len,subj_len; Itmlst address_list[3]; Itmlst body_list[3]; Itmlst attrib_list[3]; Itmlst send_list[3]; if (strchr(to,'@')!=NULL) { sprintf(realto,"%s%%\"%s\"",config_get(C_MAIL),to); } else strcpy(realto,to); dmsg("lib: mail address changed to {%s} \n",realto); mail_setrec(&address_list[0],MAIL$_SEND_USERNAME,realto,&to_len); mail_setrec(&address_list[1],0,"",0); mail_setrec(&body_list[0],MAIL$_SEND_FILENAME,fname,&fname_len); mail_setrec(&body_list[1],0,"",0); mail_setrec(&attrib_list[0],MAIL$_SEND_TO_LINE,realto,&to_len); mail_setrec(&attrib_list[1],MAIL$_SEND_SUBJECT,subj,&subj_len); mail_setrec(&attrib_list[2],0,"",0); /* Just for debugging, msut add send_list to send call */ mail_setrec(&send_list[0],0," ",0); mail_setrec(&send_list[1],0," ",0); mail_setrec(&send_list[2],0," ",0); send_list[0].code = MAIL$_SEND_ERROR_ENTRY; send_list[0].buff = (char *) mail_bad; send_list[1].code = MAIL$_SEND_SUCCESS_ENTRY; send_list[1].buff = (char *) mail_good; r = mail$send_begin(&context, nulllist, nulllist); if (r != SS$_NORMAL) { emsg("mail: %s\n",lib_message(r)); return FALSE;} r = mail$send_add_address(&context,address_list,nulllist); if (r != SS$_NORMAL) { emsg("mail: %s\n",lib_message(r)); return FALSE;} r = mail$send_add_attribute(&context,attrib_list,nulllist); if (r != SS$_NORMAL) { emsg("mail: %s\n",lib_message(r)); return FALSE;} r = mail$send_add_bodypart(&context,body_list,nulllist); if (r != SS$_NORMAL) { emsg("mail: %s\n",lib_message(r)); return FALSE;} r = mail$send_message(&context,nulllist,nulllist); if (r != SS$_NORMAL) { emsg("mail: %s\n",lib_message(r)); return FALSE;} r = mail$send_end(&context,nulllist,nulllist); if (r != SS$_NORMAL) { emsg("mail: %s\n",lib_message(r)); return FALSE;} return TRUE; } /* Return result as number of free 1K blocks (not vms blocks) */ int lib_freespace(char *s) { int rslt; int code = DVI$_FREEBLOCKS; DEFSTR1(devstr,s,strlen(s)); DEFSTR2(devstr,s,strlen(s)); rslt = 0; lib$getdvi(&code,NULL,&devstr,&rslt,NULL,NULL); return rslt/2; }