home *** CD-ROM | disk | FTP | other *** search
/ Gold Fish 3 / goldfish_volume_3.bin / files / util / boot / yourfault / src / yourfault.c < prev   
Encoding:
C/C++ Source or Header  |  1995-06-15  |  8.6 KB  |  366 lines

  1. /*
  2.  * YourFault, 1995 Lee Kindness.
  3.  *
  4.  * Patches the error strings returned by dos.library to your own.
  5.  * WARNING: It patches a private dos function!! (dosPrivate5())
  6.  *
  7.  * This source is in the public domain, do with it as you wish...
  8.  *
  9.  * version 1.4
  10.  *
  11.  ***************************************************************************/
  12.  
  13. #include "gst.c"
  14.  
  15. /* download dev/c/SFPatch.lha for documentation */
  16. #include "SFPatch.h"
  17.  
  18. /* DONT auto open... */
  19. extern struct IntuitionBase *IntuitionBase = NULL;
  20. extern struct Library *CxBase = NULL;
  21. extern struct Library *IconBase = NULL;
  22.  
  23. /* Save a bit of typing */
  24. #define REG(x) register __ ## x
  25.  
  26. /* The function offset of dosPrivate5() */
  27. #define DP5OFFSET -978
  28.  
  29. /* Default file from which the strings are to read from */
  30. #define ERRSFILENAME "S:FaultStrings"
  31.  
  32. /* Log file */
  33. #define LOGFNAME "S:YourFault.Log"
  34.  
  35. /* types */
  36. typedef STRPTR __asm (*dP5Caller)( REG(d1) LONG, REG(a6) struct Library *);
  37.  
  38. /* ErrorStringNode */
  39. typedef struct ESNode {
  40.     struct ESNode *es_Succ;
  41.     struct ESNode *es_Pred;
  42.     UBYTE          es_Type;
  43.     BYTE           es_Pri;
  44.     STRPTR         es_String;
  45.     LONG           es_Number;
  46. } ESNode;
  47.  
  48.  
  49. /* Prototypes */
  50. STRPTR __asm new_dosPrivate5(REG(d1) LONG,REG(a6) struct Library *);
  51. struct List *LoadErrStrings(STRPTR);
  52. BOOL OpenLibs(void);
  53. void CloseLibs(void);
  54. void DoLogFile(STRPTR fname, LONG code, STRPTR errstring);
  55. BOOL ShowWindow(void);
  56.  
  57. /* Global vars */
  58. SetFunc *dP5sf;
  59. struct List *codes;
  60. struct Remember *grk;
  61. BOOL Active;
  62. char vertag[] = "$VER: YourFault 1.4 "__AMIGADATE__;
  63.  
  64. /***************************************************************************/
  65.  
  66. /* main */
  67. int main(int argc, char **argv)
  68. {
  69.     int ret;        
  70.     ret = RETURN_OK;
  71.     Active = TRUE;
  72.     grk = NULL;
  73.     
  74.     /* check version */
  75.     if (OpenLibs()) {
  76.         char StringsFName[80] = ERRSFILENAME;
  77.         struct NewBroker nb = {
  78.             NB_VERSION,
  79.             "YourFault",
  80.             &vertag[6],
  81.             "Patches the system error strings.",
  82.             NBU_UNIQUE | NBU_NOTIFY,
  83.             COF_SHOW_HIDE,
  84.             -1,
  85.             NULL,
  86.             0
  87.         };
  88.         CxObj *broker;
  89.     
  90.         /* Get tooltypes */
  91.         if (argc ? FALSE : TRUE) {
  92.             BPTR oldcd;
  93.             struct DiskObject *dobj;
  94.             struct WBStartup *wbs;
  95.             #define PROGNAME wbs->sm_ArgList->wa_Name
  96.             #define PDIRLOCK wbs->sm_ArgList->wa_Lock
  97.             wbs = (struct WBStartup *)argv;
  98.             /* Run from WB */
  99.             oldcd = CurrentDir(PDIRLOCK);
  100.             if (dobj = GetDiskObject(PROGNAME)) {
  101.                 STRPTR s;
  102.                 if (s = FindToolType(dobj->do_ToolTypes, "FROM")) {
  103.                     strncpy((STRPTR)&StringsFName, s, 79);
  104.                     StringsFName[79] = NULL;
  105.                 }
  106.                 FreeDiskObject(dobj);
  107.             }
  108.             CurrentDir(oldcd);
  109.         } else {
  110.             struct RDArgs *rdargs;
  111.             #define OPT_FROM 0
  112.             LONG args[2] = {0};
  113.             #define TEMPLATE "FROM"
  114.             /* Run from Shell */
  115.             if (rdargs = ReadArgs(TEMPLATE, (LONG *)&args, NULL)) {
  116.                 if (args[OPT_FROM]) {
  117.                     strncpy((STRPTR)&StringsFName, (STRPTR) args[OPT_FROM], 79);
  118.                     StringsFName[79] = NULL;
  119.                 }
  120.                 FreeArgs(rdargs);    
  121.             }
  122.         }
  123.         
  124.         if ((nb.nb_Port = CreateMsgPort()) && (broker = CxBroker(&nb, NULL))) {
  125.             
  126.             ActivateCxObj(broker, 1L);
  127.             if (codes = LoadErrStrings((STRPTR)&StringsFName)) {
  128.                 /* Alloc our SetFunc */
  129.                 if (dP5sf = AllocVec(sizeof(SetFunc), MEMF_CLEAR)) {
  130.  
  131.                     /* init. sfs */
  132.                     dP5sf->sf_Func = new_dosPrivate5;
  133.                     dP5sf->sf_Library = (struct Library *)DOSBase;
  134.                     dP5sf->sf_Offset = DP5OFFSET;
  135.                     dP5sf->sf_QuitMethod = SFQ_COUNT;
  136.                     
  137.                     /* Replace the function */
  138.                     if (SFReplace(dP5sf)) {
  139.  
  140.                         ULONG sig, sret;
  141.                         BOOL finished;
  142.                                 
  143.                         finished = FALSE;
  144.                         sig = 1 << nb.nb_Port->mp_SigBit;
  145.                     
  146.                         do {
  147.                             sret = Wait(SIGBREAKF_CTRL_C | sig);
  148.                             if (sret & sig) {
  149.                                 CxMsg *msg;
  150.                                 while(msg = (CxMsg *)GetMsg(nb.nb_Port)) {
  151.                                     switch(CxMsgType(msg)) {
  152.                                         case CXM_COMMAND:
  153.                                             switch(CxMsgID(msg)) {
  154.                                                 case CXCMD_DISABLE:
  155.                                                     ActivateCxObj(broker, 0L);
  156.                                                     Active = FALSE;
  157.                                                     break;
  158.                                                 case CXCMD_ENABLE:
  159.                                                     ActivateCxObj(broker, 1L);
  160.                                                     Active = TRUE;
  161.                                                     break;
  162.                                                 case CXCMD_KILL:
  163.                                                     finished = TRUE;
  164.                                                     break;
  165.                                                 case CXCMD_UNIQUE:
  166.                                                     finished = ShowWindow();
  167.                                                     break;
  168.                                                 case CXCMD_APPEAR:
  169.                                                     finished = ShowWindow();
  170.                                                     break;
  171.                                             }
  172.                                             break;
  173.                                     }
  174.                                     ReplyMsg((struct Message *)msg);
  175.                                 }
  176.                             }
  177.                             if (sret & SIGBREAKF_CTRL_C)
  178.                                 finished = TRUE;
  179.                         } while (!finished);
  180.                         ActivateCxObj(broker, 0L);
  181.     
  182.                         /* Restore function */
  183.                         SFRestore(dP5sf);
  184.                     }
  185.                     FreeVec(dP5sf);
  186.                 }
  187.             } else {
  188.                 DisplayBeep(NULL);
  189.                 ret = RETURN_FAIL;
  190.             }
  191.     
  192.             DeleteCxObj(broker);
  193.             DeletePort(nb.nb_Port);
  194.         }
  195.     }
  196.     CloseLibs();
  197.     return(ret);
  198. }
  199.  
  200. /***************************************************************************/
  201. /* Show our window... currently only a requester */
  202. BOOL ShowWindow(void)
  203. {
  204.     struct EasyStruct ez = {
  205.         sizeof(struct EasyStruct),
  206.         0,
  207.         "YourFault",
  208.         "%s ©Lee Kindness.\n\n"
  209.         "Replaces the system error strings\n"
  210.         "with your own...\n\n"
  211.         "Read \"YourFault.guide\" for more information\n\n"
  212.         "(Program may take a couple of seconds to quit)",
  213.         "Quit|Hide"
  214.     };
  215.     return((BOOL)EasyRequest(NULL, &ez, NULL, &vertag[6]));
  216. }
  217.  
  218. /***************************************************************************/
  219. /* Open all used libraries */
  220. BOOL OpenLibs(void)
  221. {
  222.     BOOL ret;
  223.     IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 0);
  224.     CxBase = OpenLibrary("commodities.library", 36);
  225.     IconBase = OpenLibrary("icon.library", 0);
  226.     ret = ((DOSBase->dl_lib.lib_Version > 36) && 
  227.            (IntuitionBase) && 
  228.            (CxBase) && 
  229.            (IconBase));
  230.     return(ret);
  231. }
  232.  
  233. /***************************************************************************/
  234. /* Close all libraries */
  235. void CloseLibs(void)
  236. {
  237.     if (IconBase)
  238.         CloseLibrary(IconBase);
  239.     if (CxBase)
  240.         CloseLibrary(CxBase);
  241.     if (IntuitionBase)
  242.         CloseLibrary((struct Library *)IntuitionBase);
  243. }
  244.  
  245. /***************************************************************************/
  246. /* load the strings from the file fname into our list 
  247.  *
  248.  * The following tokens are special within the file:
  249.  *   ':', '|' and '#' on the first column of a line denote a comment.
  250.  *   '^' is replaced by '\n'
  251.  */
  252. struct List *LoadErrStrings(STRPTR fname)
  253. {
  254.     BPTR f;
  255.     char *sptr, *s, *buf;
  256.     struct List *l;
  257.     ESNode *esn;
  258.     
  259.     l = NULL;
  260.     /* alloc buffer */
  261.     buf = AllocVec(180, MEMF_CLEAR);
  262.     if (buf) {
  263.         /* open the file */
  264.         f = Open(fname, MODE_OLDFILE);
  265.         if (f) {
  266.             /* alloc the list */
  267.             l = AllocRemember(&grk, sizeof(struct List), MEMF_CLEAR);
  268.             if (l) {
  269.                 /* initilise the list */
  270.                 NewList(l);
  271.                 /* Parse the file... */
  272.                 s = FGets(f, buf, 180);
  273.                 while (s) {
  274.                     /* is it a comment? */
  275.                     if ((s[0] != ';') && (s[0] != '#') && (s[0] != '|')) {
  276.                         /* no, alloc node */
  277.                         esn = AllocRemember(&grk, sizeof(ESNode), MEMF_CLEAR);
  278.                         if (esn) {
  279.                             /* convert integer at start of string */
  280.                             esn->es_Number = atol(buf);
  281.                             sptr = strchr(buf, ':');
  282.                             if (sptr) {
  283.                                 sptr++;
  284.                                 /* remove 0x0A */
  285.                                 sptr[strlen(sptr)-1] = 0;
  286.                                 /* strip blanks */
  287.                                 sptr = stpblk(sptr);
  288.                                 /* alloc mem */
  289.                                 esn->es_String = AllocRemember(&grk, (strlen(sptr)+1), MEMF_CLEAR);
  290.                                 if (esn->es_String) {
  291.                                     STRPTR s;
  292.                                     #define FINDCHAR '^'
  293.                                     #define REPLACECHAR '\n'
  294.                                     
  295.                                     /* copy string */
  296.                                     strcpy(esn->es_String, sptr);
  297.                                     
  298.                                     /* replace all FINDCHAR with REPALCECHAR */
  299.                                     s = esn->es_String;
  300.                                     while(*s != '\0')
  301.                                     {
  302.                                         if(*s == FINDCHAR)
  303.                                             *s = REPLACECHAR;
  304.                                         s++;
  305.                                     }
  306.                                     
  307.                                     /* add to list */
  308.                                     AddTail(l, (struct Node *)esn);
  309.                                 }
  310.                             }
  311.                         }
  312.                     }
  313.                     s = FGets(f, buf, 180);
  314.                 }
  315.             }
  316.             Close(f);
  317.         }
  318.         FreeVec(buf);
  319.     }
  320.     return(l);
  321. }
  322.  
  323. /***************************************************************************/
  324. /* The new dosPrivate5() */
  325. STRPTR __saveds __asm new_dosPrivate5(REG(d1) LONG code,
  326.                                       REG(a6) struct Library *lib)
  327. {
  328.     ESNode *esn, *foundnode;
  329.     STRPTR ret;
  330.  
  331.     /* increment count */
  332.     Forbid();
  333.     dP5sf->sf_Count += 1;
  334.     Permit();
  335.     
  336.     ret = NULL;
  337.     if (Active) 
  338.     {
  339.         foundnode = NULL;
  340.         /* search for a matching code in the list */
  341.         esn = (ESNode *)codes->lh_Head;
  342.         while (esn->es_Succ) {
  343.             if (esn->es_Number == code)
  344.                 foundnode = esn;
  345.             esn = esn->es_Succ;
  346.         }
  347.         if (foundnode) 
  348.         {
  349.             /* return the string */
  350.             ret = foundnode->es_String;
  351.         }
  352.     }
  353.     
  354.     if (ret == NULL)
  355.         /* pass the buck... */
  356.         ret = ((dP5Caller)(dP5sf->sf_OriginalFunc))(code, lib);
  357.     
  358.     /* decrement count */
  359.     Forbid();
  360.     dP5sf->sf_Count -= 1;
  361.     Permit();
  362.     
  363.     /* and return */
  364.     return(ret);
  365. }
  366. /***************************************************************************/