home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / Libraries / Syslog Component / syslog component.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-11-15  |  20.3 KB  |  583 lines  |  [TEXT/SPM ]

  1. /*
  2.     Component.c
  3.     
  4.     Sample code for a simple component.  It really does nothing, but it can be used as a spring-board
  5.     for building other components.
  6. */
  7.  
  8. #if defined(powerc) || defined(__powerc)
  9. #include <stdlib.h>
  10. #endif
  11.  
  12. #include <Components.h>
  13. #include <Errors.h>
  14. #include <Packages.h>
  15. #include <Folders.h>
  16. #include <Notification.h>
  17.  
  18. #include "syslog internals.h"
  19. #include "syslog component.h"
  20.  
  21. #include "ShowInitIcon.h"
  22. #include "libsprintf.h"
  23.  
  24. /*
  25.     kIconID is the constant specifying which icon to display at system startup.  This allows for different
  26.     icons to be displayed depending on the code which is executing.
  27. */
  28. #if defined(powerc) || defined (__powerc)
  29. #define kIconID    140
  30. #else
  31. #define kIconID    141
  32. #endif
  33.  
  34. /*
  35.     kMaxIdentLen is a constant which represents the maximum size an ident string will be.  The total
  36.     max is 100.  By controling the size of the ident string, we ensure that there will be enough room in
  37.     a Str255 string for the ident string, time and date, priority, and message.
  38. */
  39. #define kMaxIdentLen 60
  40.  
  41. /*
  42.     kSyslogCreator is the creator type used when creating log files.  Use your favorite text editor here.
  43. */
  44. #define kSyslogCreator 'SPM '
  45.  
  46. pascal ComponentResult ComponentOpen(Handle storage,ComponentInstance self);
  47. pascal ComponentResult ComponentClose(Handle storage,ComponentInstance self);
  48. pascal ComponentResult ComponentCanDo(short selector);
  49. pascal ComponentResult ComponentVersion(void);
  50. pascal ComponentResult ComponentTarget(Handle storage,ComponentInstance self);
  51.  
  52. pascal ComponentResult ComponentRegister(Handle storage);
  53.  
  54. pascal ComponentResult ComponentOpenlog(Handle storage,const char* ident,long logopt,short facility);
  55. pascal ComponentResult ComponentSyslog(Handle storage,short priority,const char* message);
  56. pascal ComponentResult ComponentCloselog(Handle storage);
  57. pascal ComponentResult ComponentSetlogmask(Handle storage,short maskpri);
  58. pascal ComponentResult ComponentSetFile(Handle storage,FSSpecPtr spec);
  59.  
  60. pascal ComponentResult ComponentGetError(Handle storage,OSErr* err);
  61.  
  62. // some string routines so we don't need to include ANSI libs
  63. static short Strlen(char* s){
  64.     register char* cp=s;
  65.     register short sh=0;
  66.     
  67.     if (s==(char*)0)
  68.         return 0;
  69.     
  70.     while (*cp){
  71.         sh++;
  72.         cp++;
  73.     }
  74.     
  75.     return sh;
  76. }
  77.  
  78. static void Strncpy(char* s1,char* s2,short num){
  79.     
  80.     // copy the strings
  81.     BlockMoveData((Ptr)s2,(Ptr)s1,num);
  82.     
  83.     // terminate the new string
  84.     s1[num]=0;
  85. }
  86.  
  87. static void Strcpy(char* s1,char* s2){
  88.     // Call strncpy with the string's length
  89.     Strncpy(s1,s2,Strlen(s2));
  90. }
  91.  
  92. static void ConcatPString(StringPtr a,StringPtr b);
  93. static void ConcatPString(StringPtr a,StringPtr b){
  94.     register unsigned char* ap;
  95.     register unsigned char* bp;
  96.     register unsigned char c;
  97.     
  98.     ap=&(a[a[0]+1]);
  99.     bp=b;bp++;
  100.     c=b[0];
  101.     
  102.     while (c){
  103.         *ap=*bp;
  104.         ap++;
  105.         bp++;
  106.         c--;
  107.     }
  108.     
  109.     (a[0])+=b[0];
  110. }
  111.     
  112. pascal ComponentResult main(ComponentParameters* params,Handle storage){
  113.     ComponentResult res=((ComponentResult)noErr);
  114.     long lval;
  115.     ComponentFunctionUPP cfupp;
  116.     
  117. #if defined(powerc) || defined(__powerc)
  118.     __rsrcinit();
  119. #endif
  120.     
  121.     switch(params->what){
  122.         // Component Manager Routines
  123.         case kComponentOpenSelect:
  124.             cfupp=(ComponentFunctionUPP)NewComponentWithStorageProc(ComponentOpen);
  125.             res=CallComponentFunctionWithStorage(storage,params,cfupp);
  126.             DisposeComponentWithStorageProc(cfupp);
  127.             break;
  128.         case kComponentCloseSelect:
  129.             cfupp=(ComponentFunctionUPP)NewComponentWithStorageProc(ComponentClose);
  130.             res=CallComponentFunctionWithStorage(storage,params,cfupp);
  131.             DisposeComponentWithStorageProc(cfupp);
  132.             break;
  133.         case kComponentCanDoSelect:
  134.             cfupp=(ComponentFunctionUPP)NewComponentShortProc(ComponentCanDo);
  135.             res=CallComponentFunction(params,cfupp);
  136.             DisposeComponentShortProc(cfupp);
  137.             break;
  138.         case kComponentVersionSelect:
  139.             cfupp=(ComponentFunctionUPP)NewComponentVoidProc(ComponentVersion);
  140.             res=CallComponentFunction(params,cfupp);
  141.             DisposeComponentVoidProc(cfupp);
  142.             break;
  143.         case kComponentTargetSelect:
  144.             cfupp=(ComponentFunctionUPP)NewComponentWithStorageProc(ComponentTarget);
  145.             res=CallComponentFunctionWithStorage(storage,params,cfupp);
  146.             DisposeComponentWithStorageProc(cfupp);
  147.             break;
  148.         case kComponentRegisterSelect:
  149.             cfupp=(ComponentFunctionUPP)NewComponentHandleProc(ComponentRegister);
  150.             lval=CallComponentFunctionWithStorage(storage,params,cfupp);
  151.             DisposeComponentHandleProc(cfupp);
  152.             res=(ComponentResult)lval;
  153.             break;
  154.         
  155.         // Component Specific Routines
  156.             
  157.         case kopenlogSelector:
  158.             cfupp=(ComponentFunctionUPP)NewComponentOpenlogProc(ComponentOpenlog);
  159.             lval=CallComponentFunctionWithStorage(storage,params,cfupp);
  160.             DisposeComponentOpenlogProc(cfupp);
  161.             res=(ComponentResult)lval;
  162.             break;
  163.         case ksyslogSelector:
  164.             cfupp=(ComponentFunctionUPP)NewComponentSyslogProc(ComponentSyslog);
  165.             lval=CallComponentFunctionWithStorage(storage,params,cfupp);
  166.             DisposeComponentSyslogProc(cfupp);
  167.             res=(ComponentResult)lval;
  168.             break;
  169.         case kcloselogSelector:
  170.             cfupp=(ComponentFunctionUPP)NewComponentHandleProc(ComponentCloselog);
  171.             lval=CallComponentFunctionWithStorage(storage,params,cfupp);
  172.             DisposeComponentHandleProc(cfupp);
  173.             res=(ComponentResult)lval;
  174.             break;
  175.         case ksetlogmaskSelector:
  176.             cfupp=(ComponentFunctionUPP)NewComponentSetlogmaskProc(ComponentSetlogmask);
  177.             lval=CallComponentFunctionWithStorage(storage,params,cfupp);
  178.             DisposeComponentSetlogmaskProc(cfupp);
  179.             res=(ComponentResult)lval;
  180.             break;
  181.         case kSetFileSelector:
  182.             cfupp=(ComponentFunctionUPP)NewComponentSetFileProc(ComponentSetFile);
  183.             lval=CallComponentFunctionWithStorage(storage,params,cfupp);
  184.             DisposeComponentSetFileProc(cfupp);
  185.             res=(ComponentResult)lval;
  186.             break;
  187.         case kGetErrorSelector:
  188.             cfupp=(ComponentFunctionUPP)NewComponentOSErrPtrProc(ComponentGetError);
  189.             lval=CallComponentFunctionWithStorage(storage,params,cfupp);
  190.             DisposeComponentOSErrPtrProc(cfupp);
  191.             res=(ComponentResult)lval;
  192.             break;
  193.         
  194.         default:
  195.             res=badComponentSelector;
  196.             break;
  197.     }
  198.     
  199. #if defined(powerc) || defined(__powerc)
  200.     __rsrcterm();
  201. #endif
  202.     
  203.     return res;
  204. }
  205.  
  206. pascal ComponentResult ComponentOpen(Handle storage,ComponentInstance self){
  207.     ComponentStorageHdl sto;
  208.     ComponentResult res=((ComponentResult)noErr);
  209.     OSErr anErr=noErr;
  210.     short vref;
  211.     long dirid;
  212.     Handle i0h;
  213.     
  214.     sto=(ComponentStorageHdl)NewHandleClear(sizeof(ComponentStorageRec));
  215.     
  216.     if (sto==(ComponentStorageHdl)0){
  217.         res=((ComponentResult)MemError());
  218.     } else {
  219.         
  220.         HLock((Handle)sto);
  221.         
  222.         // (*sto)->resFileRefNum=OpenComponentResFile((Component)self); // open the resource file
  223.         
  224.         (*sto)->self=(Component)self;
  225.         
  226.         // create default values for the syslog stuff
  227.         (*sto)->ident[0]=0;
  228.         (*sto)->refnum=0;
  229.         (*sto)->logopts=0; // really ignored
  230.         (*sto)->facility=LOG_USER; // random user messages
  231.         (*sto)->mask=0xff; // mask nothing away
  232.         (*sto)->specvalid=false;
  233.         (*sto)->err=noErr;
  234.         
  235.         (*sto)->openCalled=false;
  236.         (*sto)->slogopts=(*sto)->logopts;
  237.         (*sto)->sfacility=(*sto)->facility;
  238.         (*sto)->smask=(*sto)->mask;
  239.         (*sto)->needSaved=false;
  240.         
  241.         // Set up the IU stuff
  242.         (*sto)->i0h=(Intl0Hndl)IUGetIntl(0);
  243.         
  244.         if ((*sto)->i0h!=(Intl0Hndl)0){
  245.             // detach it so we don't save the changes...
  246.             DetachResource((Handle)(*sto)->i0h);
  247.             
  248.             // date as 01/01/95
  249.             (*((*sto)->i0h))->shrtDateFmt|=dayLdingZ;
  250.             (*((*sto)->i0h))->shrtDateFmt&=~century;
  251.             
  252.             // time as 15:06:30
  253.             (*((*sto)->i0h))->timeCycle=0;
  254.             (*((*sto)->i0h))->timeFmt|=secLeadingZ|minLeadingZ|hrLeadingZ;
  255.         }
  256.         
  257.         /*
  258.             Start with the default syslog spec.  A file named 'syslog' will be created in the
  259.             system folder.  Use SetFile to change the spec to point somewhere else...
  260.         */
  261.         anErr=FindFolder(kOnSystemDisk,kSystemFolderType,kCreateFolder,&vref,&dirid);
  262.         if (anErr==noErr){
  263.             FInfo info;
  264.             
  265.             (*sto)->vRefNum=0;
  266.             (*sto)->dirID=0L;
  267.             
  268.             anErr=FSMakeFSSpec(vref,dirid,"\psyslog",&((*sto)->spec));
  269.             
  270.             // (*sto)->spec.vRefNum=vref;
  271.             // (*sto)->spec.parID=dirid;
  272.             
  273.             if ((anErr==noErr)||(anErr==fnfErr)){
  274.                 (*sto)->specvalid=true;
  275.                 
  276.                 (*sto)->vRefNum=vref;
  277.                 (*sto)->dirID=dirid;
  278.                 
  279.                 anErr=noErr;
  280.             }
  281.         }
  282.         
  283.         (*sto)->err=anErr;
  284.         
  285.         HUnlock((Handle)sto);
  286.         
  287.         SetComponentInstanceStorage(self,(Handle)sto);
  288.     }
  289.     
  290.     return res;
  291. }
  292.  
  293. pascal ComponentResult ComponentClose(Handle storage,ComponentInstance self){
  294.     ComponentResult res=((ComponentResult)noErr);
  295.     SignedByte s=HGetState(storage);
  296.     ComponentStorageHdl sto;
  297.     
  298.     HLock(storage);
  299.     sto=(ComponentStorageHdl)storage;
  300.     
  301.     DisposeHandle((Handle)(*sto)->i0h);
  302.     
  303.     HSetState(storage,s);
  304.     
  305.     DisposeHandle(storage);
  306.     
  307.     return res;
  308. }
  309.  
  310. pascal ComponentResult ComponentCanDo(short selector){
  311.     ComponentResult res=((ComponentResult)noErr);
  312.     
  313.     switch(selector){
  314.         // Component Manager Routines
  315.         case kComponentOpenSelect:
  316.         case kComponentCloseSelect:
  317.         case kComponentCanDoSelect:
  318.         case kComponentVersionSelect:
  319.         case kComponentTargetSelect:
  320.         case kComponentRegisterSelect:
  321.         
  322.         // Add component specific routines here...
  323.         case kopenlogSelector:
  324.         case ksyslogSelector:
  325.         case kcloselogSelector:
  326.         case ksetlogmaskSelector:
  327.         case kSetFileSelector:
  328.         case kGetErrorSelector:
  329.         
  330.             res=((ComponentResult)1);
  331.             break;
  332.         default:
  333.             res=((ComponentResult)0);
  334.             break;
  335.     }
  336.     
  337.     return res;
  338. }
  339.  
  340. pascal ComponentResult ComponentVersion(void){
  341.     ComponentResult res=((ComponentResult)kVersion);
  342.     
  343.     return res;
  344. }
  345.  
  346. pascal ComponentResult ComponentTarget(Handle storage,ComponentInstance kidnapper){
  347.     ComponentResult res=((ComponentResult)noErr);
  348.     SignedByte s=HGetState(storage);
  349.     ComponentStorageHdl sto;
  350.     
  351.     HLock(storage);
  352.     sto=(ComponentStorageHdl)storage;
  353.     
  354.     (*sto)->kidnapper=kidnapper;
  355.     
  356.     HSetState(storage,s);
  357.     
  358.     return res;
  359. }
  360.  
  361. pascal ComponentResult ComponentRegister(Handle storage){
  362.     ComponentResult res=((ComponentResult)noErr);
  363.     short refnum,oldref;
  364.     SignedByte s=HGetState(storage);
  365.     ComponentStorageHdl sto;
  366.     
  367.     HLock(storage);
  368.     sto=(ComponentStorageHdl)storage;
  369.     
  370.     oldref=CurResFile();
  371.     
  372.     refnum=OpenComponentResFile((*sto)->self);
  373.     
  374.     if (refnum>0){
  375.         // use our resource file
  376.         UseResFile(refnum);
  377.         
  378.         // show the icon
  379.         ShowInitIcon(kIconID,true);
  380.         
  381.         // close our resource file
  382.         CloseComponentResFile(refnum);
  383.         
  384.         // restore the old front resource
  385.         UseResFile(oldref);
  386.     } else {
  387.         (*sto)->err=2005;
  388.     }
  389.     
  390.     HSetState(storage,s);
  391.     
  392.     return res;
  393. }
  394.  
  395. // Add component specific routines here or in another file
  396.  
  397. /*
  398.     ComponentOpenlog
  399.     
  400.     Handles the opening of the syslog file.  Note that if we are opening an existing file, it's contents are
  401.     purged.
  402. */
  403. pascal ComponentResult ComponentOpenlog(Handle storage,const char* ident,long logopt,short facility){
  404.     ComponentResult res;
  405.     SignedByte s=HGetState(storage);
  406.     ComponentStorageHdl sto;
  407.     
  408.     HLock(storage);
  409.     sto=(ComponentStorageHdl)storage;
  410.     
  411.     // save the current stuff if necessary
  412.     if (!((*sto)->openCalled)){
  413.         // open called for the first time...
  414.         if ((*sto)->needSaved){
  415.             // the settings have changed, so we are not just resetting the syslog file
  416.             (*sto)->openCalled=true;
  417.             (*sto)->slogopts=(*sto)->logopts;
  418.             (*sto)->sfacility=(*sto)->facility;
  419.             (*sto)->smask=(*sto)->mask;
  420.         }
  421.     }
  422.     
  423.     if (Strlen((char*)ident)){
  424.         // save the current ident string
  425.         if (Strlen((char*)ident)>kMaxIdentLen){
  426.             Strncpy((*sto)->ident,(char*)ident,kMaxIdentLen);
  427.         } else {
  428.             Strcpy((*sto)->ident,(cha file if it's open
  429.         if (anErr==noErr)
  430.             SetFPos((*sto)->refnum,fsFromLEOF,0L);
  431.         else {
  432.             (*sto)->refnum=0;
  433.             
  434.             // problem opening the file, try to create it...
  435.             anErr=FSpCreate(&((*sto)->spec),kSyslogCreator,'TEXT',smSystemScript);
  436.             
  437.             if (anErr==noErr){
  438.                 // if the file was just created, then we don't need to seek, just open
  439.                 anErr=FSpOpenDF(&((*sto)->spec),fsRdWrPerm,&((*sto)->refnum));
  440.                 if (anErr!=noErr)
  441.                     (*sto)->refnum=0;
  442.             } else {
  443.                 // DebugNotify("\pLog component: Error creating the file!");
  444.             }
  445.         }
  446.         
  447.         if ((anErr==noErr)&&((*sto)->refnum!=0)){
  448.             // OK to write to the file, add the nstr first
  449.             ct=(long)(nstr[0]);
  450.             FSWrite((*sto)->refnum,&ct,&(nstr[1]));
  451.             
  452.             // add the message to the file
  453.             ct=(long)Strlen((char*)message);
  454.             FSWrite((*sto)->refnum,&ct,message);
  455.             
  456.             // now add a newline char
  457.             msg[1]=0x0d;
  458.             ct=1;
  459.             FSWrite((*sto)->refnum,&ct,&(msg[1]));
  460.             
  461.             // done, flush & close file
  462.             FSClose((*sto)->refnum);
  463.             (*sto)->refnum=0;
  464.             FlushVol((StringPtr)0,(*sto)->spec.vRefNum);
  465.         }
  466.     } else {
  467.         anErr=2002; // fsspec is invalid
  468.     }
  469.     
  470. ExitSyslog:
  471.     (*sto)->err=anErr;
  472.     
  473.     HSetState(storage,s);
  474.     
  475.     return res;
  476. }
  477.  
  478. pascal ComponentResult ComponentCloselog(Handle storage){
  479.     ComponentResult res=noErr;
  480.     SignedByte s=HGetState(storage);
  481.     ComponentStorageHdl sto;
  482.     
  483.     HLock(storage);
  484.     sto=(ComponentStorageHdl)storage;
  485.     
  486.     // the current log should be closed and the old syslog reused.
  487.     
  488.     if ((*sto)->openCalled){
  489.         // open was called and the settings were changed
  490.         // restore the settings to the default values.
  491.         
  492.         (*sto)->openCalled=false;
  493.         (*sto)->facility=(*sto)->sfacility;
  494.         (*sto)->mask=(*sto)->smask;
  495.         (*sto)->logopts=(*sto)->slogopts;
  496.         (*sto)->needSaved=false;
  497.         (*sto)->ident[0]=0;
  498.         
  499.         if (((*sto)->vRefNum!=0)&&((*sto)->dirID!=0L)){
  500.             FSMakeFSSpec((*sto)->vRefNum,(*sto)->dirID,"\psyslog",&((*sto)->spec));
  501.             (*sto)->specvalid=true;
  502.         } else {
  503.             (*sto)->specvalid=false;
  504.         }
  505.     }
  506.     
  507.     HSetState(storage,s);
  508.     
  509.     return res;
  510. }
  511.  
  512. pascal ComponentResult ComponentSetlogmask(Handle storage,short maskpri){
  513.     ComponentResult res;
  514.     SignedByte s=HGetState(storage);
  515.     ComponentStorageHdl sto;
  516.     
  517.     HLock(storage);
  518.     sto=(ComponentStorageHdl)storage;
  519.     
  520.     res=(ComponentResult)(*sto)->mask;
  521.     
  522.     // save the new mask
  523.     if (maskpri!=0)
  524.         (*sto)->mask=maskpri;
  525.     (*sto)->needSaved=true;
  526.     
  527.     HSetState(storage,s);
  528.     
  529.     return res;
  530. }
  531.  
  532. pascal ComponentResult ComponentSetFile(Handle storage,FSSpecPtr spec){
  533.     ComponentResult res;
  534.     SignedByte s=HGetState(storage);
  535.     ComponentStorageHdl sto;
  536.     Boolean didClose=false;
  537.     
  538.     HLock(storage);
  539.     sto=(ComponentStorageHdl)storage;
  540.     
  541.     (*sto)->specvalid=false;
  542.     
  543.     // save the fsspec stuff
  544.     res=FSMakeFSSpec(spec->vRefNum,spec->parID,spec->name,&((*sto)->spec));
  545.     
  546.     if ((res==noErr)||(res==fnfErr)){
  547.         (*sto)->specvalid=true;
  548.         (*sto)->needSaved=true;
  549.     }
  550.     
  551.     HSetState(storage,s);
  552.     
  553.     return res;
  554. }
  555.  
  556. pascal ComponentResult ComponentGetError(Handle storage,OSErr* err){
  557.     ComponentResult res=noErr;
  558.     SignedByte s=HGetState(storage);
  559.     ComponentStorageHdl sto;
  560.     
  561.     HLock(storage);
  562.     sto=(ComponentStorageHdl)storage;
  563.     
  564.     *err=(*sto)->err;
  565.     (*sto)->err=noErr;
  566.     
  567.     HSetState(storage,s);
  568.     
  569.     return res;
  570. }
  571.  
  572. /*
  573.     In PPC applications, constructors and destructors for global and static objects are called automatically
  574.     by __cplusstart, which is actually the main entry point to your application (and not main()).  This
  575.     routine calls your constructors, initializes your QuickDraw globals, calls your main() function, then
  576.     calls your destructors.
  577.     
  578.     In a shared library, constructors for global and static objects are called by __cplusinit, which the linker
  579.     assigns as an initialization routine.  The Code Fragment Manager will automatically call this initialization
  580.     routine when your shared library is loaded.  __cplusinit will also allow hook your shared library's
  581.     QuickDraw globals to the QuickDraw globals of the calling application.  Destructors for global and static
  582.     objects are called by __cplusterm, which the linker assigns as a termination routine.  The Code Fragment
  583.     Manager will automatically call this termination