home *** CD-ROM | disk | FTP | other *** search
- /*
- Mr - Pager for piped files.
-
- Original effort by Fabio Rossetti.
-
- (c) 1989 by Fabio Rossetti
-
- To compile under Lattice C v5.0x use:
-
- lc -O -v s
- blink lib:cres.o s.o to s lib lib:a.lib lib:lc.lib sd nd
- */
-
- #include <exec/types.h>
- #include <exec/ports.h>
- #include <exec/io.h>
- #include <exec/memory.h>
- #include <exec/libraries.h>
-
- #include <devices/console.h>
- #include <devices/conunit.h>
-
- #include <libraries/dos.h>
- #include <libraries/dosextens.h>
- #include <libraries/arpbase.h>
-
-
- #include <arpfunctions.h>
- #include <proto/exec.h>
- #include <proto/intuition.h>
- #include <proto/dos.h>
-
- #include <intuition/intuitionbase.h>
- #include <intuition/intuition.h>
-
- #include <graphics/text.h>
-
- #define BFSIZE 1024
- #define LINSIZE 512
-
- #define ENDFILE 0
- #define FORMFEED -1
- #define LINEOK 1
-
- /* command line arguments */
-
- /* */
- /* global */
- /* */
-
- struct ArpBase *ArpBase;
- struct IntuitionBase *IntuitionBase;
- struct Window *CliWin; /* poUSHORTer to console window */
- struct Process *Pr;
-
-
- USHORT dsplin,x,y,xf,yf,count,bp=0;
- BPTR stdi;
- TEXT *Buf,*Lin;
- TEXT *Morpos="\033[0;0H\033[000;2H\033[7m\033[3m ";
- #define CYPOS 8
- #define CYOFF 48
- struct Window *w;
-
- /* this is exec stuff for GetWin, to be kept global for Cleanup() */
- struct MsgPort iorp = {
- {0, 0, NT_MSGPORT, 0, 0}, 0,
- -1, /* initialize signal to -1 */
- 0,
- /* start with empty list */
- {&iorp.mp_MsgList.lh_Tail, 0, &iorp.mp_MsgList.lh_Head, 0, 0}
- };
- struct IOStdReq ior = {
- {{0, 0, 0, 0, 0}, &iorp, 0},
- 0 /* device is zero */
- };
-
- VOID MemCleanup()
- {
- }
-
- /* general shutdown routine*/
- VOID Cleanup(code,retcode,msg)
- LONG code;
- LONG retcode;
- STRPTR msg;
- {
- if (ior.io_Device != 0) {
- if (iorp.mp_SigBit != -1) {
- FreeSignal(iorp.mp_SigBit);
- }
- CloseDevice(&ior);
- }
-
- CloseLibrary((struct Library*)ArpBase);
-
- if (msg) Puts(msg);
-
- Pr->pr_Result2=retcode;
-
- exit(code);
- }
- /* bulletproofly obtain a pointer to the CLI window sending a ACTION_DISK_INFO
- packet to the console process and looking into InfoData */
- struct Window *GetWin(mode)
- USHORT mode;
- #define RAW -1
- #define CON 0
- #define POINTER 1
-
- {
- struct MsgPort *con;
- struct StandardPacket *packet=NULL;
- struct InfoData *id=NULL;
-
- /* open the console device */
- if ((OpenDevice("console.device", -1, &ior, 0)) != 0) {
- Cleanup(RETURN_FAIL,ERROR_DEVICE_NOT_MOUNTED,NULL);
- }
-
- /* set up the message port in the I/O request */
- if ((iorp.mp_SigBit = AllocSignal(-1)) < 0) {
- Cleanup(RETURN_FAIL,ERROR_NO_FREE_STORE,"No mem");
- }
- iorp.mp_SigTask = (struct Task*)Pr;
-
- /* try to find console associated with calling process */
- /* if started from CLI, than is */
- if ((iorp.mp_SigTask->tc_Node.ln_Type == NT_PROCESS)) {
- con = (struct MsgPort *)
- ((struct Process *) iorp.mp_SigTask) -> pr_ConsoleTask;
- if (con != 0) {
- if ((packet = (struct StandardPacket *)
- ArpAlloc(sizeof(*packet)))) {
-
- /* this is the console handlers packet port */
- packet->sp_Msg.mn_Node.ln_Name = &(packet->sp_Pkt);
- packet->sp_Pkt.dp_Link = &(packet->sp_Msg);
- packet->sp_Pkt.dp_Port = &iorp;
- if (mode == POINTER) {
- if (!(id = (struct id *) ArpAlloc(sizeof(*id))))
- return((struct Window *)-1);
- packet->sp_Pkt.dp_Type = ACTION_DISK_INFO;
- packet->sp_Pkt.dp_Arg1 = ((ULONG) id) >> 2;
- }
- else {
- packet->sp_Pkt.dp_Type = ACTION_SCREEN_MODE;
- packet->sp_Pkt.dp_Arg1 = mode;
- }
- PutMsg(con, packet);
- WaitPort(&iorp);
- /* Pointer to console window, all we need..*/
- if (mode == POINTER)
- return( (struct Window*)(id->id_VolumeNode));
- else return(0);
- }
- }
- /* error */
- return((struct Window *)-1);
- }
- }
-
- VOID Clear(fl)
- BPTR fl;
- {
- (VOID)Write(fl,"\033[0;0H\033[J",9);
- dsplin = 0;
- x = (w->Width-24) / xf;
- y = (w->Height-16) / yf;
- }
-
- TEXT Banner(fl,ban)
- BPTR fl;
- STRPTR ban;
- {
-
- TEXT ch;
- USHORT j = y+1;
-
- Morpos[CYPOS] = (TEXT)((j / 100) + CYOFF);
- Morpos[CYPOS+1] = (TEXT)(((j - ((j / 100)*100)) / 10) + CYOFF);
- Morpos[CYPOS+2] =
- (TEXT)((j - ((j / 100)*100) - ((j - ((j / 100)*100)) / 10)*10) + CYOFF);
-
-
- (VOID)Write(fl,Morpos,strlen(Morpos));
- (VOID)Write(fl,ban,strlen(ban));
- /* hide crsr */
- (VOID)Write(fl," \033[0m\033[K\033[43m \010",16);
-
- (VOID)Read(fl,&ch,1);
- (VOID)Write(fl,"\033[0m",4);
-
- return(ch);
- }
-
- Displine(fl)
- BPTR fl;
- {
-
- REGISTER TEXT chr;
- REGISTER ULONG ln = 0,actlin=0;
-
- for (;;) {
-
- if(!bp) if (!(count = Read(stdi,Buf,BFSIZE))) {
- return(ENDFILE);
- }
-
- chr = *(Buf + bp++);
-
- *(Lin + ln++) = chr;
- actlin++;
- switch (chr) {
-
- case '\n':
- Write(fl,Lin,ln);
- dsplin++;
- if (bp >= count) bp = 0;
- return(LINEOK);
- break;
- case '\t':
- actlin+=8;
- break;
- case '\010': /* backspace */
- actlin--;
- break;
- case '\014':
- Write(fl,Lin,ln-1);
- Write(fl,"\n^L",3);
- if (bp >= count) bp = 0;
- return(FORMFEED);
- break;
- }
- if (actlin >= x) {
- Write(fl,Lin,ln);
- dsplin++;
- if (bp >= count) bp = 0;
- return (LINEOK);
- }
- if (bp >= count) bp = 0;
- }
- }
-
- VOID Bye(fl)
- BPTR fl;
- {
- Write(fl,"\015\033[K",4);
- (VOID)GetWin(CON);
- Cleanup(RETURN_OK,NULL,NULL);
- }
-
- /* _main used instead of main to slim code */
- VOID _main(Line)
- STRPTR Line;
-
- {
-
- BPTR fil;
- ULONG st;
- TEXT c;
-
- Pr = (struct Process *) FindTask(NULL);
- if(!(ArpBase = (struct ArpBase*)OpenLibrary(ArpName,ArpVersion)))
- Cleanup(RETURN_FAIL,ERROR_INVALID_RESIDENT_LIBRARY,NULL);
-
-
- if (!(Buf = ArpAllocMem(BFSIZE,MEMF_CLEAR)) ||
-
- !(Lin = ArpAllocMem(LINSIZE,MEMF_CLEAR)))
- Cleanup(RETURN_FAIL,ERROR_NO_FREE_STORE,"No mem");
-
- stdi = Input();
-
- if (IsInteractive(stdi)) Cleanup(RETURN_ERROR,NULL,"Use a pipe");
-
- w = GetWin(POINTER);
-
- xf = w->RPort->Font->tf_XSize;
- yf = w->RPort->Font->tf_YSize;
-
- (VOID)GetWin(RAW);
-
- fil = Open("*",MODE_OLDFILE);
-
-
- for (;;) {
-
- Clear(fil);
- while (dsplin <= (y-1)) {
-
- if ((st = Displine(fil)) != LINEOK) break;
-
- }
-
- if (st == ENDFILE) {
- Banner(fil,"--End of file--");
- break;
- }
- else {
-
- /* Goodbye Mr Wirth :-) */
- more:
- switch(c = Banner(fil,"--More--")) {
-
- case ' ':
- break;
- case 'q':
- Bye(fil);
- break;
- case '\003':
- Bye(fil);
- break;
- case '\015':
- Write(fil,"\015\033[K",4);
- Displine(fil);
- goto more;
- break;
- default:
- Banner(fil,"--???--");
- }
- }
- }
- Bye(fil);
- }
-
-