home *** CD-ROM | disk | FTP | other *** search
- /*
- * aosvs.c - AOS/VS & MV/UX version of the termio.c module
- *
- * The functions in this module deal with the O/S in reading/writing
- * characters from/to the screen. We also deal with various wiedness things
- * in dealing with the AOS/VS file system such as ACL's and elementsizes.
- * This has been written primarily for AOS/VS but should work for MV/UX as
- * well. No promises though.
- *
- * AOS/VS and MV/UX are products of Data General Corporation, Westboro MA.
- *
- * Authors:
- * Daniel Lawrence --- doing MicroEmacs... stuff copied into here...
- * Douglas Rady ------ most of the rest of the stuff here
- * Credits:
- * Michael Meissner -- beating Doug over the head with advice and info.
- * on AOS/VS "C" compiler. THANK YOU!!!!!!!!!!
- * Bill Benedetto
- * & friends ---- beta victims, bug finders/fixers
- * GNU --------------- inspiration, software tools, clean readable BSD
- * and USG code examples and interesting comments.
- *
- * Definition: uka = Unixly Known As
- *
- * Revision/Hack History
- * MicroEMACS v3.<9p,10> AOS/VS History
- *
- * 3.09.16.00 - 3.09.16.09 ??-???-?? dcr
- * Before written history. Suffice to say that .00 - .04 was just the
- * AOS/VS port from 3.8z, 3.9e, 3.9i and 3.9n with major cleaning up and
- * rewriting of the AOS/VS stuff. Sub-revisions 3.09.16.05 - 3.09.16.09
- * being optimizations and various fixes.
- * Yawn...
- *
- * 3.09.16.10 25-Aug-88 dcr
- * Changed do_system_end() in aosvs.c to check for execution of a
- * macro as basis for not executing an mlreply("Continue") call.
- * Also fixed stime() in aosvs.c so it just plain worked.
- * #$&^@*&(+$#!!!!
- * Also added REPLYNL in estruct.h and made use of CR or NL in the
- * mlreply() routine in input.c compile time conditional.
- *
- * 3.09.16.11 13-Sep-88 dcr
- * Start of written hisory. This is a momentous event in the course of
- * AOS/VS MicroEMACS history: doug writes some change doc.!!! Yeah!!!
- * Changed several functions to force the $builtin version as a trade of
- * more code size for more speed (usually defaulted to $builtin anyway...).
- *
- * 3.09.16.12 14-Sep-88 dcr
- * Recompiled with revision 4.00 of AOS/VS C. A miracle...
- *
- * 3.09.16.13 12-Oct-88 dcr
- * Changed to have the temporary file for pipecmd() be created in a system
- * wide temporary file directory known as :TMP, uka /tmp. You paranoids
- * can create :TMP as a CPD with max. size of 2048 blocks and an ACL of
- * +,WE and you should be able to relax a nibble.
- * Creates temp. file with ACL of username,OWAR
- *
- * 3.09.16.14 13-Oct-88 dcr
- * Put in MCA's hack to reduce memory consumption when VIEWing a file.
- * Modified lalloc() in line.c Test case of paru.h saved 27 2Kb pages.
- *
- * 3.10.00.00 09-Nov-88 dcr
- * Begin code porting for 3.10 BETA.
- *
- * 3.10.00.01 20-Dec-88 dcr
- * Implemented multi-language messages in aosvs.c per 3.10 BETA.
- *
- * 3.10.00.02 26-Dec-88 dcr
- * Tracked down some un-documented runtime optimizations and got
- * a working version. Also resolved timeset() references.
- *
- * 3.10.00.03 17-Jan-89 dcr
- * Cleaned up for shipping to Dan. Put in some missing code for input.c
- *
- * 3.10.00.04 17-Jan-89 dcr
- * Put in some optimizations regarding TTflush() and ostring() in the
- * bind.c, input.c and aosvs.c files. This freed 2Kb... but not for long.
- *
- * 3.10.00.05 17-Jan-89 dcr
- * Some memory optimization in exec.c and input.c for small regain.
- *
- * 3.10.00.06 - 3.10.00.27 02-Mar-89 - 10-Mar-89 dcr
- * Various changes. Cleaned up the AOS/VS changes in other modules so
- * we actually work right. Added conditionals for using either BSD or
- * USG console i/o (BSD doesn't seem to work). Reclaimed about 4Kb of
- * memory in various places and made some of these optimizations compile
- * time conditional. We are still using .890+ ms to start up intead of the
- * .520+ ms that we took with 3.9p. Not much hope there... but...
- * Various tweaks here and there. Added the skip of nulls when reading in
- * a file (most unpleasant results if we don't). Lost some memory to the
- * USG console i/o stuff. Threw out the BSD console i/o stuff, sigh....
- *
- * 3.10.00.28 10-Mar-89 dcr
- * Stuck in the aosvs$unix_to_aosvs_path() routine to replace the code
- * in resolve_pathname(). The new routine does a fairly complete job of
- * converting Unix(tm) pathnames to AOS/VS format. It also handles the
- * Ms-Dog '\' path seperator.
- *
- * 3.10.00.29 16-Mar-89 dcr
- * Changed pathname expansion to be invisible to user. Required changes
- * to fileio.c to #if AOSVS replace the fopen() calls with our xxfopen()
- * call which does the pathname expansion. Allowed removal of all the
- * related to the EXPPATH define. Also changed several routines here.
- * Allows user to reference buffer & file names w/o "unexpanding" the
- * orginal pathname.
- * Diff'd & sent to Dan.
- *
- */
-
- #nolist
- #include <stdio.h> /* get the usual */
- #list
- #include "estruct.h" /* get the MicroEMACS stuff */
-
- #ifdef AOSVS | MV_UX /* should this be done? */
-
- #define dashertermdef 1 /* might not be used any more */
-
- #nolist
- #include "edef.h" /* get the MicroEMACS extern's */
- #include "elang.h"
- #list
-
- /* There is no kitchen sink in C so we can't include it. Maybe in C++... */
- #nolist
- #include <paru.h> /* AOS/VS system mnemonics */
- #include <sysid.h> /* AOS/VS system call mnemonics */
- #include <packets/characteristics.h> /* sys call packet for terminal char.*/
- #include <packets/create.h> /* sys call packet to create files */
- #include <packets/filestatus.h> /* sys call packet to get file info */
- #include <packets/misc.h> /* misc. sys call packets (?SYSPRV) */
-
- /* And now... the Unix(tm) stuff... */
- #include <fcntl.h> /* terminal file control stuff */
- #include <signal.h> /* the signals... */
- #include <termio.h> /* more terminal control stuff */
- #list
-
- /*
- Variables!!! Functions!!! Externals!!!!
- */
- struct termio old_in_termio; /* original stdin terminal characteristics */
- struct termio new_in_termio; /* stdin characteristics to use inside */
-
- int kbdpoll; /* type ahead polling flag */
- int kbdflgs; /* saved keyboard fd flags */
- int kbdqp; /* there is a char in kbdq */
- char kbdq; /* char we've already read */
-
- /*
- some D.G. supplied AOS/VS & MV/UX specific functions
-
- _toaos_fid() - changes UNIX(tm) pathname to AOS/VS pathname (Thank you!)
- traceback() - calls the ?SNAP LANG_RT routine for error traceback
- */
- /*extern int _toaos_fid(char*, char* );*/
- extern VOID traceback(int );
-
- /*
- This is how we make an MV/Eclipse accumulator in C with almost all options.
- */
- union accumulator { /* dearly beloved, we are gathered here...*/
- unsigned long * ptr; /* pointer to unsigned long (generic) */
- char * cptr; /* pointer to char */
- unsigned int * pint; /* pointer to unsigned int */
- unsigned short *psht; /* pointer to short */
- unsigned long ulng; /* unsigned long */
- signed long lng; /* signed long */
- unsigned int uin; /* unsigned int */
- signed int in; /* signed int */
- unsigned short usht; /* unsigned short */
- unsigned char chr; /* a char, unsigned of course!!! */
- } ac0, ac1, ac2; /* our bountiful accumulators, sigh... */
-
-
- P_CREATE create_pkt; /* file create system call packet */
- P_FSTAT fstat_pkt; /* file status system call packet */
- char acl_buf[ $MXACL ]; /* ACL buffer, gotta protect things... */
- char *crt_eol="\013"; /* Dasher D2xx commands */
- char *crt_eop="\014"; /* Dasher D2xx commands */
- int dimsts, revsts;
- int su_mode; /* Superuser mode flag */
- #define TLINE_LEN 512
- char tline[TLINE_LEN]; /* command line for cli/shell/program calls */
-
- extern VOID do_system(); /* calls the cli/shell/program */
- extern VOID do_system_end(); /* cleans up after cli/shell/program calls */
- extern VOID init_tline(); /* inits the command line for cli/shell... */
- extern VOID ttputs();
- extern VOID in_init();
- extern FILE *ffp; /* file stream pointer used in fileio.c */
- extern int vttidy(); /* MicroEMACS routine to tidy up the screen */
-
- extern int aosvs$expand_pathname();
- extern void aosvs$unix_to_aosvs_path();
- #endif
-
- FILE *STDIN, *STDOUT; /* Needed since the array of files went away.*/
- /* Of course, if _iob changes, we'll have to */
- /* bend over since we use ->_file in _iob. */
-
- static int mexist; /* is the mouse driver installed? */
- static int nbuttons; /* number of buttons on the mouse */
- static int oldbut; /* Previous state of mouse buttons */
-
- /*------------------------------------------------------------------------------
- * resolve_full_pathname(char*, char*) - resolves a filename or pathname to
- * full AOS/VS pathname via the ?GRNAME system call. If the file does not
- * exsist then the current working directory is assumed by AOS/VS.
- *
- * Returns FIOSUC if from_path is found or FIOFNF if it isn't found.
- */
- int resolve_full_pathname(from_path, to_path)
-
- char *from_path, *to_path; /* resolve "from" pathname "to" pathname */
- {
- if (aosvs$expand_pathname(from_path, to_path))
- return(FIOFNF);
-
- return(FIOSUC);
- }
-
- /*
- * ffwopen() - AOS/VS specific version of the ffwopen() routine found in the
- * fileio.c source. This version will attempt to recreate the edit file
- * (if it exists) with the existing edit file ACL, elementsize, filetype and
- * recordsize parameters as determined via a ?FSTAT filestatus system call.
- *
- * Returns FIOSUC if file is opened or FIOERR if not opened.
- *
- * DOUG, we need to make the mode param work here, or ignore it....
- */
- int ffwopen(bfilnam, mode, sfilnam)
-
- char *bfilnam; /* buffer file name */
- char *mode; /* mode for file open (w = write, a = append) */
- char *sfilnam; /* save file name or NULL */
- {
- char bfnam[NFILEN], sfnam[NFILEN];
- char *tptr;
-
- /* some initializations */
- zero((char *) &create_pkt, sizeof(create_pkt));
- zero((char *) &fstat_pkt, sizeof(fstat_pkt));
- zero(acl_buf, $MXACL);
-
- strcpy(bfnam, bfilnam);
- if (sfilnam) {
- strcpy(sfnam, sfilnam);
- resolve_full_pathname(sfnam, sfnam);
- tptr = sfnam;
- } else {
- tptr = bfnam;
- }
-
- create_pkt.ctim = -1L; /* take default file creation time */
- create_pkt.cacp = -1L; /* take default file creation acl */
- create_pkt.cdel = -1L; /* take default file creation elementsize */
- create_pkt.cmil = -1L; /* take default file creation max. index levels */
- fstat_pkt.stim = -1L;
- fstat_pkt.sacp = -1L;
-
- /* attempt to get full AOS/VS pathname of the file */
- if ((resolve_full_pathname(bfnam, bfnam)) == FIOFNF) { /* edit file found? */
- /* bfnam not found, create one with default specs. */
- create_pkt.cftyp_format = $ORDS; /* data sensitive record type */
- create_pkt.cftyp_entry = $FTXT; /* text file type */
- ac2.ptr = &create_pkt;
- ac1.lng = 0L;
-
- ac0.cptr = tptr;
-
- /* have AOS/VS attempt to create the file */
- if (sys($CREATE, &ac0, &ac1, &ac2))
- goto fubar;
-
- } else { /* bfnam found, get filestatus info. for recreation of bfnam */
- ac2.ptr = &fstat_pkt;
- ac1.lng = 0L;
- ac0.cptr = bfnam;
- /* have AOS/VS attempt to get the file information for us */
- if (sys($FSTAT, &ac0, &ac1, &ac2))
- goto fubar;
-
- /*
- Get ACL of bfnam. If we can't get that then we get the
- default ACL and use that.
- */
- ac0.cptr = bfnam;
- ac1.cptr = acl_buf;
- ac2.lng = 0L;
- if (sys($GACL, &ac0, &ac1, &ac2)) { /* try to get the file ACL */
- /* can't get ACL of file, get default ACL */
- ac0.lng = 0L;
- ac2.lng = 0L;
- ac1.cptr = acl_buf;
- sys($DACL, &ac0, &ac1, &ac2); /* try to get user default ACL */
- }
-
- /*
- Delete sfnam file. We don't care about any errors on this.
- */
- ac0.cptr = tptr;
- ac1.lng = 0L;
- ac2.lng = 0L;
- sys($DELETE, &ac0, &ac1, &ac2); /* delete it */
-
- /*
- Set up the packet for the file create system call
- */
- create_pkt.cftyp_format = fstat_pkt.styp_format; /* file format */
- create_pkt.cftyp_entry = fstat_pkt.styp_type; /* file type */
- create_pkt.ccps = fstat_pkt.scps; /* recordsize, if any */
- create_pkt.cacp = acl_buf; /* acl buffer ptr */
- create_pkt.cdeh = fstat_pkt.sdeh; /* element size */
- create_pkt.cmil = fstat_pkt.smil; /* max. index level */
-
- /*
- Make system call to create a file with supplied specs.
- */
- ac2.ptr = &create_pkt;
- ac0.cptr = tptr;
-
- ac1.lng = 0L;
- if (sys($CREATE, &ac0, &ac1, &ac2)) /* attempt file create */
- goto fubar;
- }
-
- if ((ffp = fopen(tptr, "a")) == NULL)
- goto fubar;
-
- #if ISADIR
- if (isadirectory(ffp)) { /* check to see if file is a directory */
- mlwrite(TEXT216); /* bitch... */
- ffclose(ffp); /* yes, close it and get out!!! */
- return(FIOERR); /* actual checking code in O/S modules */
- }
- #endif
-
- return(FIOSUC);
-
- /*
- Common error exit for all ffwopen() errors
- */
- fubar:
- mlwrite(TEXT155);
- /* mlwrite("Cannot open file for writing");*/
- return(FIOERR);
- }
-
- /*
- * unlink() - delete a file - called from writeout() in file.c
- *
- * This routine replaces the DG supplied unlink() since we don't use the
- * link() unlink() combination to rename files. Saves some memory.
- *
- */
- int unlink(del_fnam)
-
- char *del_fnam; /* name of file to delete */
- {
- char dtmp[NFILEN];
-
- strcpy(dtmp, del_fnam);
- resolve_full_pathname(dtmp, dtmp);
- ac0.cptr = dtmp;
- ac1.lng = 0L;
- ac2.lng = 0L;
- if (sys($DELETE, &ac0, &ac1, &ac2)) /* attempt to delete it */
- return(-1); /* normal error return */
- return(0); /* normal okay return */
- }
-
- /*
- * rename() - rename a file - called from writeout() in file.c
- */
- int rename(from_nam, to_nam)
-
- char *from_nam; /* rename from name */
- char *to_nam; /* rename to name */
- {
- char ftmp[NFILEN], ttmp[NFILEN];
-
- /*
- First we convert Unix(tm) or Ms-dog paths to Aos/Vs paths.
- Second we strip the actual filename from the "to" path by going to the
- end of the string and working our way backward until we find a pathname
- seperator which under AOS/VS is a colon (:).
- */
- strcpy(ftmp, from_nam);
- strcpy(ttmp, to_nam);
- resolve_full_pathname(ftmp, ftmp);
- resolve_full_pathname(ttmp, ttmp);
-
- ac1.cptr = ttmp + (sizeof(char) * strlen(ttmp));
- while ((ac1.cptr >= ttmp) && (*ac1.cptr != ':') && (*ac1.cptr != '='))
- --ac1.cptr;
-
- ++ac1.cptr; /* move pointer from seperator to 1st char in filename */
- ac0.cptr = ftmp;
- ac2.lng = 0L;
- if (sys($RENAME, &ac0, &ac1, &ac2)) /* attempt the rename */
- return(-1); /* oops!!! */
- return(0); /* okay... */
- }
-
- /*
- * This function gets called just before we go back home to the command
- * interpreter.
- */
- VOID ttclose()
- {
- fflush(stdout);
- fflush(stdin);
- ioctl(STDIN->_file, TCSETA, &old_in_termio); /* restore terminal settings */
- fcntl(STDIN->_file, F_SETFL, kbdflgs);
- }
-
- /*
- * Write a character to the display.
- */
- #if TTPUTC == 0
- VOID ttputc(c)
- {
- putc(c, stdout);
- }
- #endif
-
- /*
- * Flush terminal buffer. Does real work where the terminal output is buffered
- * up. A no-operation on systems where byte at a time terminal I/O is done.
- */
- #if TTFLUSH == 0
- VOID ttflush()
- {
- fflush(stdout);
- }
- #endif
-
- unsigned int extcode(c)
-
- unsigned int c;
-
- {
- if ((c == 1 || c == 8 || c == 17 || c == 23) || (c >= 24 && c <=26)
- || (c >= 32 && c <= 110) || (c >= 112 && c <= 126)) /* 111 is mouse */
- return((c & 255) | SPEC);
-
- return(c & 255);
- }
-
- /* input buffers and pointers */
-
- #define IBUFSIZE 64 /* this must be a power of 2 */
-
- unsigned char in_buf[IBUFSIZE]; /* input character buffer */
- int in_next = 0; /* pos to retrieve next input character */
- int in_last = 0; /* pos to place most recent input character */
-
- VOID in_init() /* initialize the input buffer */
-
- {
- in_next = in_last = 0;
- }
-
- int in_check() /* is the input buffer non-empty? */
-
- {
- if (in_next == in_last)
- return(FALSE);
- else
- return(TRUE);
- }
-
- VOID in_put(event)
-
- int event; /* event to enter into the input buffer */
-
- {
- in_buf[in_last++] = event;
- in_last &= (IBUFSIZE - 1);
- }
-
- int in_get() /* get an event from the input buffer */
-
- {
- register int event; /* event to return */
-
- event = in_buf[in_next++];
- in_next &= (IBUFSIZE - 1);
- return(event);
- }
- #if MOUSE
- int checkmouse()
-
- {
- register int k; /* current bit/button of mouse */
- register int event; /* encoded mouse event */
- int newbut; /* new state of the mouse buttons */
- int mousecol; /* current mouse column */
- int mouserow; /* current mouse row */
- int sstate; /* current shift key status */
-
- /* check to see if any mouse buttons are different */
- /* rg.x.ax = 3;*/ /* Get button status and mouse position */
- /* int86(0x33, &rg, &rg);*/
- /* newbut = rg.x.bx;*/
- /* mousecol = rg.x.cx >> 3;*/
- mouserow = rg.x.dx >> 3;
-
- /* get the shift key status as well */
- sstate = 0;
- /* rg.h.ah = 2;*/ /* return current shift status */
- /* int86(0x16, &rg, &rg);*/
- /* sstate = rg.h.al;*/
-
- for (k=1; k != (1 << nbuttons); k = k<<1) {
- /* For each button on the mouse */
- if ((oldbut&k) != (newbut&k)) {
- /* This button changed, generate an event */
- in_put(0);
- in_put(MOUS >> 8);
- in_put(mousecol);
- in_put(mouserow);
- event = ((newbut&k) ? 0 : 1); /* up or down? */
- if (k == 2) /* center button? */
- event += 4;
- if (k == 4) /* right button? */
- event += 2;
- if (sstate & 3) /* shifted */
- event += 'A';
- else if (sstate & 4) /* controled? */
- event += 1;
- else
- event += 'a'; /* plain */
- in_put(event);
- oldbut = newbut;
- return(TRUE);
- }
- }
- return(FALSE);
- }
- #endif
-
- int doschar()
-
- {
- /* USG - SysV console i/o - From "C Users Journal", April 1989, Vol. 7, # 9 */
- if(kbdqp) /* any typeahead known? */
- kbdqp = FALSE; /* yes, clear flag & return typeahead char */
- else { /* no typeahead. */
- if (fcntl(STDIN->_file, F_SETFL, kbdflgs) < 0 && kbdpoll)
- return(FALSE);
- kbdpoll = FALSE;
- read(STDIN->_file, &kbdq, 1); /* wait and get a char */
- }
- if (kbdq == '\036') { /* D.G. Dasher CRT function key lead-in? */
- in_put(SPEC >> 8); /* ??? stash in the keyboard buffer stuff ??? */
- return(0);
- }
- return (kbdq & 255);
- }
-
- /*
- * Read a character from the terminal, performing no editing and doing no echo
- * at all.
- */
- int ttgetc()
- {
- /* return any keystrokes waiting in the
- type ahead buffer */
- ttc: if (in_check())
- return(in_get());
-
- if (typahead())
- return(doschar());
-
- /* with no mouse, this is a simple get char routine */
- if (mexist == FALSE || mouseflag == FALSE)
- return(doschar());
-
- #if MOUSE
- /* turn the mouse cursor on */
- /* rg.x.ax = 1;*/ /* Show Cursor */
- /* int86(0x33, &rg, &rg);*/
- /* loop waiting for something to happen */
- while (TRUE) {
- if (typahead())
- break;
- if (checkmouse())
- break;
- }
-
- /* turn the mouse cursor back off */
- /* rg.x.ax = 2;*/ /* Hide Cursor */
- /* int86(0x33, &rg, &rg);*/
-
- goto ttc:
- #endif /* MOUSE */
- }
-
- #if TYPEAH
- /* typahead: Check to see if any characters are already in the
- keyboard buffer. Hurray for kludges!!!
- */
- int typahead()
- {
- /* USG - SysV console i/o - From "C Users Journal", April 1989, Vol. 7, # 9 */
- if (!kbdqp) {
- if (fcntl(STDIN->_file, F_SETFL, (kbdflgs | O_NDELAY)) < 0 && kbdpoll)
- return(FALSE);
- kbdpoll = TRUE;
- kbdqp = (1 == read(STDIN->_file, &kbdq, 1));
- }
- return(kbdqp);
- }
-
- #endif /* TYPEAH */
-
- /* Spawn: various DOS access commands
- for MicroEMACS ver 3.9e
- */
-
-
- /*
- * Create a subjob with a copy of the command intrepreter in it. When the
- * command interpreter exits, mark the screen as garbage so that you do a full
- * repaint. Bound to "^X C".
- */
- int spawncli(f, n)
- {
- register char *cp;
-
- /* don't allow this command if restricted */
- if (restflag)
- return(resterr());
-
- #if MV_UX
- TTflush();
- TTclose(); /* stty to old settings */
- if ((cp = getenv("SHELL")) != NULL && *cp != '\0')
- system(cp);
- else
- system("exec /bin/sh");
- #endif
-
- #if AOSVS
- init_tline();
- strcat(tline,"CHAIN/1=AB/2=AB,:CLI,EMACS_SET_CLI_PREFIX");
- do_system();
- #endif
-
- sleep(2);
- return(TRUE);
- }
-
- /*
- * Run a one-liner in a subjob. When the command returns, wait for a single
- * character to be typed, then mark the screen as garbage so a full repaint is
- * done. Bound to "C-X !".
- */
- int spawn(f, n)
- {
- register int s;
- char line[NLINE];
-
- /* don't allow this command if restricted */
- if (restflag)
- return(resterr());
-
- if ((s=mlreply("!", line, NLINE)) != TRUE)
- return (s);
- init_tline();
- strcat(tline,line);
- do_system();
- do_system_end();
- return (TRUE);
- }
-
- /*
- * Run an external program with arguments. When it returns, wait for a single
- * character to be typed, then mark the screen as garbage so a full repaint is
- * done. Bound to "C-X $".
- */
-
- int execprg(f, n)
-
- {
- register int s;
- char line[NLINE];
-
- /* don't allow this command if restricted */
- if (restflag)
- return(resterr());
-
- if ((s=mlreply("!", line, NLINE)) != TRUE)
- return (s);
- strcpy(tline, line);
- do_system();
- do_system_end();
- return (TRUE);
- }
-
- /*
- * Pipe a one line command into a window
- * Bound to ^X @
- *
- * This command REQUIRES a directory named :TMP or a link by that name to
- * another directory such as :SL_TEMPS. This diectory should have an
- * ACL of +,RWE which will allow all users to access it. This diectory is
- * where the output file for this command is placed. This was done because
- * the sons of MircoEMACS do not always have the same privileges. The file
- * is of the pathname :TMP:pid.MICRO_EMACS_COMMAND where "pid" is the PID
- * of the MicroEMACS process. Also note that this sort of follows the UNIX(tm)
- * convention for a common temporary file directory.
- * The temp. file is created with an ACL of username,OWAR
- *
- * See the THINGS_TO_DO.TXT for planned enhancements in this area.
- *
- */
- int pipecmd(f, n)
- {
- register int s; /* return status from CLI */
- register WINDOW *wp; /* pointer to new window */
- register BUFFER *bp; /* pointer to buffer to zot */
- char line[NLINE]; /* command line send to shell */
- const char pipecmd_bname[] = "command";
- char pipecmd_filnam[NFILEN] = ":tmp:"; /* must be AOS/VS format!!!! */
-
-
- /* don't allow this command if restricted */
- if (restflag)
- return(resterr());
-
- /* get the users pid and build a pathname for our scratch file */
- ac0.ulng = 0L;
- ac2.ulng = 0L;
- ac1.ulng = -1L;
- sys($PNAME, &ac0, &ac1, &ac2); /* get our PID */
- itoa(ac1.in, line);
- strcat(pipecmd_filnam, line); /* build temp. filename */
- strcat(pipecmd_filnam, ".micro_emacs_command");
-
- zero((char *) &create_pkt, sizeof(create_pkt));
- zero(acl_buf, $MXACL);
- ac2.cptr = &acl_buf;
- ac0.ulng = -1L;
- ac1.ulng = -1L;
- sys($GUNM, &ac0, &ac1, &ac2); /* get our user name */
- ac0.cptr = &acl_buf[strlen(acl_buf)];
- ac0.cptr++;
- *ac0.cptr = ($FACO | $FACW | $FACA | $FACR); /* specify the ACL */
- ac0.cptr++;
- *ac0.cptr = '\000';
- create_pkt.cacp = &acl_buf; /* load addr of temp file ACL */
-
- create_pkt.ctim = -1L;
- create_pkt.cdel = -1L;
- create_pkt.cmil = -1L;
- create_pkt.cftyp_format = $ORDS; /* data sensitive */
- create_pkt.cftyp_entry = $FTXT; /* TEXT file type */
- ac2.ptr = &create_pkt;
- ac1.lng = 0L;
- ac0.cptr = &pipecmd_filnam;
- sys($CREATE, &ac0, &ac1, &ac2); /* have AOS/VS create the temp file */
-
- /* get the command to pipe in */
- if ((s=mlreply("@", line, NLINE)) != TRUE)
- return(s);
-
- /* get rid of the command output buffer if it exists */
- if ((bp=bfind(pipecmd_bname, FALSE, 0)) != FALSE) {
- /* try to make sure we are off screen */
- wp = wheadp;
- while (wp) {
- if (wp->w_bufp == bp) {
- onlywind(FALSE, 1);
- break;
- }
- wp = wp->w_wndp;
- }
- if (zotbuf(bp) != TRUE)
- return(FALSE);
- }
-
- s = 0; /* init. index into line */
- init_tline();
- strcat(tline,"LISTFILE,"); /* give CLI an @LIST to use */
- strcat(tline,pipecmd_filnam); /* tack on the filename for @LIST */
- strcat(tline,";"); /* separate the commands */
- s = strpbrk(line,",; \t"); /* check for cmd line delimiters */
- if (s) { /* find any? */
- strncat(tline,line,(s-(int) &line));/* get whats before the delimeter*/
- strcat(tline,"/L"); /* tack on "use @LIST file" switch */
- strcat(tline,s); /* get the rest of the cmd line */
- } else { /* no delimiers... */
- strcat(tline,line); /* get the cmd line */
- strcat(tline,"/L"); /* tack on "use @LIST file" switch*/
- }
- strcat(tline,";BYE/L=@NULL"); /* tell CLI to die quietly */
- do_system();
- s = TRUE;
-
- /* split the current window to make room for the command output */
- if (splitwind(FALSE, 1) == FALSE)
- goto fubar;
-
- /* and read the stuff in */
- if (getfile(pipecmd_filnam, FALSE) == FALSE)
- goto fubar;
-
- /* make this window in VIEW mode, update all mode lines */
- curwp->w_bufp->b_mode |= MDVIEW;
- wp = wheadp;
- while (wp) {
- wp->w_flag |= WFMODE;
- wp = wp->w_wndp;
- }
-
- /* and get rid of the temporary file */
- unlink(pipecmd_filnam);
- return(TRUE);
-
- fubar:
- unlink(pipecmd_filnam);
- return(FALSE);
- }
-
- /*
- * filter a buffer through an external DOS program
- * Bound to ^X #
- */
- int filter(f, n)
-
- {
- mlwrite(TEXT217);
- /* mlwrite("[Not available yet under AOS/VS]");*/
- sleep(1);
- return(FALSE);
- }
-
-
- /*
- return a system dependant string with the current time
- original version didn't work. modified idea of bill benedetto by
- doug rady. note the use of sys($ITIME, ...) instead of sys_itime()
- */
- char *PASCAL NEAR timeset()
-
- {
- register char *sp; /* temp string pointer */
- short int tvec[2];
- extern char *dg_ctime();
-
- ac0.ulng = 0L;
- ac1.ulng = 0L;
- ac2.ulng = 0L;
- sys($ITIME, &ac0, &ac1, &ac2); /* get system time */
- tvec[0] = ac2.in;
- ac1.lng /= 32768L;
- tvec[1] = (int)(ac1.lng/2L);
- sp = dg_ctime(tvec);
- sp[ strlen(sp)-1 ] = NULL;
- return(sp);
- }
-
- VOID init_tline()
- {
- extern char *curdir();
-
- tline[0] = '\000';
- strcat(tline, "DIR,");
- curdir(&tline[4]);
- strcat(tline, ";");
- return;
- }
-
- VOID do_system()
- {
- movecursor(term.t_nrow, 0); /* Seek to last line. */
- mlerase();
- TTclose(); /* stty to old modes */
- system(tline);
- TTkopen();
- sgarbf = TRUE;
- }
-
- VOID do_system_end()
- {
- int s;
-
- if (clexec == TRUE) {
- mlputs(TEXT188);
- /* mlputs("[End]");*/
- TTflush();
- while ((s = tgetc()) != '\r' && s != ' ')
- ;
- }
- return;
- }
-
- /*
- Data General AOS/VS terminal handling routines
-
- Known types are:
- DASHER D2xx/4xx series - support primarily for D2xx series
- written by Doug Rady (based on ANSI.C and VMSVT.C)
- */
- extern VOID ttopen();
- extern VOID ttkopen();
- extern VOID ttkclose();
- extern VOID tteeol();
- extern VOID tteeop();
- extern VOID ttbeep();
- extern VOID dashermove();
- extern VOID ansimove();
- extern VOID dasherrev();
- extern VOID ansirev();
- extern int ttcres();
- #if COLOR
- extern VOID ttfcol();
- extern VOID ttbcol();
- #endif
- extern VOID dasherdim();
- extern VOID ansidim();
- extern VOID spal();
-
- #define NROWS 24 /* normal # of screen rows */
- #define MXROWS 24 /* max # of screen rows */
- #define NCOLS 80 /* normal mode # of screen columns*/
- #define MXCOLS 135 /* wide mode # of screen columns*/
- #define MARGIN 4 /* size of minimim margin and */
- #define SCRSIZ 64 /* scroll size for extended lines */
- #define NPAUSE 100 /* # times thru update to pause */
- #define ESC 0x16
- #define BEL 7
-
- /*
- * Dispatch table. All the
- * hard fields just point into the
- * terminal I/O code.
- */
- noshare TERM term = {
- MXROWS -1,
- NROWS -1,
- MXCOLS,
- NCOLS,
- 0, 0,
- MARGIN,
- SCRSIZ,
- NPAUSE,
- &ttopen,
- &ttclose,
- &ttkopen,
- &ttkclose,
- &ttgetc,
- #if TTPUTC == 0
- &ttputc,
- #endif
- #if TTFLUSH == 0
- &ttflush,
- #endif
- &dashermove,
- &tteeol,
- &tteeop,
- &tteeop,
- &ttbeep,
- &dasherrev,
- &ttcres,
- &dasherdim,
- #if COLOR
- &ttfcol,
- &ttbcol
- #endif
- };
-
- /*
- dashermove - Move the cursor for DG Dasher
- */
- VOID dashermove(row, col)
- {
- TTputc('\020');
- TTputc(col);
- TTputc(row);
- }
-
- /*
- ansimove - Move the cursor for ANSI crt
- */
- VOID ansimove(row, col)
-
- int row, col;
- {
- char rc_tmp[ 8 ];
-
- ++row;
- ++col;
- ttputs("\033[");
- itoa(row, rc_tmp);
- ttputs(rc_tmp);
- TTputc(';');
- itoa(col, rc_tmp);
- ttputs(rc_tmp);
- TTputc('H');
- }
-
- /*
- * dasherrev - set the reverse video status for DG Dasher
- */
- VOID dasherrev(status)
-
- int status; /* TRUE = reverse video, FALSE = normal video */
- {
- if (status)
- ttputs("\036\104");
- else
- ttputs("\036\105");
- }
-
- /*
- * ansirev- set the reverse video status for ANSI crt
- */
- VOID ansirev(status)
-
- int status;
- {
- if (dimsts) {
- if (status) {
- ttputs("\033[0;2;7m");
- } else {
- ttputs("\033[0;2m");
- }
- } else {
- if (status) {
- ttputs("\033[0;7m");
- } else {
- ttputs("\033[0m");
- }
- }
- if (status)
- revsts = TRUE;
- else
- revsts = FALSE;
- }
-
- /*
- * dasherdim - set the dim/bright video status for DG Dasher
- */
- VOID dasherdim(status)
-
- int status; /* TRUE = dim video, FALSE = bright video */
- {
- if (status)
- TTputc('\034');
- else
- TTputc('\035');
- }
-
- /*
- * ansidim - set the dim/bright video status for ANSI crt
- */
- VOID ansidim(status)
-
- int status;
- {
- if (revsts) {
- if (status) {
- ttputs("\033[0;2;7m");
- } else {
- ttputs("\033[0;7m");
- }
- } else {
- if (status) {
- ttputs("\033[0;2m");
- }
- else
- {
- ttputs("\033[0m");
- }
- }
- if (status)
- dimsts = TRUE;
- else
- dimsts = FALSE;
- }
-
- /*
- ttcres - Change screen resolution (what resolution?)
- */
- int ttcres()
- {
- return(TRUE);
- }
-
- VOID spal() /* change palette string */
-
- {
- /* Does nothing here */
- }
-
- #if COLOR
- /*
- ttfcol - Set the forground color (not implimented)
- */
- VOID ttfcol()
- {
- }
-
- /*
- ttbcol - Set the background color (not implimented)
- */
-
- VOID ttbcol()
- {
- }
- #endif /* COLOR */
-
- /*
- tteeol - Erase to end of line
- */
- VOID tteeol()
- {
- ttputs(crt_eol);
- }
-
-
- /*
- tteeop - Erase to end of page (clear screen)
- */
- VOID tteeop()
- {
- ttputs(crt_eop);
- }
-
-
- /*
- ttbeep - Ring the bell
- */
- VOID ttbeep()
- {
- TTputc('\007');
- }
-
- VOID ttputs(str)
- char *str;
- {
- while(*str) {
- putc(*str, stdout);
- str++;
- }
- }
-
- /*
- ttopen() - open the terminal and change characteristics for our use
- */
-
- VOID ttopen()
- {
- int sys_err;
- P_CHAR_EX crt_info; /* for ?GECHR system call */
- /*
- set some traps
- */
- signal(SIGTRAP, &traceback);
- signal(SIGIOT, &traceback);
- signal(SIGILL, &traceback);
- signal(SIGSEGV, &traceback);
- signal(SIGTERM, &traceback);
- /* signal(SIGINT, &traceback);*/
- signal(SIGQUIT, &traceback);
- signal(SIGEMT, &traceback);
- signal(SIGFPE, &traceback);
- signal(SIGKILL, &traceback);
- signal(SIGBUS, &traceback);
- signal(SIGSYS, &traceback);
- signal(SIGTERM, &traceback);
-
- ac0.in = fchannel(stdout); /* make sure it is opened */
- ac0.in = fchannel(stdin); /* make sure it is opened */
- ac1.ulng = (BIT0 | (sizeof(crt_info)/2)); /* get characteristics flag */
- ac2.ptr = (unsigned long*) &crt_info;
-
- sys_err = sys($GECHR, &ac0, &ac1, &ac2); /* ?GECHR system call */
-
- /*
- copy the actual stdio pointer macro values into pointers
- */
- STDIN = stdin;
- STDOUT = stdout;
-
- /*
- set LPP & CPL in case they aren't == defaults - idea from bill benedetto
- resetting the max. row value is condtional because some of us can
- display more than LPP lines on a screen.
- */
- term.t_ncol = (short)crt_info.char_cpl; /* get CPL */
- term.t_nrow = ((short)crt_info.char_lpp -1);/* get LPP */
- if (term.t_nrow > term.t_mrow) /* only reset max. row if LPP is > */
- term.t_mrow = term.t_nrow; /* default max. row */
-
- #if XXCRT
- if (termcode == 0) { /* CRT type given on command line? */
- /* nope, we must figure it out */
- }
-
- switch (termcode) {
- case 0: /* Generic ANSI compliant */
- crt_eol = "\033[K";
- crt_eop = "\033[J";
- term.t_move = &ansimove;
- term.t_rev = &ansirev;
- term.t_dim = &ansidim;
- /*
- term.t_getkey = &ansigetkey;
- */
- break;
- case 1: /* DEC VT100 */
- case 2: /* DEC VT100K */
- crt_eol = "\033[K";
- crt_eop = "\033[J";
- term.t_move = &ansimove;
- term.t_rev = &ansirev;
- term.t_dim = &ansidim;
- /*
- term.t_getkey = &vt100getkey;
- */
- break;
- case 4: /* DEC VT102 */
- case 5: /* DEC VT102K */
- crt_eol = "\033[K";
- crt_eop = "\033[J";
- term.t_move = &ansimove;
- term.t_rev = &ansirev;
- term.t_dim = &ansidim;
- crt_func = (INS_CHAR | INS_LINE | DEL_CHAR | DEL_LINE);
- /*
- term.t_getkey = &vt100getkey;
- */
- break;
- case 7: /* DEC VT220 */
- case 8: /* DEC VT220K */
- crt_eol = "\033[K";
- crt_eop = "\033[J";
- term.t_move = &ansimove;
- term.t_rev = &ansirev;
- term.t_dim = &ansidim;
- /*
- term.t_getkey = &vt220getkey;
- */
- break;
- case 6: /* D.G. Dasher D4xx */
- crt_func = (INS_CHAR | INS_LINE | DEL_CHAR | DEL_LINE);
- break;
- case 3: /* D.G. Dasher D2xx */
- default;
- }
- #else
- if ((crt_info.char_cdt != char_d2xx) /* is not CRT3 or D2xx ? and */
- && (crt_info.char_cdt != char_d4xx)) { /* is not CRT6 or D4xx or D5xx ? */
- crt_eol = "\033[K";
- crt_eop = "\033[J";
- term.t_move = &ansimove;
- term.t_rev = &ansirev;
- term.t_dim = &ansidim;
- }
- #endif /* XXCRT */
-
- /*
- change terminal charactersitcs to Unix(tm) raw mode
- */
- ioctl(STDIN->_file, TCGETA, &old_in_termio); /* save old settings */
- new_in_termio.c_iflag = 0; /* setup new settings */
- new_in_termio.c_oflag = 0;
- new_in_termio.c_lflag = 0;
- new_in_termio.c_cc[VTIME] = 0;
- new_in_termio.c_cc[VMIN] = 1;
- new_in_termio.c_line = BELL_LD; /* emulate unix(tm) line handling */
- new_in_termio.c_cflag = old_in_termio.c_cflag;
- ioctl(STDIN->_file, TCSETA, &new_in_termio);
- kbdflgs = fcntl(STDIN->_file, F_GETFL, 0);
- dimsts = 0;
- revsts = 0;
-
- /*
- check for mouse here
- */
- mexist = 0;
- nbuttons = 0;
- oldbut = 0;
-
- /*
- on all screens we are not sure of the initial position
- of the cursor
- */
- ttrow = 999;
- ttcol = 999;
-
- /* assume terminal has following */
- eolexist = TRUE;
- revexist = TRUE;
- strcpy(sres, "NORMAL");
-
- /*
- here we lower the priority of this task so that the console
- reader task will always get control when we get a char.
- */
- ac0.ulng = 0L; /* will get TID of this task */
- ac1.ulng = 0L; /* will get task pri. this task */
- ac2.ulng = 0L; /* who knows... */
- sys($MYTID, &ac0, &ac1, &ac2);
- ac1.ulng = 100L; /* new task priority */
- ac2.ulng = 0L; /* must be zero... */
- sys($IDPRI, &ac1, &ac0, &ac2); /* do it!!! */
-
- }
-
- /*
- open the keyboard
- */
- VOID ttkopen()
- {
- /*
- activate the MircoEmacs console characteristics
- */
- ioctl(STDIN->_file, TCSETA, &new_in_termio);
- fcntl(STDIN->_file, F_SETFL, kbdflgs);
- kbdqp = 0;
- kbdpoll = FALSE;
- kbdq = '\000';
- in_init();
- }
-
- VOID ttkclose()
- {
- }
-
- #if FLABEL
- fnclabel(f, n) /* label a function key */
-
- int f,n; /* default flag, numeric argument [unused] */
-
- {
- /* on machines with no function keys...don't bother */
- return(TRUE);
- }
- #endif
-
- /*
- Change the current working directory
- */
- PASCAL NEAR int chdirectory()
-
- {
- #if CHDIR /* include this code? */
-
- /* don't allow this command if restricted */
- if (restflag)
- return(resterr());
-
- if ((ac0.in = mlreply("Directory: ", tline, NLINE)) != TRUE)
- return(ac0.in);
-
- ac0.in = chdir(tline); /* change the current working directory */
-
- /*
- tell the story... success or failure
- */
- if (ac0.in) {
- mlwrite("Error- directory not changed.");
- return(ac0.in);
- }
- else {
- mlwrite("Directory changed.");
- return(TRUE);
- }
- #endif
- }
-
-
- #if ORMDNI
-
- /*
- superuser on/off toggle routines to override those annoying ACLs
-
- usage: superuser_on(); or superuser_off();
-
- */
- int superuser_on()
-
- {
- int err;
-
- if (restflag)
- return(resterr());
-
- ac0.lng = -1L;
- ac1.ulng = 0L;
- ac2.ulng = 0L;
- err = 0;
-
- if ((err = sys($SUSER, &ac0, &ac1, &ac2)))
- if (err = ERPRV)
- mlwrite("Error: you are not allowed use of superuser.");
- else
- mlwrite("Error turning superuser ON.");
-
- return(err);
- }
-
-
- int superuser_off()
-
- {
- int err;
-
- if (restflag)
- return(resterr());
-
- ac0.ulng = 1L;
- ac1.ulng = 0L;
- ac2.ulng = 0L;
- err = 0;
-
- if ((err = sys($SUSER, &ac0, &ac1, &ac2)))
- mlwrite("Error turning superuser OFF.");
-
- return(err);
- }
- #endif
-
- #if ISADIR
- int isadirectory(fstream)
-
- FILE *fstream;
-
- {
- return(isadir(fstream->_file));
- }
- #endif
-
-
- /****************************************************************************/
- /* */
- /* */
- /* All aosvs$ library routines Copyright (c) 1989 by Douglas C. Rady */
- /* */
- /* */
- /****************************************************************************/
-
- /*
- aosvs$bsd_dir.h -- a replacement inlcude file under AOS/VS for:
- <dir.h> -- definitions for 4.2BSD-compatible directory access
-
- Taken from GNU's emacs/etc/ndir.h for porting GNU stuff to AOS/VS.
-
- All of the usual fields are defined but dd_buf is defined as a char*
- so we can pass a poniter to a template under AOS/VS.
- */
-
- #ifndef DIRSIZ
- struct direct { /* data from readdir() */
- long d_ino; /* inode number of entry */
- unsigned short d_reclen; /* length of this record */
- unsigned short d_namlen; /* length of string in d_name */
- char d_name[$MXFN]; /* name of file */
- };
- #endif
-
- typedef struct {
- int dd_fd; /* file desc. - channel# under aos/vs */
- int dd_loc; /* offset in block */
- int dd_size; /* amount of valid data */
- char *dd_buf; /* pointer to wildcard/template */
- } DIR; /* stream data from opendir() */
-
- /*
- set up the MV/Eclipse accumulators used by the aosvs$ routines
- */
- $align(1) $low32k union aosvs$accumulator { /* dearly beloved, we are gathered here...*/
- unsigned long * ptr; /* pointer to unsigned long */
- char * cptr; /* pointer to char */
- unsigned int * pint; /* pointer to unsigned int */
- unsigned short *psht; /* pointer to short */
- unsigned long ulng; /* unsigned long */
- signed long lng; /* signed long */
- unsigned int uin; /* unsigned int */
- signed int in; /* signed int */
- unsigned short usht; /* unsigned short */
- unsigned char chr; /* a char, unsigned of course!!! */
- } aosvs$ac0, aosvs$ac1, aosvs$ac2; /* our bountiful accumulators, sigh... */
-
-
- /*
- aosvs$bsd_dir.c -- fake 4.2BSD directory access routines for AOS/VS
-
- System call city...
-
- */
-
- P_GNFN aosvs$bsd_gnfn_pkt;
-
- /*
- aosvs$bsd_closedir
- */
- void closedir(dir_stream) /* $name("aosvs$bsd_closedir") */
-
- DIR *dir_stream;
-
- {
- aosvs$ac0.ulng = 0L;
- aosvs$ac2.ulng = 0L;
- aosvs$ac1.in = dir_stream->dd_fd; /* load channel number */
- sys($GCLOSE, &aosvs$ac0, &aosvs$ac1, &aosvs$ac2);
- }
-
-
- /*
- aosvs$bsd_opendir
- */
-
- DIR *opendir(dir_name) /* name$("aosvs$bsd_opendir") */
-
- char *dir_name;
-
- {
-
- #include "packets/block_io.h"
-
- P_GOPEN gopen_pkt;
- DIR *dir_stream;
- int err;
- char t_name[$MXPL];
-
- err = 0;
- dir_stream = (DIR *) malloc(sizeof(DIR));
- zero((char *) dir_stream, sizeof(DIR));
- zero((char *) &aosvs$bsd_gnfn_pkt, sizeof(aosvs$bsd_gnfn_pkt));
- zero((char *) &gopen_pkt, sizeof(gopen_pkt));
-
- err = aosvs$expand_pathname(dir_name, t_name);
- aosvs$ac0.cptr = t_name;
- aosvs$ac1.lng = -1L;
- aosvs$ac2.ptr = &gopen_pkt;
-
- /* Try to ?GOPEN the file. */
- if (err = sys($GOPEN, &aosvs$ac0, &aosvs$ac1, &aosvs$ac2)) {
- free(dir_stream); /* Error Will Robinson! Error! Error! */
- return(NULL);
- }
-
- /* Make sure it is some type of directory! */
- if ((gopen_pkt.opty_type != $FDIR) && (gopen_pkt.opty_type != $FLDU)
- && (gopen_pkt.opty_type != $FCPD)) { /* AOS/VS 7.62 directory types. */
- dir_stream->dd_fd = (int)gopen_pkt.opch;
- closedir(dir_stream);
- free(dir_stream); /* Error Will Robinson! Error! Error! */
- return(NULL);
- }
-
- dir_stream->dd_fd = (int)gopen_pkt.opch; /* stash the channel number */
- return(dir_stream);
- }
-
-
- /*
- aosvs$bsd_readdir
- */
-
- struct direct *readdir(dir_stream) /* name$("aosvs$bsd_readdir") */
-
- DIR *dir_stream;
-
- {
- struct direct *dptr;
-
- dptr = NULL;
- aosvs$ac0.in = 0;
- aosvs$ac1.in = dir_stream->dd_fd; /* load channel number */
-
- dptr = (struct direct *) malloc(sizeof(struct direct));
- zero((char *)dptr, sizeof(struct direct));
-
- if (dir_stream->dd_loc)
- aosvs$bsd_gnfn_pkt.nfky = (short)dir_stream->dd_loc;
- else
- aosvs$bsd_gnfn_pkt.nfky = 0;
-
- if (dir_stream->dd_buf) /* if passed a template */
- aosvs$bsd_gnfn_pkt.nftp = dir_stream->dd_buf; /* load it into packet */
- else
- aosvs$bsd_gnfn_pkt.nftp = (char *) -1L; /* load default flag */
-
- aosvs$bsd_gnfn_pkt.nfnm = dptr->d_name; /* load buffer ptr */
- aosvs$ac2.ptr = &aosvs$bsd_gnfn_pkt;
- if (sys($GNFN, &aosvs$ac0, &aosvs$ac1, &aosvs$ac2) == 0)
- {
- /* save the AOS/VS internal pointer */
- dir_stream->dd_loc = (int) aosvs$bsd_gnfn_pkt.nfky;
-
- /* load the direct struct values */
- dptr->d_ino = (long) aosvs$bsd_gnfn_pkt.nfky; /* fake an inode */
- dptr->d_reclen = sizeof(struct direct); /* why? why not? */
- dptr->d_namlen = strlen(dptr->d_name); /* handy to have */
- return(dptr);
- }
-
- free(dptr);
- return(NULL);
- }
-
-
- /*
- aosvs$bsd_seekdir
- */
-
- void seekdir(dir_stream, pos) /* name$("aosvs$bsd_seekdir") */
-
- DIR *dir_stream;
- long pos;
-
- {
- dir_stream->dd_loc = (short)pos;
- }
-
-
- /*
- aosvs$bsd_telldir
- */
-
- long telldir(dir_stream) /* name$("aosvs$bsd_telldir") */
-
- DIR *dir_stream;
-
- {
- return(dir_stream->dd_loc);
- }
-
-
- /*
- aosvs$unix_to_aosvs_path.c -- convert a Unix(tm) pathname to a Aos/Vs pathname
- We also accept the Ms-Dos '\' seperator and
- convert it to the Unix(tm) '/' seperator. We do
- not deal with Ms-Dos device specifiers. The '\'
- is handled since most current Ms-Dos C compilers
- can deal with either '\' or '/'.
-
- usage:
- aosvs$unix_to_aosvs(u_path, a_path);
-
- where:
- data item name data type description
- ----------------------- ------------------ -----------------------------------
- u_path char * char * of Unix(tm) pathname,
- end with null.
- a_path char * char * for Aos/Vs pathname, MUST be
- $MXPL in length.
-
- -------------------------------------------------------------------------------
- edit history
-
- who mm/dd/yy rev # what.....................................................
- --- -------- ----- ---------------------------------------------------------
- dcr 01/27/89 01.00 birth, new life, creation...
- dcr 03/02/89 01.01 cleaned up, added internal temp. storage for path.
- dcr 03/02/89 01.02 added code to deal with Ms-Dog '\' seperator.
- dcr 03/02/89 01.03 added code to skip out if first char is legal Aos/Vs char.
- This makes us "just like" _toaos_fid().
- */
- void aosvs$unix_to_aosvs_path(u_path, a_path)
-
- char *u_path, *a_path;
- {
-
- extern int _toaos_fid(); /* Data General library routine */
-
- /*
- local variables
- */
- register char *up, *ap;
- register int dec1;
- char t_path[$MXPL], octal[4];
-
- /*
- check for null ptrs... no tricks here please...
- */
- if ((u_path == NULL) || (a_path == NULL))
- return;
-
- /*
- copy to register vars.
- */
- up = u_path; /* load ptr to Unix(tm) path */
- ap = t_path; /* load ptr to temp. storage area */
- zero(t_path, $MXPL); /* zero the temp. storage area */
-
- /*
- to be "just like" DG's _toaos_fid() we skip out if the first char. is a
- legal Aos/Vs seperator. This is from page 2-1 of the "Using Specialized
- C Functions" manual, DG part number 093-000585-00.
- */
- if ((*up == '^') || (*up == '@') || (*up == '=') || (*up == ':')) {
- strcpy(a_path, u_path);
- return;
- }
-
- /*
- step through the unix(tm) pathname and copy or translate bytes into
- the temp. storage area.
- */
- while (*up) { /* better be NULL terminated!!! */
- if ((*up == '$') || (*up == '?') || (*up == '\\') || (*up == '_')
- || ((*up >= '.') && (*up <= ':')) /* thank you ASCII */
- || ((*up >= 'A') && (*up <= 'Z'))
- || ((*up >= 'a') && (*up <= 'z'))) {
- if (*up == '\\') { /* convert ms-dos '\' to unix(tm) '/' */
- *ap++ = '/';
- up++;
- continue;
- }
- *ap++ = *up++;
- continue;
- }
-
- dec1 = 0;
- zero(octal, 4);
- *ap++ = '?'; /* marker for octal replacement */
- dec1 = (int)*up;
- otoa(dec1, octal);
- if (dec1 < 64)
- *ap++ = '0';
- strcat(ap, octal);
- if (dec1 >= 64)
- ap++;
- ap++;
- ap++;
- up++;
- }
-
- *ap = NULL;
-
- /*
- go home...
- */
- _toaos_fid(t_path, a_path);
-
- return;
- }
-
- /*
- aosvs$expand_pathname.c
-
- usage:
- err = aosvs$expand_pathname(c_path, x_path);
-
- where:
- data item name data type description
- ----------------------- ------------------ -----------------------------------
- err int Error return, if any.
- c_path char * Current pathname.
- x_path char * Expanded pathname returned here.
- This must be at least $MXPL bytes.
-
- -------------------------------------------------------------------------------
- edit history
-
- who mm/dd/yy rev # what.....................................................
- --- -------- ----- ---------------------------------------------------------
- dcr 03/02/89 01.00 birth, new life, creation...
-
- */
-
- /*
- aosvs$expand_pathname.c
-
- usage:
- err = aosvs$expand_pathname(c_path, x_path);
-
- where:
- data item name data type description
- ----------------------- ------------------ -----------------------------------
- err int Error return, if any.
- c_path char * Current pathname.
- x_path char * Expanded pathname returned here.
- This must be at least $MXPL bytes.
-
- -------------------------------------------------------------------------------
- edit history
-
- who mm/dd/yy rev # what.....................................................
- --- -------- ----- ---------------------------------------------------------
- dcr 03/02/89 01.00 birth, new life, creation...
-
- */
-
- int aosvs$expand_pathname(c_path, x_path)
-
- char *c_path, *x_path;
-
- {
- /*
- local variables
- */
- char t_path[$MXPL];
-
- /*
- things to do...
- */
- zero(t_path, $MXPL);
- aosvs$unix_to_aosvs_path(c_path, t_path);
-
- aosvs$ac2.in = $MXPL;
- aosvs$ac0.cptr = t_path;
- aosvs$ac1.cptr = x_path;
- if (sys($GRNAME, &aosvs$ac0, &aosvs$ac1, &aosvs$ac2))
- if ((aosvs$ac0.in == ERFDE) || (aosvs$ac0.in == ERFDE))
- strcpy(x_path, t_path);
- else
- return(1);
-
- return(0);
- }
-
- extern DIR *opendir();
- extern struct direct *readdir();
- extern long telldir();
- extern void seekdir();
- extern void closedir();
-
- #define rewinddir( dirp ) seekdir( dirp, 0L )
-
-
- /* FILE Directory routines */
-
- char gnfntmp[NFILEN]; /* wildcard template */
- char gnfnpath[NFILEN]; /* path of file to find */
- char gnfnrbuf[NFILEN]; /* return file buffer */
- DIR *gnfndir;
- struct direct *gnfndirect;
-
- char PASCAL NEAR *getnfile();
-
- /* do a template directory search (for file name completion) */
-
- char *PASCAL NEAR getffile(fspec)
-
- char *fspec; /* pattern to match */
-
- {
- register int index; /* index into various strings */
-
- /* clean up from our last time in here... */
- if (gnfndir) {
- closedir(gnfndir);
- free(gnfndir);
- }
-
- if (gnfndirect)
- free(gnfndirect);
-
- /* init. some things... */
- zero(gnfnpath, NFILEN);
- zero(gnfnrbuf, NFILEN);
- zero(gnfntmp, NFILEN);
- gnfndir = NULL;
- gnfndirect = NULL;
-
- /* first parse the file path off the file spec */
- strcpy(gnfnpath, fspec);
- index = strlen(gnfnpath) - 1;
- while (index >= 0 && (gnfnpath[index] != '/' &&
- gnfnpath[index] != '\\' && gnfnpath[index] != ':'))
- --index;
-
- gnfnpath[index+1] = 0;
-
- if ((gnfndir = opendir(gnfnpath)) == NULL)
- return(NULL);
-
- /* build the wildcard or template to use in the lookup */
- strcpy(gnfntmp, &fspec[index+1]);
- strcat(gnfntmp, "+");
- gnfndir->dd_buf = gnfntmp;
-
- return(getnfile());
- }
-
- char *PASCAL NEAR getnfile()
-
- {
- register int index; /* index into various strings */
-
- zero(gnfnrbuf, NFILEN); /* init return buffer */
-
- /* and call for the next file */
- if ((gnfndirect = readdir(gnfndir)) == NULL) {
- closedir(gnfndir);
- free(gnfndir);
- gnfndir = NULL;
- return(NULL);
- }
-
- /* return the next file name! */
- strcpy(gnfnrbuf, gnfnpath);
- strcat(gnfnrbuf, gnfndirect->d_name);
- mklower(gnfnrbuf);
- free(gnfndirect);
- gnfndirect = NULL;
- return(gnfnrbuf);
- }
-
- FILE *xxfopen(fn, mode) /* expand a pathname and open it */
-
- char *fn, *mode;
-
- {
- char tmppath[NFILEN]; /* temp. to hold expanded pathname */
-
- strcpy(tmppath, fn); /* load passed pathname */
- resolve_full_pathname(tmppath, tmppath); /* expand it... */
- return(fopen(tmppath, mode)); /* try to open expanded pathname */
- }
-
- #endif /* AOSVS */
-