home *** CD-ROM | disk | FTP | other *** search
/ Gold Fish 3 / goldfish_volume_3.bin / files / util / cli / man / man.c < prev    next >
C/C++ Source or Header  |  1994-03-04  |  25KB  |  991 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.11
  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.11
  24. ** --------------
  25. ** created on Monday, 28.02.94 19:33:29  by  Kai Iske.   LogMessage :
  26. **  -*-  changed on Saturday, 05.03.94 02:30:54  by  Kai Iske.   LogMessage :
  27. **   - Man produced an enforcer hit when no manpage was supplied
  28. **     (Reported by : Michael van Elst)
  29. **  -*-  changed on Monday, 28.02.94 20:03:34  by  Kai Iske.   LogMessage :
  30. **   - Man will no longer issue an error if you a) didn`t specify a
  31. **     manpage and b) set the MANGETFILE attribute for the File
  32. **     Requester. This way the Requester will popup if you
  33. **     call MAN without any arguments
  34. **     (Requested by : Bill Hogsett)
  35. **  -*-  changed on Monday, 28.02.94 20:02:39  by  Kai Iske.   LogMessage :
  36. **   - The FileRequester will pop up on the default PubScreen now
  37. **     (Requested by : Bill Hogsett)
  38. **   - The default path for the FileRequester will be set to the
  39. **     first Dir of the MANPATHS now
  40. **     (Requested by : Bill Hogsett)
  41. **  -*-  created on Monday, 28.02.94 19:33:29  by  Kai Iske.   LogMessage :
  42. **   - Support for DVI files added
  43. **   - MAN will set the Viewer`s current dir of that where the
  44. **     man page resides in
  45. **
  46. ** Revision V1.10
  47. ** --------------
  48. ** created on Tuesday, 25.01.94 14:41:58  by  Kai Iske.   LogMessage :
  49. **   - Mike Barsoom added MANBASENAME attribute for stripping
  50. **     off any path names from the manpage name. Useful when
  51. **     launching MAN from within (ie) ToolsDaemon
  52. **     (Submitted by : Mike Barsoom)
  53. **
  54. ** Revision V1.9
  55. ** --------------
  56. ** created on Sunday, 23.01.94 21:36:26  by  Kai Iske.   LogMessage :
  57. **   - Recompiled using SAS/C 6.51
  58. **   - Added MANGETFILE parameter
  59. **     (Requested by : Bill Hogsett)
  60. **
  61. ** Revision V1.8
  62. ** --------------
  63. ** created on Saturday, 15.01.94 01:14:17  by  Kai Iske.   LogMessage :
  64. **   - Man now correctly handles multi-assigns, since ExAll
  65. **     doesn`t....;)
  66. **     (Reported by : Jan Hoeydahl)
  67. **
  68. ** Revision V1.7
  69. ** --------------
  70. ** created on Friday, 31.12.93 14:00:28  by  Kai Iske.   LogMessage :
  71. **   - All config variables have been moved to a single one,
  72. **     which will be parsed just like a CommandLine
  73. **     (Suggested by : Michael 'Mick' Hohmann)
  74. **
  75. ** Revision V1.6
  76. ** --------------
  77. ** created on Thursday, 16.12.93 16:49:51  by  Kai Iske.   LogMessage :
  78. **   - Added MANRMEXT, MANAGEXT and MANNOVIEW options,
  79. **     which may be used for extensibility of MAN
  80. **     (Somehow suggested by : Michael 'Mick' Hohmann)
  81. **
  82. ** Revision V1.5
  83. ** --------------
  84. ** created on Thursday, 09.12.93 00:58:47  by  Kai Iske.   LogMessage :
  85. **   - Referenced free memory area
  86. **
  87. ** Revision V1.4
  88. ** --------------
  89. ** created on Wednesday, 08.12.93 22:07:47  by  Kai Iske.   LogMessage :
  90. **  -*-  created on Wednesday, 08.12.93 22:07:47  by  Kai Iske.   LogMessage :
  91. **   - DOS-Library wasn`t closed
  92. **
  93. ** Revision V1.3
  94. ** --------------
  95. ** created on Wednesday, 08.12.93 19:26:17  by  Kai Iske.   LogMessage :
  96. **  -*-  changed on Wednesday, 08.12.93 19:31:23  by  Kai Iske.   LogMessage :
  97. **   - Added CTRL-C checking
  98. **  -*-  created on Wednesday, 08.12.93 19:26:17  by  Kai Iske.   LogMessage :
  99. **   - Recompiled using SAS 6.50
  100. **   - Reduced stack usage
  101. **   - Reduced executable size
  102. **
  103. ** Revision V1.2
  104. ** --------------
  105. ** created on Tuesday, 27.07.93 15:20:51  by  Kai Iske.   LogMessage :
  106. **   - Used MAN as a keyword for the template which prevented MAN
  107. **     to accept inputs like "man man".
  108. **
  109. ** Revision V1.1
  110. ** --------------
  111. ** created on Monday, 26.07.93 17:42:32  by  Kai Iske.   LogMessage :
  112. **   - Accidentially called Exit() instead of exit(), which
  113. **     prevented the program to pass the cleanup code of SAS.
  114. **     So a lock to the directory was kept and the shell could
  115. **     never been left.............
  116. **
  117. ** Revision V1.0
  118. ** --------------
  119. ** created on Friday, 16.07.93 18:00:23  by  Kai Iske.   LogMessage :
  120. **  -*-  changed on Saturday, 17.07.93 16:30:41  by  Kai Iske.   LogMessage :
  121. **   - Man now searches for files that end up with .doc/.man/.guide
  122. **     If a .guide file is found, the second Viewer (MANVIEWAG)
  123. **     will be used to display the AmigaGuide viewer. Otherwise
  124. **     the normal viewer (MANVIEW) will be used
  125. **  -*-  created on Friday, 16.07.93 18:00:23  by  Kai Iske.   LogMessage :
  126. **     --- Initial release ---
  127. **
  128. *********************************************************************************/
  129. #define REVISION "1.11a"
  130. #define REVDATE  "05.03.94"
  131. #define REVTIME  "02:30:54"
  132. #define AUTHOR   "Kai Iske"
  133. #define VERNUM   1
  134. #define REVNUM   11
  135.  
  136.  
  137.  
  138. #define        _USE_SYSBASE
  139.  
  140.  
  141.  
  142. /**********************************************************************/
  143. /*         This is, so that the code references our Libraries         */
  144. /*                      stored in our structure                       */
  145. /**********************************************************************/
  146. #define        DOSBase        MC->mc_DOSBase
  147. #define        UtilityBase    MC->mc_UtilityBase
  148.  
  149.  
  150. #include    <string.h>
  151. #include    <stdlib.h>
  152. #include    <exec/types.h>
  153. #include    <exec/memory.h>
  154. #include    <exec/execbase.h>
  155. #include    <libraries/asl.h>
  156. #include    <dos/dos.h>
  157. #include    <dos/exall.h>
  158. #include    <dos/dostags.h>
  159. #include    <proto/exec.h>
  160. #include    <proto/asl.h>
  161. #include    <clib/dos_protos.h>
  162. #include    <clib/utility_protos.h>
  163. #include    <pragmas/dos_pragmas.h>
  164. #include    <pragmas/utility_pragmas.h>
  165.  
  166.  
  167.  
  168.  
  169. /**********************************************************************/
  170. /*             This is the private structure for all vars             */
  171. /**********************************************************************/
  172. struct ManControl
  173. {
  174.     struct    DOSLibrary    *mc_DOSBase;
  175.     struct    Library        *mc_UtilityBase;
  176.     struct    ExAllControl    *mc_EAC;
  177.     char            mc_ManOpt[1536],
  178.                 mc_ManPaths[1024],
  179.                 mc_ViewCmd[1024],
  180.                 mc_ViewCmdAG[1024],
  181.                 mc_ViewCmdDVI[1024],
  182.                 mc_CheckDir[1024],
  183.                 mc_SearchName[1536],
  184.                 mc_FileName[1024],
  185.                 mc_Pattern[3074],
  186.                 mc_NormExt[1024],
  187.                 mc_AGExt[1024],
  188.                 mc_DVIExt[1024],
  189.                 mc_NameBuffer[1024],
  190.                 mc_NonExt[1024];
  191.     APTR            *mc_EAB;
  192.     BPTR            mc_OutHandle;
  193.     BOOL            mc_Found,
  194.                 mc_Breaked;
  195. };
  196.  
  197.  
  198.  
  199.  
  200.  
  201.  
  202. /**********************************************************************/
  203. /*                             Prototypes                             */
  204. /**********************************************************************/
  205. static char    *GetDir(char *NewName, char *OldName);
  206. static BOOL    DoCheckDir(struct ManControl *MC);
  207. static BOOL    IsAssign(struct ManControl *MC);
  208. static void    DetermineFileType(struct ManControl *MC);
  209.  
  210.  
  211.  
  212.  
  213.  
  214. /**********************************************************************/
  215. /*                           Version-String                           */
  216. /**********************************************************************/
  217. static const char *Version    = "$VER: Man "REVISION" ("REVDATE")\0";
  218.  
  219.  
  220.  
  221.  
  222. /**********************************************************************/
  223. /*                 Template for Command-Line parsing                  */
  224. /**********************************************************************/
  225. static const char *Template    = "MANPAGE";
  226. enum {MAN_ARG, TMP_LAST_ARG};
  227.  
  228.  
  229.  
  230.  
  231. /**********************************************************************/
  232. /*                    Template for MANOPT settings                    */
  233. /**********************************************************************/
  234. static const char *ManTemplate    = "MANPATHS/K/A,MANVIEW/K/A,MANVIEWAG/K/A,MANVIEWDVI/K/A,MANNRMEXT/K,MANAGEXT/K,MANDVIEXT/K,MANNOVIEW/K,MANGETFILE/S,MANBASENAME/S";
  235. enum {MANPATHS_ARG, MANVIEW_ARG, MANVIEWAG_ARG, MANVIEWDVI_ARG, MANNRMEXT_ARG, MANAGEXT_ARG, MANDVIEXT_ARG, MANNOVIEW_ARG, MANGETFILE_ARG, MANBASENAME_ARG, MAN_LAST_ARG};
  236.  
  237.  
  238.  
  239.  
  240.  
  241.  
  242. /**********************************************************************/
  243. /*                       This is the main part                        */
  244. /**********************************************************************/
  245. ULONG __saveds main(void)
  246. {
  247.     struct    ManControl    *MC;
  248.     struct    Process        *MyProc;
  249.     struct    RDArgs        *RDArgs,
  250.                 *ManRDArgs;
  251.     APTR            *Args,
  252.                 *ManArgs;
  253.     ULONG            MySig;
  254.     char            *DirOffset;
  255.     BOOL            StartedSearch    = FALSE,
  256.                 UseAsl        = FALSE,
  257.                 GotManPage;
  258.  
  259.  
  260.  
  261.         // Allocate control structure
  262.  
  263.     if(!(MC = AllocVec(sizeof(struct ManControl), MEMF_CLEAR)))
  264.         return(20);
  265.  
  266.     MC->mc_Found        = FALSE;
  267.     MC->mc_Breaked        = FALSE;
  268.  
  269.  
  270.  
  271.  
  272.         // Don`t start from WB
  273.  
  274.     MyProc    = (struct Process *)FindTask(NULL);
  275.  
  276.     if(!MyProc->pr_CLI)
  277.     {
  278.         struct    WBStartup    *Msg;
  279.  
  280.         WaitPort(&MyProc->pr_MsgPort);
  281.         Msg    = (struct WBStartup *)GetMsg(&MyProc->pr_MsgPort);
  282.  
  283.         Disable();
  284.         ReplyMsg((struct Message *)Msg);
  285.         FreeVec(MC);
  286.  
  287.         return(0);
  288.     }
  289.  
  290.  
  291.  
  292.         // Try to open DOSBase
  293.  
  294.     if(!(DOSBase    = (struct DOSLibrary *)OpenLibrary("dos.library", 0)))
  295.     {
  296.         FreeVec(MC);
  297.         return(20);
  298.     }
  299.  
  300.  
  301.         // Get Out Handle
  302.  
  303.     MC->mc_OutHandle = Output();
  304.  
  305.  
  306.  
  307.         // Check for System we`re running on
  308.  
  309.     if(((struct Library *)*((ULONG **)0x4L))->lib_Version < 37)
  310.     {
  311.         Write(MC->mc_OutHandle, "You must use KickStart 2.04 (37.175) or higher for MAN\n", 55);
  312.  
  313.             // Close library
  314.  
  315.         CloseLibrary((struct Library *)DOSBase);
  316.             // Free buffer
  317.  
  318.         FreeVec(MC);
  319.         return(20);
  320.     }
  321.  
  322.  
  323.         // Try to open UtilityBase
  324.  
  325.     if(!(UtilityBase = OpenLibrary("utility.library", 0)))
  326.     {
  327.         CloseLibrary((struct Library *)DOSBase);
  328.         FreeVec(MC);
  329.         return(20);
  330.     }
  331.  
  332.  
  333.         // Get buffer for Commandline parsing
  334.  
  335.     if((Args = AllocVec(TMP_LAST_ARG * sizeof(ULONG), MEMF_CLEAR)))
  336.     {
  337.             // Get buffer for MANOPT parsing
  338.  
  339.         if((ManArgs = AllocVec(MAN_LAST_ARG * sizeof(ULONG), MEMF_CLEAR)))
  340.         {
  341.                 // Get RDArgs structure for MANOPT parsing
  342.  
  343.             if((ManRDArgs = AllocDosObject(DOS_RDARGS, NULL)))
  344.             {
  345.                     // Get structure for ExAll()
  346.  
  347.                 if((MC->mc_EAC = AllocDosObject(DOS_EXALLCONTROL, NULL)))
  348.                 {
  349.                         // Get buffer for ExAll()
  350.  
  351.                     if((MC->mc_EAB = AllocVec(sizeof(struct ExAllData)*20, MEMF_CLEAR)))
  352.                     {
  353.                             // Try to parse commandline
  354.  
  355.                         if((RDArgs = ReadArgs((char *)Template, (LONG *)Args, NULL)))
  356.                         {
  357.                                 // Rearrange pointer to paths
  358.  
  359.                             DirOffset    = MC->mc_ManPaths;
  360.  
  361.                                 // Did we get a manpage ?!?
  362.  
  363.                             GotManPage    = (BOOL)(Args[MAN_ARG] != NULL);
  364.  
  365.  
  366.                                 // Try to get MANOPT Env-Variable
  367.  
  368.                             if(GetVar("MANOPT", MC->mc_ManOpt, 2048, GVF_GLOBAL_ONLY) >= 1)
  369.                             {
  370.                                     // Try to parse strings
  371.  
  372.                                 strcat(MC->mc_ManOpt, "\n");
  373.                                 ManRDArgs->RDA_Source.CS_Buffer    = MC->mc_ManOpt;
  374.                                 ManRDArgs->RDA_Source.CS_Length    = strlen(MC->mc_ManOpt);
  375.                                 ManRDArgs->RDA_Source.CS_CurChr    = 0;
  376.                                 ManRDArgs->RDA_DAList        = NULL;
  377.                                 ManRDArgs->RDA_Buffer        = NULL;
  378.                                 ManRDArgs->RDA_BufSiz        = 0;
  379.                                 ManRDArgs->RDA_ExtHelp        = NULL;
  380.                                 ManRDArgs->RDA_Flags        = 0;
  381.  
  382.                                     // Try to parse MANOPT variable
  383.  
  384.                                 if(ReadArgs((char *)ManTemplate, (LONG *)ManArgs, ManRDArgs))
  385.                                 {
  386.                                         // Get Paths etc.pp
  387.  
  388.                                     strcpy(MC->mc_ManPaths, (char *)ManArgs[MANPATHS_ARG]);
  389.                                     strcpy(MC->mc_ViewCmd, (char *)ManArgs[MANVIEW_ARG]);
  390.                                     strcpy(MC->mc_ViewCmdAG, (char *)ManArgs[MANVIEWAG_ARG]);
  391.                                     strcpy(MC->mc_ViewCmdDVI, (char *)ManArgs[MANVIEWDVI_ARG]);
  392.  
  393.                                         // Per default use the ASCII viewer for "non-extension" files
  394.  
  395.                                     strcpy(MC->mc_NonExt, MC->mc_ViewCmd);
  396.  
  397.                                         // Get additional patterns for normal texts
  398.  
  399.                                     if(ManArgs[MANNRMEXT_ARG])
  400.                                         strcpy(MC->mc_NormExt, (char *)ManArgs[MANNRMEXT_ARG]);
  401.  
  402.                                         // Get additional patterns for AmigaGuide texts
  403.  
  404.                                     if(ManArgs[MANAGEXT_ARG])
  405.                                         strcpy(MC->mc_AGExt, (char *)ManArgs[MANAGEXT_ARG]);
  406.  
  407.                                         // Get additional patterns for DVI files
  408.  
  409.                                     if(ManArgs[MANDVIEXT_ARG])
  410.                                         strcpy(MC->mc_DVIExt, (char *)ManArgs[MANDVIEXT_ARG]);
  411.  
  412.                                         // Get name of viewer to use when no extension was found
  413.  
  414.                                     if(ManArgs[MANNOVIEW_ARG])
  415.                                         strcpy(MC->mc_NonExt, (char *)ManArgs[MANNOVIEW_ARG]);
  416.  
  417.                                         // Check for GetFile attribute
  418.  
  419.                                     if(ManArgs[MANGETFILE_ARG])
  420.                                         UseAsl        = TRUE;
  421.  
  422.                                         // Do we have a manpage ???
  423.  
  424.                                     if(GotManPage)
  425.                                     {
  426.                                             // Set pattern for ExAll() search
  427.  
  428.                                         if(ManArgs[MANBASENAME_ARG])
  429.                                             strcpy(MC->mc_SearchName, (char *)FilePart(Args[MAN_ARG]));
  430.                                         else
  431.                                             strcpy(MC->mc_SearchName, Args[MAN_ARG]);
  432.  
  433.                                             // Append patterns
  434.  
  435.                                         strcat(MC->mc_SearchName, "(.doc|.man|.guide|.dvi|");
  436.                                         strcat(MC->mc_SearchName, MC->mc_NormExt);
  437.                                         strcat(MC->mc_SearchName, "|");
  438.                                         strcat(MC->mc_SearchName, MC->mc_AGExt);
  439.                                         strcat(MC->mc_SearchName, "|");
  440.                                         strcat(MC->mc_SearchName, MC->mc_DVIExt);
  441.                                         strcat(MC->mc_SearchName, "|)");
  442.  
  443.                                             // Parse the pattern
  444.  
  445.                                         if(ParsePatternNoCase(MC->mc_SearchName, MC->mc_Pattern, 1024) != -1)
  446.                                         {
  447.                                                 // Ok, reached this point
  448.  
  449.                                             StartedSearch    = TRUE;
  450.  
  451.                                                 // Loop for all dirs and wait until file has been found
  452.  
  453.                                             while(!MC->mc_Found && !MC->mc_Breaked && DirOffset)
  454.                                             {
  455.                                                     // Check for CTRL-C
  456.  
  457.                                                 MySig    = CheckSignal(SIGBREAKF_CTRL_C);
  458.  
  459.                                                 if(!(MySig & SIGBREAKF_CTRL_C))
  460.                                                 {
  461.                                                         // Extract next directory from list
  462.  
  463.                                                     DirOffset = GetDir(MC->mc_CheckDir, DirOffset);
  464.  
  465.                                                         // This dir an assign ???
  466.  
  467.                                                     if(IsAssign(MC))
  468.                                                     {
  469.                                                         struct    MsgPort    *OldSysTask;
  470.                                                         struct    DevProc    *DirProc    = NULL;
  471.                                                         BOOL    ErrLoop            = FALSE;
  472.  
  473.                                                             // Get old FileSystemTask
  474.  
  475.                                                         OldSysTask    = GetFileSysTask();
  476.  
  477.                                                             // Loop for dirs assigned
  478.  
  479.                                                         do
  480.                                                         {
  481.                                                                 // get the deviceproc for this Assign
  482.  
  483.                                                             if((DirProc = GetDeviceProc(MC->mc_CheckDir, DirProc)))
  484.                                                             {
  485.                                                                     // Set FileSystem task for locking
  486.  
  487.                                                                 SetFileSysTask(DirProc->dvp_Port);
  488.  
  489.                                                                     // Get full device/path name and try to scan dir
  490.  
  491.                                                                 if(NameFromLock(DirProc->dvp_Lock, MC->mc_NameBuffer, 1024) == DOSTRUE)
  492.                                                                     DoCheckDir(MC);
  493.                                                                 else
  494.                                                                 {
  495.                                                                     PrintFault(IoErr(), "Man ");
  496.                                                                     ErrLoop    = TRUE;
  497.                                                                 }
  498.                                                             }
  499.                                                             else
  500.                                                             {
  501.                                                                 ULONG    Err = IoErr();
  502.  
  503.                                                                 if(Err != ERROR_NO_MORE_ENTRIES)
  504.                                                                 {
  505.                                                                     PrintFault(IoErr(), "Man ");
  506.                                                                     ErrLoop    = TRUE;
  507.                                                                 }
  508.                                                             }
  509.  
  510.                                                             // Loop for additional assignments
  511.  
  512.                                                         } while(!ErrLoop && !MC->mc_Found && !MC->mc_Breaked && DirProc && (DirProc->dvp_Flags & DVPF_ASSIGN));
  513.  
  514.                                                             // Restore old FileSystemTask
  515.  
  516.                                                         SetFileSysTask(OldSysTask);
  517.  
  518.                                                             // Still having a DeviceProc ??? -> Release it
  519.  
  520.                                                         if(DirProc)
  521.                                                             FreeDeviceProc(DirProc);
  522.  
  523.                                                             // Error occured -> End whole loop
  524.  
  525.                                                         if(ErrLoop)
  526.                                                             DirOffset = NULL;
  527.                                                     }
  528.                                                     else
  529.                                                     {
  530.                                                             // For "normal" dirs simply check
  531.  
  532.                                                         strcpy(MC->mc_NameBuffer, MC->mc_CheckDir);
  533.  
  534.                                                         DoCheckDir(MC);
  535.                                                     }
  536.                                                 }
  537.                                                 else
  538.                                                     MC->mc_Breaked = TRUE;
  539.                                             }
  540.  
  541.                                             if(!MC->mc_Found)
  542.                                                 strcpy(MC->mc_FileName, Args[MAN_ARG]);
  543.                                         }
  544.                                         else
  545.                                             PrintFault(IoErr(), "Man ");
  546.                                     }
  547.                                     else
  548.                                     {
  549.                                             // if no popup wanted, issue error
  550.  
  551.                                         if(!UseAsl)
  552.                                             PrintFault(ERROR_REQUIRED_ARG_MISSING, "Man ");
  553.                                     }
  554.  
  555.                                     FreeArgs(ManRDArgs);
  556.                                 }
  557.                                 else
  558.                                     PrintFault(IoErr(), "Man (MANOPT) ");
  559.                             }
  560.                             else
  561.                                 PrintFault(IoErr(), "Man (MANOPT) ");
  562.  
  563.                             FreeArgs(RDArgs);
  564.                         }
  565.                         else
  566.                             PrintFault(IoErr(), "Man ");
  567.  
  568.                         FreeVec(MC->mc_EAB);
  569.                     }
  570.                     else
  571.                         FPuts(MC->mc_OutHandle, "Man : Could not allocate buffer for ExAll()\n");
  572.  
  573.                     FreeDosObject(DOS_EXALLCONTROL, (void *)MC->mc_EAC);
  574.                 }
  575.                 else
  576.                     FPuts(MC->mc_OutHandle, "Man : Could not allocate structure for ExAll()\n");
  577.  
  578.                 FreeDosObject(DOS_RDARGS, (void *)ManRDArgs);
  579.             }
  580.             else
  581.                 FPuts(MC->mc_OutHandle, "Man : Could not allocate structure for MANOPT parsing\n");
  582.  
  583.             FreeVec(ManArgs);
  584.         }
  585.         else
  586.             FPuts(MC->mc_OutHandle, "Man : Could not allocate buffer for MANOPT parsing\n");
  587.  
  588.         FreeVec(Args);
  589.     }
  590.     else
  591.         FPuts(MC->mc_OutHandle, "Could not allocate buffer for CommandLine Parsing\n");
  592.  
  593.  
  594.         // Found and not breaked ???
  595.  
  596.     if((MC->mc_Found || UseAsl) && !MC->mc_Breaked)
  597.     {
  598.         if(!MC->mc_Found && UseAsl)
  599.         {
  600.             struct    Library        *AslBase;
  601.             struct    FileRequester    *FileReq;
  602.  
  603.                 // Open ASL library
  604.  
  605.             if((AslBase = OpenLibrary("asl.library", 37)))
  606.             {
  607.                     // Extract first path of MANPATH
  608.  
  609.                 GetDir(MC->mc_CheckDir, MC->mc_ManPaths);
  610.  
  611.                     // Create FileRequester
  612.  
  613.                 if((FileReq = AllocAslRequestTags(ASL_FileRequest,
  614.                     ASLFR_PubScreenName,    NULL,
  615.                     ASLFR_PositiveText,    "Show",
  616.                     ASLFR_Flags2,        FRF_REJECTICONS,
  617.                     ASLFR_RejectIcons,    TRUE,
  618.                     ASLFR_TitleText,    "Man page not found; please select",
  619.                     ASLFR_InitialFile,    MC->mc_FileName,
  620.                     ASLFR_InitialDrawer,    MC->mc_CheckDir,
  621.                 TAG_DONE)))
  622.                 {
  623.                         // Let the user select
  624.  
  625.                     if(AslRequest(FileReq, TAG_DONE))
  626.                     {
  627.                             // Copy Drawer part
  628.  
  629.                         strcpy(MC->mc_CheckDir, FileReq->fr_Drawer);
  630.  
  631.                             // ...and file part
  632.  
  633.                         strcpy(MC->mc_FileName, FileReq->fr_File);
  634.  
  635.                             // Check for type of file to be displayed
  636.  
  637.                         DetermineFileType(MC);
  638.                     }
  639.  
  640.                         // Free FileRequester
  641.  
  642.                     FreeAslRequest(FileReq);
  643.                 }
  644.                 else
  645.                     PrintFault(ERROR_NO_FREE_STORE, "Man (FileRequester) ");
  646.  
  647.                     // Close library again
  648.  
  649.                 CloseLibrary(AslBase);
  650.             }
  651.             else
  652.                 PrintFault(ERROR_NO_FREE_STORE, "Man (FileRequester) ");
  653.         }
  654.  
  655.             // Really found a man page ???
  656.  
  657.         if(MC->mc_Found)
  658.         {
  659.             char    *Offset    = PathPart(MC->mc_CheckDir);
  660.             BPTR    CurDir;
  661.  
  662.                 // Get name of path doc file resides in
  663.  
  664.             memset(MC->mc_FileName, 0, 1024);
  665.             strncpy(MC->mc_FileName, MC->mc_CheckDir, (ULONG)(Offset - MC->mc_CheckDir));
  666.  
  667.                 // And try to lock directory
  668.  
  669.             CurDir    = Lock(MC->mc_FileName, ACCESS_READ);
  670.  
  671.                 // Call viewer
  672.  
  673.             if(SystemTags(MC->mc_SearchName, NP_CurrentDir, CurDir, TAG_DONE) == -1)
  674.             {
  675.                     // Free lock on current dir, if command could not be launched
  676.  
  677.                 if(CurDir)
  678.                     UnLock(CurDir);
  679.             }
  680.         }
  681.  
  682.  
  683.                 // Close libs
  684.  
  685.         CloseLibrary((struct Library *)DOSBase);
  686.         CloseLibrary(UtilityBase);
  687.  
  688.             // Free structure
  689.  
  690.         FreeVec(MC);
  691.         return(0);
  692.     }
  693.         // Got buffers ???
  694.  
  695.     else if(Args && RDArgs)
  696.     {
  697.             // Started search ???
  698.  
  699.         if(StartedSearch)
  700.         {
  701.                 // Not breaked ???
  702.  
  703.             if(!MC->mc_Breaked)
  704.             {
  705.                     // No pages found
  706.  
  707.                 FPuts(MC->mc_OutHandle, "Man-Pages not found for : ");
  708.                 FPuts(MC->mc_OutHandle, MC->mc_FileName);
  709.                 FPuts(MC->mc_OutHandle, "\n");
  710.             }
  711.             else
  712.                 FPuts(MC->mc_OutHandle, "Man : ^C...\n");
  713.         }
  714.  
  715.             // Close libs
  716.  
  717.         CloseLibrary((struct Library *)DOSBase);
  718.         CloseLibrary(UtilityBase);
  719.  
  720.             // Free structure
  721.  
  722.         FreeVec(MC);
  723.         return(10);
  724.     }
  725.  
  726.         // Close libs
  727.  
  728.     CloseLibrary((struct Library *)DOSBase);
  729.     CloseLibrary(UtilityBase);
  730.  
  731.         // Free structure
  732.  
  733.     FreeVec(MC);
  734.     return(20);
  735. }
  736.  
  737.  
  738.  
  739.  
  740.  
  741. /**********************************************************************/
  742. /*          Get portions from the Env-Var -> Next directory           */
  743. /**********************************************************************/
  744. static char *GetDir(char *NewDir, char *OldDir)
  745. {
  746.     while(*OldDir == ' ')
  747.         OldDir++;
  748.  
  749.     while((*OldDir != '\n') && (*OldDir != '\0') && (*OldDir != '|') && (*OldDir != ','))
  750.         *NewDir++ = *OldDir++;
  751.  
  752.     *NewDir        = '\0';
  753.  
  754.     if(*OldDir == '\n' || *OldDir == '\0')
  755.         OldDir = NULL;
  756.     else
  757.         OldDir++;
  758.  
  759.     return(OldDir);
  760. }
  761.  
  762.  
  763.  
  764.  
  765.  
  766.  
  767.  
  768.  
  769. /**********************************************************************/
  770. /*                        Check this directory                        */
  771. /**********************************************************************/
  772. static BOOL DoCheckDir(struct ManControl *MC)
  773. {
  774.     BPTR    TestLock;
  775.     ULONG    MySig;
  776.     BOOL    GoOn;
  777.  
  778.         // Try to lock directory
  779.  
  780.     if((TestLock = Lock(MC->mc_NameBuffer, SHARED_LOCK)))
  781.     {
  782.             // Fill in ExAll structure
  783.  
  784.         MC->mc_EAC->eac_LastKey        = 0;
  785.         MC->mc_EAC->eac_MatchString    = MC->mc_Pattern;
  786.         MC->mc_EAC->eac_MatchFunc    = NULL;
  787.  
  788.         do
  789.         {
  790.                 // Check for CTRL-C
  791.  
  792.             MySig = CheckSignal(SIGBREAKF_CTRL_C);
  793.             if((MySig & SIGBREAKF_CTRL_C))
  794.                 MC->mc_Breaked = TRUE;
  795.  
  796.                 // Do the scanning
  797.  
  798.             GoOn = ExAll(TestLock, (struct ExAllData *)MC->mc_EAB, (20*sizeof(struct ExAllData)), ED_NAME, MC->mc_EAC);
  799.  
  800.                 // Error occured ???
  801.  
  802.             if((!GoOn) && (IoErr() != ERROR_NO_MORE_ENTRIES))
  803.                 PrintFault(IoErr(), "Man ");
  804.  
  805.                 // End of dir reached ;
  806.  
  807.             if(MC->mc_EAC->eac_Entries == 0)
  808.                 GoOn = FALSE;
  809.             else if(!MC->mc_Breaked)
  810.             {
  811.                     // Copy real name of directory to our CheckDir buffer
  812.  
  813.                 strcpy(MC->mc_CheckDir, MC->mc_NameBuffer);
  814.  
  815.                     // Get first name matching
  816.  
  817.                 strcpy(MC->mc_FileName, ((struct ExAllData *)MC->mc_EAB)->ed_Name);
  818.  
  819.  
  820.                     // Check for type of file and set command
  821.  
  822.                 DetermineFileType(MC);
  823.             }
  824.         } while(GoOn);
  825.  
  826.         GoOn = TRUE;
  827.  
  828.             // Unlock Directory
  829.  
  830.         UnLock(TestLock);
  831.     }
  832.     else
  833.     {
  834.             // Display message
  835.  
  836.         FPuts(MC->mc_OutHandle, "Man : Skipping directory; not existent : ");
  837.         FPuts(MC->mc_OutHandle, MC->mc_CheckDir);
  838.         FPuts(MC->mc_OutHandle, "\n");
  839.  
  840.         GoOn = FALSE;
  841.     }
  842.  
  843.     return(GoOn);
  844. }
  845.  
  846.  
  847.  
  848. /**********************************************************************/
  849. /*                 Check if a given name is an assign                 */
  850. /**********************************************************************/
  851. static BOOL IsAssign(struct ManControl *MC)
  852. {
  853.     struct    DosList    *DList;
  854.     UBYTE        *AssignName;
  855.     UCOUNT        AssignLength;
  856.     LONG        Position;
  857.     BOOL        RetVal    = FALSE;
  858.  
  859.     Position = SplitName(MC->mc_CheckDir, ':', MC->mc_NameBuffer, 0, 1024);
  860.  
  861.     if(Position != -1)
  862.     {
  863.         if(MC->mc_CheckDir[Position] == '\0')
  864.         {
  865.             if((DList = AttemptLockDosList(LDF_ASSIGNS | LDF_READ)) > (struct DosList *)1)
  866.             {
  867.                 while(DList = NextDosEntry(DList, LDF_ASSIGNS))
  868.                 {
  869.                     AssignName    = (UBYTE *)BADDR(DList->dol_Name);
  870.                     AssignLength    = AssignName[0];
  871.  
  872.                     if(!Strnicmp(AssignName + 1, MC->mc_NameBuffer, AssignLength))
  873.                     {
  874.                         RetVal = TRUE;
  875.                         break;
  876.                     }
  877.                 }
  878.  
  879.                 UnLockDosList(LDF_ASSIGNS | LDF_READ);
  880.             }
  881.         }
  882.     }
  883.  
  884.     return(RetVal);
  885. }
  886.  
  887.  
  888.  
  889.  
  890.  
  891.  
  892.  
  893. /**********************************************************************/
  894. /*       Check for the file given and set command to be called        */
  895. /**********************************************************************/
  896. static void DetermineFileType(struct ManControl *MC)
  897. {
  898.         // Check extension to decide whether it`s an AmigaGuide file
  899.  
  900.     if(strchr(MC->mc_FileName, '.'))
  901.     {
  902.         char    *ExtPtr,
  903.             *DelPtr;
  904.         int    ExtLen;
  905.         BOOL    FoundAG        = FALSE,
  906.             FoundDVI    = FALSE;
  907.  
  908.             // Append default .guide extension and additional
  909.             // seperator for ease of calculating the length
  910.  
  911.         ExtPtr    = MC->mc_AGExt;
  912.         strcat(ExtPtr, "|.guide|");
  913.  
  914.             // Loop for all extensions
  915.  
  916.         while(!FoundAG && (ExtPtr = strchr(ExtPtr, '.')))
  917.         {
  918.                 // Calc len of extension
  919.  
  920.             DelPtr    = strchr(ExtPtr, '|');
  921.             ExtLen    = DelPtr - ExtPtr;
  922.  
  923.             if(!strnicmp(&MC->mc_FileName[strlen(MC->mc_FileName) - ExtLen], ExtPtr, ExtLen))
  924.                 FoundAG    = TRUE;
  925.  
  926.             ExtPtr++;
  927.         }
  928.  
  929.             // Now set view command accordingly
  930.  
  931.         if(FoundAG)
  932.             strcpy(MC->mc_SearchName, MC->mc_ViewCmdAG);
  933.         else
  934.         {
  935.                 // No AmigaGuide file found, check for DVI
  936.  
  937.                 // Append default .guide extension and additional
  938.                 // seperator for ease of calculating the length
  939.  
  940.             ExtPtr    = MC->mc_DVIExt;
  941.             strcat(ExtPtr, "|.dvi|");
  942.  
  943.                 // Loop for all extensions
  944.  
  945.             while(!FoundDVI && (ExtPtr = strchr(ExtPtr, '.')))
  946.             {
  947.                     // Calc len of extension
  948.  
  949.                 DelPtr    = strchr(ExtPtr, '|');
  950.                 ExtLen    = DelPtr - ExtPtr;
  951.  
  952.                 if(!strnicmp(&MC->mc_FileName[strlen(MC->mc_FileName) - ExtLen], ExtPtr, ExtLen))
  953.                     FoundDVI    = TRUE;
  954.  
  955.                 ExtPtr++;
  956.             }
  957.  
  958.             if(FoundDVI)
  959.                 strcpy(MC->mc_SearchName, MC->mc_ViewCmdDVI);
  960.  
  961.         }
  962.  
  963.  
  964.             // No AmigaGuide, nor DVI file found, use default viewer
  965.  
  966.         if(!FoundAG && !FoundDVI)
  967.             strcpy(MC->mc_SearchName, MC->mc_ViewCmd);
  968.     }
  969.     else
  970.     {
  971.             // Only use default viewer for non-extension files, when not set to "none"
  972.  
  973.         if(Stricmp(MC->mc_NonExt, "none"))
  974.         {
  975.                 // No extension use default viewer
  976.  
  977.             strcpy(MC->mc_SearchName, MC->mc_NonExt);
  978.  
  979.         }
  980.     }
  981.  
  982.     MC->mc_Found = TRUE;
  983.  
  984.         // Append directory and FileName
  985.  
  986.     AddPart(MC->mc_CheckDir, MC->mc_FileName, 1024);
  987.  
  988.     strcat(MC->mc_SearchName, " ");
  989.     strcat(MC->mc_SearchName, MC->mc_CheckDir);
  990. }
  991.