home *** CD-ROM | disk | FTP | other *** search
/ Micro R&D 1 / MicroRD-CD-ROM-Vol1-1994.iso / os20 / cli / man16.lha / Man.c next >
Encoding:
C/C++ Source or Header  |  1993-12-16  |  13.0 KB  |  503 lines

  1. /*
  2. Auto:        sc <file>
  3. */
  4.  
  5. /* $Revision Header built automatically *************** (do not edit) ************
  6. **
  7. ** © Copyright by GuntherSoft
  8. **
  9. ** File             : SnakeSYS:CPrgs/Utils/Man.c
  10. ** Created on       : Friday, 16.07.93 18:00:23
  11. ** Created by       : Kai Iske
  12. ** Current revision : V1.6
  13. **
  14. **
  15. ** Purpose
  16. ** -------
  17. **   - This is a man program, which may scan different directories
  18. **     for man-pages. These directories are set within an ENV-VAR
  19. **     called MANPATHS. Additionally a VIEWER may be set using
  20. **     ENV-VAR MANVIEW (for plain ASCII) or MANVIEWAG (for
  21. **     AMIGAGUIDE). THIS ONE`S PURE AND IN THE PUBLIC DOMAIN
  22. **
  23. ** Revision V1.6
  24. ** --------------
  25. ** created on Thursday, 16.12.93 16:49:51  by  Kai Iske.   LogMessage :
  26. **   - Added MANRMEXT, MANAGEXT and MANNOVIEW options,
  27. **     which may be used for extensibility of MAN
  28. **     (Somehow suggested by : Michael 'Mick' Hohmann)
  29. **
  30. ** Revision V1.5
  31. ** --------------
  32. ** created on Thursday, 09.12.93 00:58:47  by  Kai Iske.   LogMessage :
  33. **   - Referenced free memory area
  34. **
  35. ** Revision V1.4
  36. ** --------------
  37. ** created on Wednesday, 08.12.93 22:07:47  by  Kai Iske.   LogMessage :
  38. **  -*-  created on Wednesday, 08.12.93 22:07:47  by  Kai Iske.   LogMessage :
  39. **   - DOS-Library wasn`t closed
  40. **
  41. ** Revision V1.3
  42. ** --------------
  43. ** created on Wednesday, 08.12.93 19:26:17  by  Kai Iske.   LogMessage :
  44. **  -*-  changed on Wednesday, 08.12.93 19:31:23  by  Kai Iske.   LogMessage :
  45. **   - Added CTRL-C checking
  46. **  -*-  created on Wednesday, 08.12.93 19:26:17  by  Kai Iske.   LogMessage :
  47. **   - Recompiled using SAS 6.50
  48. **   - Reduced stack usage
  49. **   - Reduced executable size
  50. **
  51. ** Revision V1.2
  52. ** --------------
  53. ** created on Tuesday, 27.07.93 15:20:51  by  Kai Iske.   LogMessage :
  54. **   - Used MAN as a keyword for the template which prevented MAN
  55. **     to accept inputs like "man man".
  56. **
  57. ** Revision V1.1
  58. ** --------------
  59. ** created on Monday, 26.07.93 17:42:32  by  Kai Iske.   LogMessage :
  60. **   - Accidentially called Exit() instead of exit(), which
  61. **     prevented the program to pass the cleanup code of SAS.
  62. **     So a lock to the directory was kept and the shell could
  63. **     never been left.............
  64. **
  65. ** Revision V1.0
  66. ** --------------
  67. ** created on Friday, 16.07.93 18:00:23  by  Kai Iske.   LogMessage :
  68. **  -*-  changed on Saturday, 17.07.93 16:30:41  by  Kai Iske.   LogMessage :
  69. **   - Man now searches for files that end up with .doc/.man/.guide
  70. **     If a .guide file is found, the second Viewer (MANVIEWAG)
  71. **     will be used to display the AmigaGuide viewer. Otherwise
  72. **     the normal viewer (MANVIEW) will be used
  73. **  -*-  created on Friday, 16.07.93 18:00:23  by  Kai Iske.   LogMessage :
  74. **     --- Initial release ---
  75. **
  76. *********************************************************************************/
  77. #define REVISION "1.6"
  78. #define REVDATE  "16.12.93"
  79. #define REVTIME  "16:49:51"
  80. #define AUTHOR   "Kai Iske"
  81. #define VERNUM   1
  82. #define REVNUM   6
  83.  
  84. #include    <string.h>
  85. #include    <stdlib.h>
  86. #include    <exec/types.h>
  87. #include    <exec/memory.h>
  88. #include    <exec/execbase.h>
  89. #include    <proto/exec.h>
  90. #include    <proto/dos.h>
  91. #include    <dos/dos.h>
  92. #include    <dos/exall.h>
  93. #include    <dos/dostags.h>
  94.  
  95.  
  96. /**********************************************************************/
  97. /*                             Prototypes                             */
  98. /**********************************************************************/
  99. char    *GetDir(char *NewName, char *OldName);
  100.  
  101.  
  102.  
  103. /**********************************************************************/
  104. /*                           Version-String                           */
  105. /**********************************************************************/
  106. static const char *Version = "$VER: Man "REVISION" ("REVDATE")\0";
  107.  
  108.  
  109. /**********************************************************************/
  110. /*                 Template for Command-Line parsing                  */
  111. /**********************************************************************/
  112. static char *Template    = "MANPAGE/A";
  113. enum {MAN_ARG};
  114.  
  115.  
  116.  
  117. /**********************************************************************/
  118. /*                       This is the main part                        */
  119. /**********************************************************************/
  120. ULONG __saveds main(void)
  121. {
  122.     struct    ExecBase    *SysBase;
  123.     struct    DOSLibrary    *DOSBase;
  124.     struct    Process        *MyProc;
  125.     struct    RDArgs        *RDArgs;
  126.     struct    ExAllControl    *EAC;
  127.     char    *MainBuffer    = NULL,
  128.         *ManPaths,
  129.         *ViewCmd,
  130.         *ViewCmdAG,
  131.         *CheckDir,
  132.         *SearchName,
  133.         *FileName,
  134.         *Pattern,
  135.         *NormExt,
  136.         *AGExt,
  137.         *NonExt;
  138.     APTR    *Args;
  139.     APTR    EAB;
  140.     char    *DirOffset;
  141.     BPTR    TestLock;
  142.     BPTR    OutHandle;
  143.     ULONG    MySig;
  144.     BOOL    Found        = FALSE,
  145.         Breaked        = FALSE,
  146.         GoOn;
  147.  
  148.         // Get Pointer to SysBase
  149.  
  150.     SysBase    = *((struct ExecBase **)0x4L);
  151.  
  152.         // Don`t start from WB
  153.  
  154.     MyProc    = (struct Process *)FindTask(NULL);
  155.  
  156.     if(!MyProc->pr_CLI)
  157.     {
  158.         struct    WBStartup    *Msg;
  159.  
  160.         WaitPort(&MyProc->pr_MsgPort);
  161.         Msg    = (struct WBStartup *)GetMsg(&MyProc->pr_MsgPort);
  162.         Disable();
  163.         ReplyMsg((struct Message *)Msg);
  164.         return(0);
  165.     }
  166.  
  167.         // Try to open DOSBase
  168.  
  169.     if(!(DOSBase    = (struct DOSLibrary *)OpenLibrary("dos.library", 0)))
  170.         return(20);
  171.  
  172.         // Get Out Handle
  173.  
  174.     OutHandle = Output();
  175.  
  176.         // Check for System we`re running on
  177.  
  178.     if(((struct Library *)SysBase)->lib_Version < 37)
  179.     {
  180.         Write(OutHandle, "You must use KickStart 2.04 (37.175) or higher for MAN\n", 55);
  181.         CloseLibrary((struct Library *)DOSBase);
  182.         return(20);
  183.     }
  184.  
  185.         // Get buffer for Commandline parsing
  186.  
  187.     if((Args = AllocVec((MAN_ARG + 1)*sizeof(ULONG), MEMF_CLEAR)))
  188.     {
  189.             // Get structure for ExAll()
  190.  
  191.         if((EAC = AllocDosObject(DOS_EXALLCONTROL, NULL)))
  192.         {
  193.                 // Get buffer for ExAll()
  194.  
  195.             if((EAB = AllocVec(sizeof(struct ExAllData)*20, MEMF_CLEAR)))
  196.             {
  197.                     // Try to parse commandline
  198.  
  199.                 if((RDArgs = ReadArgs(Template, (LONG *)Args, NULL)))
  200.                 {
  201.                     if((MainBuffer = AllocVec((1024 * 10), MEMF_CLEAR)))
  202.                     {
  203.                             // Set up pointers to buffers
  204.  
  205.                         ManPaths    = MainBuffer;
  206.                         ViewCmd        = (ManPaths + 1024);
  207.                         ViewCmdAG    = (ViewCmd + 1024);
  208.                         CheckDir    = (ViewCmdAG + 1024);
  209.                         SearchName    = (CheckDir + 1024);
  210.                         FileName    = (SearchName + 1024);
  211.                         Pattern        = (FileName + 1024);
  212.                         NormExt        = (Pattern + 1024);
  213.                         AGExt        = (NormExt + 1024);
  214.                         NonExt        = (AGExt + 1024);
  215.  
  216.                             // Rearrange pointer
  217.  
  218.                         DirOffset    = ManPaths;
  219.  
  220.                             // Try to get MANPATHS Env-Variable
  221.  
  222.                         if(GetVar("MANPATHS", ManPaths, 1024, GVF_GLOBAL_ONLY) >= 1)
  223.                         {
  224.                                 // Try to get MANVIEW Env-Variable
  225.  
  226.                             if(GetVar("MANVIEW", ViewCmd, 1024, GVF_GLOBAL_ONLY) >= 1)
  227.                             {
  228.                                     // Try to get MANVIEWAG Env-Variable
  229.  
  230.                                 if(GetVar("MANVIEWAG", ViewCmdAG, 1024, GVF_GLOBAL_ONLY) >= 1)
  231.                                 {
  232.                                         // Per default use the ASCII viewer for "non-extension" files
  233.  
  234.                                     strcpy(NonExt, ViewCmd);
  235.  
  236.                                         // Get additional patterns for normal texts
  237.  
  238.                                     GetVar("MANNRMEXT", NormExt, 1024, GVF_GLOBAL_ONLY);
  239.  
  240.                                         // Get additional patterns for AmigaGuide texts
  241.  
  242.                                     GetVar("MANAGEXT", AGExt, 1024, GVF_GLOBAL_ONLY);
  243.  
  244.                                         // Get nam of viewer to use when no extension was found
  245.  
  246.                                     GetVar("MANNOVIEW", NonExt, 1024, GVF_GLOBAL_ONLY);
  247.  
  248.                                         // Set pattern for ExAll() search
  249.  
  250.                                     strcpy(SearchName, Args[MAN_ARG]);
  251.  
  252.                                         // Append patterns
  253.  
  254.                                     strcat(SearchName, "(.doc|.man|.guide|");
  255.                                     strcat(SearchName, NormExt);
  256.                                     strcat(SearchName, "|");
  257.                                     strcat(SearchName, AGExt);
  258.                                     strcat(SearchName, "|)");
  259.  
  260.                                         // Parse the pattern
  261.  
  262.                                     if(ParsePatternNoCase(SearchName, Pattern, 1024) != -1)
  263.                                     {
  264.  
  265.                                             // Loop for all dirs and wait until file has been found
  266.  
  267.                                         while(!Found && !Breaked && DirOffset)
  268.                                         {
  269.                                             MySig    = CheckSignal(SIGBREAKF_CTRL_C);
  270.  
  271.                                             if(!(MySig & SIGBREAKF_CTRL_C))
  272.                                             {
  273.                                                     // Extract next directory from list
  274.  
  275.                                                 DirOffset = GetDir(CheckDir, DirOffset);
  276.  
  277.                                                     // Add "/" if neither "/", nor ":" end the directory
  278.  
  279.                                                 if((CheckDir[strlen(CheckDir) - 1] != '/') && (CheckDir[strlen(CheckDir) - 1] != ':'))
  280.                                                     strcat(CheckDir, "/");
  281.  
  282.                                                     // Directory available ???
  283.  
  284.                                                 if((TestLock = Lock(CheckDir, ACCESS_READ)))
  285.                                                 {
  286.                                                         // Fill in ExAll structure
  287.  
  288.                                                     EAC->eac_LastKey    = 0;
  289.                                                     EAC->eac_MatchString    = Pattern;
  290.                                                     EAC->eac_MatchFunc    = NULL;
  291.  
  292.                                                     do
  293.                                                     {
  294.                                                         MySig = CheckSignal(SIGBREAKF_CTRL_C);
  295.                                                         if((MySig & SIGBREAKF_CTRL_C))
  296.                                                             Breaked = TRUE;
  297.  
  298.                                                             // Do the scanning
  299.  
  300.                                                         GoOn = ExAll(TestLock, EAB, (20*sizeof(struct ExAllData)), ED_NAME, EAC);
  301.  
  302.                                                             // Error occured ???
  303.  
  304.                                                         if((!GoOn) && (IoErr() != ERROR_NO_MORE_ENTRIES))
  305.                                                             PrintFault(IoErr(), "Man ");
  306.  
  307.                                                             // End of dir reached ;
  308.  
  309.                                                         if(EAC->eac_Entries == 0)
  310.                                                             GoOn = FALSE;
  311.                                                         else if(!Breaked)
  312.                                                         {
  313.                                                                 // Get first name matching
  314.  
  315.                                                             strcpy(FileName, ((struct ExAllData *)EAB)->ed_Name);
  316.  
  317.                                                                 // Check extension to decide whether it`s an AmigaGuide file
  318.  
  319.                                                             if(strchr(FileName, '.'))
  320.                                                             {
  321.                                                                 char    *ExtPtr    = AGExt,
  322.                                                                     *DelPtr;
  323.                                                                 int    ExtLen;
  324.                                                                 BOOL    FoundAG    = FALSE;
  325.  
  326.                                                                     // Append default .guide extension and additional
  327.                                                                     // seperator for ease of calculating the length
  328.  
  329.                                                                 strcat(ExtPtr, "|.guide|");
  330.  
  331.                                                                     // Loop for all extensions
  332.  
  333.                                                                 while(!FoundAG && (ExtPtr = strchr(ExtPtr, '.')))
  334.                                                                 {
  335.                                                                         // Calc len of extension
  336.  
  337.                                                                     DelPtr    = strchr(ExtPtr, '|');
  338.                                                                     ExtLen    = DelPtr - ExtPtr;
  339.  
  340.                                                                     if(!strnicmp(&FileName[strlen(FileName) - ExtLen], ExtPtr, ExtLen))
  341.                                                                         FoundAG    = TRUE;
  342.  
  343.                                                                     ExtPtr++;
  344.                                                                 }
  345.  
  346.                                                                     // Now set view command accordingly
  347.  
  348.                                                                 if(!FoundAG)
  349.                                                                     strcpy(SearchName, ViewCmd);
  350.                                                                 else
  351.                                                                     strcpy(SearchName, ViewCmdAG);
  352.  
  353.                                                                     // Set flag that we`ve found the file
  354.  
  355.                                                                 Found = TRUE;
  356.                                                             }
  357.                                                             else
  358.                                                             {
  359.                                                                     // Only use default viewer for non-extension files, when not set to ""
  360.  
  361.                                                                 if(strlen(NonExt))
  362.                                                                 {
  363.                                                                         // No extension use default viewer
  364.  
  365.                                                                     strcpy(SearchName, NonExt);
  366.                                                                     
  367.                                                                         // Set flag that the entry was found
  368.  
  369.                                                                     Found = TRUE;
  370.                                                                 }
  371.                                                             }
  372.  
  373.                                                                 // Append directory and FileName
  374.  
  375.                                                             strcat(SearchName, " ");
  376.                                                             strcat(SearchName, CheckDir);
  377.  
  378.                                                                 // Copy Filename to place where the last quote used to reside
  379.  
  380.                                                             strcat(SearchName, FileName);
  381.                                                         }
  382.                                                     } while(GoOn);
  383.  
  384.                                                         // Unlock Directory
  385.  
  386.                                                     UnLock(TestLock);
  387.                                                 }
  388.                                                 else
  389.                                                 {
  390.                                                         // Display message
  391.  
  392.                                                     FPuts(OutHandle, "Skipping directory; not existent : ");
  393.                                                     FPuts(OutHandle, CheckDir);
  394.                                                     FPuts(OutHandle, "\n");
  395.                                                 }
  396.                                             }
  397.                                             else
  398.                                                 Breaked = TRUE;
  399.                                         }
  400.  
  401.                                         if(!Found)
  402.                                             strcpy(FileName, Args[MAN_ARG]);
  403.  
  404.                                     }
  405.                                     else
  406.                                         PrintFault(IoErr(), "Man ");
  407.                                 }
  408.                                 else
  409.                                     PrintFault(IoErr(), "MANVIEWAG ");
  410.                             }
  411.                             else
  412.                                 PrintFault(IoErr(), "MANVIEW ");
  413.                         }
  414.                         else
  415.                             PrintFault(IoErr(), "MANPATHS ");
  416.                     }
  417.                     else
  418.                         PrintFault(ERROR_NO_FREE_STORE, "Man ");
  419.  
  420.                     FreeArgs(RDArgs);
  421.                 }
  422.                 else
  423.                     PrintFault(IoErr(), "Man ");
  424.  
  425.                 FreeVec(EAB);
  426.             }
  427.             else
  428.                 FPuts(OutHandle, "Could not allocate buffer for ExAll()\n");
  429.  
  430.             FreeDosObject(DOS_EXALLCONTROL, (void *)EAC);
  431.         }
  432.         else
  433.             FPuts(OutHandle, "Could not allocate structure for ExAll()\n");
  434.  
  435.         FreeVec(Args);
  436.     }
  437.     else
  438.         FPuts(OutHandle, "Could not allocate buffer for CommandLine Parsing\n");
  439.  
  440.     if(Found && !Breaked)
  441.     {
  442.         SystemTags(SearchName, TAG_DONE);
  443.  
  444.             // Free buffers
  445.  
  446.         if(MainBuffer)
  447.             FreeVec(MainBuffer);
  448.  
  449.         CloseLibrary((struct Library *)DOSBase);
  450.         return(0);
  451.     }
  452.     else if(Args && RDArgs)
  453.     {
  454.         if(!Breaked)
  455.         {
  456.             FPuts(OutHandle, "Man-Pages not found for : ");
  457.             FPuts(OutHandle, FileName);
  458.             FPuts(OutHandle, "\n");
  459.         }
  460.         else
  461.             FPuts(OutHandle, "Man : ^C...\n");
  462.  
  463.             // Free buffers
  464.  
  465.         if(MainBuffer)
  466.             FreeVec(MainBuffer);
  467.  
  468.         CloseLibrary((struct Library *)DOSBase);
  469.         return(10);
  470.     }
  471.  
  472.     if(MainBuffer)
  473.         FreeVec(MainBuffer);
  474.  
  475.     CloseLibrary((struct Library *)DOSBase);
  476.     return(20);
  477. }
  478.  
  479.  
  480.  
  481.  
  482.  
  483. /**********************************************************************/
  484. /*          Get portions from the Env-Var -> Next directory           */
  485. /**********************************************************************/
  486. char *GetDir(char *NewDir, char *OldDir)
  487. {
  488.     while(*OldDir == ' ')
  489.         OldDir++;
  490.  
  491.     while((*OldDir != '\n') && (*OldDir != '\0') && (*OldDir != '|') && (*OldDir != ','))
  492.         *NewDir++ = *OldDir++;
  493.  
  494.     *NewDir        = '\0';
  495.  
  496.     if(*OldDir == '\n' || *OldDir == '\0')
  497.         OldDir = NULL;
  498.     else
  499.         OldDir++;
  500.  
  501.     return(OldDir);
  502. }
  503.