Back to index

lightning-sunbird  0.9+nobinonly
Defines | Functions | Variables
InstallCleanupMac.cpp File Reference
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <MacTypes.h>
#include "MoreFiles.h"
#include "MoreFilesExtras.h"
#include "FullPath.h"
#include <AppleEvents.h>
#include <Gestalt.h>
#include <TextUtils.h>
#include <Folders.h>
#include <Processes.h>
#include <Resources.h>
#include <Aliases.h>
#include "InstallCleanup.h"
#include "InstallCleanupDefines.h"

Go to the source code of this file.

Defines

#define kSleepMax   60

Functions

int strcasecmp (const char *str1, const char *str2)
 Case-insensitive string comparison.
OSErr GetFSSpecFromPath (char *aPath, FSSpec *aSpec)
void my_c2pstrcpy (Str255 aDstPStr, const char *aSrcCStr)
OSErr GetCWD (short *aVRefNum, long *aDirID)
OSErr GetCleanupReg (FSSpec *aCleanupReg)
OSErr GetFSSpecFromPath (const char *aPath, FSSpec *aSpec)
int NativeDeleteFile (const char *aFileToDelete)
int NativeReplaceFile (const char *aReplacementFile, const char *aDoomedFile)
OSErr GetProgramSpec (FSSpecPtr aProgSpec)
void PutAliasInStartupItems (FSSpecPtr aAlias)
void RemoveAliasFromStartupItems (FSSpecPtr aAlias)
static pascal OSErr DoAEOpenApplication (const AppleEvent *theAppleEvent, AppleEvent *replyAppleEvent, long refCon)
static pascal OSErr DoAEOpenDocuments (const AppleEvent *theAppleEvent, AppleEvent *replyAppleEvent, long refCon)
static pascal OSErr DoAEPrintDocuments (const AppleEvent *theAppleEvent, AppleEvent *replyAppleEvent, long refCon)
static pascal OSErr DoAEQuitApplication (const AppleEvent *theAppleEvent, AppleEvent *replyAppleEvent, long refCon)
static void InitAppleEventsStuff (void)
static void DoHighLevelEvent (EventRecord *theEventRecPtr)
void main (void)
 main()

Variables

Boolean gAppleEventsFlag
Boolean gQuitFlag
long gSleepVal

Define Documentation

#define kSleepMax   60

Definition at line 58 of file InstallCleanupMac.cpp.


Function Documentation

static pascal OSErr DoAEOpenApplication ( const AppleEvent *  theAppleEvent,
AppleEvent *  replyAppleEvent,
long  refCon 
) [static]

Definition at line 384 of file InstallCleanupMac.cpp.

{
#pragma unused (theAppleEvent, replyAppleEvent, refCon)
    return noErr;
}

Here is the caller graph for this function:

static pascal OSErr DoAEOpenDocuments ( const AppleEvent *  theAppleEvent,
AppleEvent *  replyAppleEvent,
long  refCon 
) [static]

Definition at line 390 of file InstallCleanupMac.cpp.

{
#pragma unused (theAppleEvent, replyAppleEvent, refCon)
    return errAEEventNotHandled;
}

Here is the caller graph for this function:

static pascal OSErr DoAEPrintDocuments ( const AppleEvent *  theAppleEvent,
AppleEvent *  replyAppleEvent,
long  refCon 
) [static]

Definition at line 396 of file InstallCleanupMac.cpp.

{
#pragma unused (theAppleEvent, replyAppleEvent, refCon)
    return errAEEventNotHandled;
}

Here is the caller graph for this function:

static pascal OSErr DoAEQuitApplication ( const AppleEvent *  theAppleEvent,
AppleEvent *  replyAppleEvent,
long  refCon 
) [static]

Definition at line 402 of file InstallCleanupMac.cpp.

{
#pragma unused (theAppleEvent, replyAppleEvent, refCon)
    gQuitFlag = true;
    return noErr;
}

Here is the caller graph for this function:

static void DoHighLevelEvent ( EventRecord *  theEventRecPtr) [static]

Definition at line 444 of file InstallCleanupMac.cpp.

{
    (void) AEProcessAppleEvent(theEventRecPtr);
}

Here is the caller graph for this function:

OSErr GetCleanupReg ( FSSpec aCleanupReg)

Definition at line 161 of file InstallCleanupMac.cpp.

{
    OSErr err = noErr;
    short efVRefNum = 0;
    long efDirID = 0;
    
    if (!aCleanupReg)
        return paramErr;
        
    err = GetCWD(&efVRefNum, &efDirID);
    if (err == noErr)
    {
        Str255 pCleanupReg;
        my_c2pstrcpy(pCleanupReg, CLEANUP_REGISTRY);
        err = FSMakeFSSpec(efVRefNum, efDirID, pCleanupReg, aCleanupReg);
    }
    
    return err;
}

Here is the call graph for this function:

Here is the caller graph for this function:

OSErr GetCWD ( short *  aVRefNum,
long aDirID 
)

Definition at line 130 of file InstallCleanupMac.cpp.

{
    OSErr               err = noErr;
    ProcessSerialNumber psn;
    ProcessInfoRec      pInfo;
    FSSpec              tmp;
        
    if (!aVRefNum || !aDirID)
        return paramErr;
    
    *aVRefNum = 0;
    *aDirID = 0;
    
    /* get cwd based on curr ps info */
    if (!(err = GetCurrentProcess(&psn))) 
    {
        pInfo.processName = nil;
        pInfo.processAppSpec = &tmp;
        pInfo.processInfoLength = (sizeof(ProcessInfoRec));
             
        if(!(err = GetProcessInformation(&psn, &pInfo)))
        {   
            *aVRefNum = pInfo.processAppSpec->vRefNum;
            *aDirID = pInfo.processAppSpec->parID; 
        }
    }
      
    return err;
}

Here is the call graph for this function:

Here is the caller graph for this function:

OSErr GetFSSpecFromPath ( char *  aPath,
FSSpec aSpec 
)

Here is the caller graph for this function:

OSErr GetFSSpecFromPath ( const char *  aPath,
FSSpec aSpec 
)

Definition at line 99 of file InstallCleanupMac.cpp.

{
    if (!aPath || !aSpec)
        return paramErr;
        
    // 1> verify path is not an empty string
    // 2> verify path has leaf
    // 3> verify path does not start with leading ':'
    
    if ((!*aPath) || 
       (*(aPath + strlen(aPath) - 1) == ':') ||
       (*aPath == ':'))
    {
       return paramErr;
    }
    
    // path is kosher: get FSSpec for it
    return FSpLocationFromFullPath(strlen(aPath), (const void *) aPath, aSpec);
}
OSErr GetProgramSpec ( FSSpecPtr  aProgSpec)

Definition at line 281 of file InstallCleanupMac.cpp.

{
       OSErr                       err = noErr;
       ProcessSerialNumber  psn;
       ProcessInfoRec              pInfo;
       
       if (!aProgSpec)
           return paramErr;
           
       /* get cwd based on curr ps info */
       if (!(err = GetCurrentProcess(&psn))) 
       {
              pInfo.processName = nil;
              pInfo.processAppSpec = aProgSpec;
              pInfo.processInfoLength = (sizeof(ProcessInfoRec));
              
              err = GetProcessInformation(&psn, &pInfo);
       }
       
       return err;
}

Here is the caller graph for this function:

static void InitAppleEventsStuff ( void  ) [static]

Definition at line 414 of file InstallCleanupMac.cpp.

{
    OSErr retCode;

    if (gAppleEventsFlag) {

        retCode = AEInstallEventHandler(kCoreEventClass, kAEOpenApplication,
                    NewAEEventHandlerUPP(DoAEOpenApplication), 0, false);

        if (retCode == noErr)
            retCode = AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments,
                    NewAEEventHandlerUPP(DoAEOpenDocuments), 0, false);

        if (retCode == noErr)
            retCode = AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments,
                    NewAEEventHandlerUPP(DoAEPrintDocuments), 0, false);
        if (retCode == noErr)
            retCode = AEInstallEventHandler(kCoreEventClass, kAEQuitApplication,
                    NewAEEventHandlerUPP(DoAEQuitApplication), 0, false);

        if (retCode != noErr) DebugStr("\pInstall event handler failed");
        // a better way to indicate an error is to post a notification
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void main ( void  )

main()

Definition at line 452 of file InstallCleanupMac.cpp.

{
    OSErr retCode;
    long gestResponse;
    FSSpec aliasToSelf;
    FSSpec fsCleanupReg;

    EventRecord mainEventRec;
    Boolean eventFlag, bDone = false, bHaveCleanupReg = false;
    
    HREG reg;
    int rv = DONE;

#if !TARGET_CARBON
    // initialize QuickDraw globals
    InitGraf(&qd.thePort);
#endif

    // initialize application globals
    gQuitFlag = false;
    gSleepVal = kSleepMax;

    // is the Apple Event Manager available?
    retCode = Gestalt(gestaltAppleEventsAttr, &gestResponse);
    if (retCode == noErr &&
        (gestResponse & (1 << gestaltAppleEventsPresent)) != 0)
        gAppleEventsFlag = true;
    else gAppleEventsFlag = false;

    // install Apple event handlers
    InitAppleEventsStuff();

    // put an alias to ourselves in the Startup Items folder
    // so that if we are shutdown before finishing we do our 
    // tasks at startup
    FSMakeFSSpec(0, 0, "\p", &aliasToSelf);  // initialize
    PutAliasInStartupItems(&aliasToSelf);
    
    if ( REGERR_OK == NR_StartupRegistry() )
    {
        char *regName = "";
        Boolean regNameAllocd = false;
        Handle pathH = 0;
        short pathLen = 0;
        
        // check if XPICleanup data file exists
        retCode = GetCleanupReg(&fsCleanupReg);
        if (retCode == noErr)
        {
            bHaveCleanupReg = true;
            
            // get full path to give to libreg open routine
            retCode = FSpGetFullPath(&fsCleanupReg, &pathLen, &pathH);
            if (retCode == noErr && pathH)
            {
                HLock(pathH);
                if (*pathH)
                {
                    regName = (char *) malloc(sizeof(char) * (pathLen + 1));
                    if (regName)
                        regNameAllocd = true;
                    else
                        retCode = memFullErr;
                    strncpy(regName, *pathH, pathLen);
                    *(regName + pathLen) = 0;
                }
                HUnlock(pathH);
                DisposeHandle(pathH);
            }
        }
            
        if ( (retCode == noErr) && (REGERR_OK == NR_RegOpen(regName, &reg)) )
        {
            // main event loop

            while (!gQuitFlag)
            {
                eventFlag = WaitNextEvent(everyEvent, &mainEventRec, gSleepVal, nil);

                if (mainEventRec.what == kHighLevelEvent)
                    DoHighLevelEvent(&mainEventRec);

                rv = PerformScheduledTasks(reg);
                if (rv == DONE)
                {
                    bDone = true;
                    gQuitFlag = true;
                }
            }
            NR_RegClose(&reg);
            NR_ShutdownRegistry();
        }
        
        if (regNameAllocd)
            free(regName);      
    }
    
    // clean up the alias to ouselves since we have 
    // completed our tasks successfully
    if (bDone)
    {
        if (bHaveCleanupReg)
            FSpDelete(&fsCleanupReg);
        RemoveAliasFromStartupItems(&aliasToSelf);
    }
}

Here is the call graph for this function:

void my_c2pstrcpy ( Str255  aDstPStr,
const char *  aSrcCStr 
)

Definition at line 120 of file InstallCleanupMac.cpp.

{
    if (!aSrcCStr)
        return;
    
    memcpy(&aDstPStr[1], aSrcCStr, strlen(aSrcCStr) > 255 ? 255 : strlen(aSrcCStr));
    aDstPStr[0] = strlen(aSrcCStr);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int NativeDeleteFile ( const char *  aFileToDelete)

Definition at line 187 of file InstallCleanupMac.cpp.

{
    OSErr err;
    FSSpec delSpec;
    
    if (!aFileToDelete)
        return DONE;
        
    // stat the file
    err = GetFSSpecFromPath(aFileToDelete, &delSpec);
    if (err != noErr)
    {
        // return fine if it doesn't exist
        return DONE;
    }
        
    // else try to delete it
    err = FSpDelete(&delSpec);
    if (err != noErr)
    {
        // tell user to try again later if deletion failed
        return TRY_LATER;
    }

    return DONE;
}

Here is the call graph for this function:

int NativeReplaceFile ( const char *  aReplacementFile,
const char *  aDoomedFile 
)

Definition at line 217 of file InstallCleanupMac.cpp.

{
    OSErr err;
    FSSpec replSpec, doomSpec, tgtDirSpec;
    long dirID;
    Boolean isDir;
    
    if (!aReplacementFile || !aDoomedFile)
        return DONE;
        
    err = GetFSSpecFromPath(aReplacementFile, &replSpec);
    if (err != noErr)
        return DONE;
                      
    // stat replacement file
    err = FSpGetDirectoryID(&replSpec, &dirID, &isDir);
    if (err != noErr || isDir)
    {
        // return fine if it doesn't exist
        return DONE;
    }
        
    // check if the replacement file and doomed file are the same
    if (strcasecmp(aReplacementFile, aDoomedFile) == 0)
    {
        // return fine if they are the same
        return DONE;
    }
        
    // try and delete doomed file (NOTE: this call also stats)
    err = GetFSSpecFromPath(aDoomedFile, &doomSpec); 
    if (err == noErr)
    { 
        // (will even try to delete a dir with this name)
        err = FSpDelete(&doomSpec);
        
        // if deletion failed tell user to try again later
        if (err != noErr)
            return TRY_LATER;
    }
    
    // get the target dir spec (parent directory of doomed file)
    err = FSMakeFSSpec(doomSpec.vRefNum, doomSpec.parID, "\p", &tgtDirSpec);
    if (err == noErr)
    {
        // now try and move replacment file to path of doomed file
        err = FSpMoveRename(&replSpec, &tgtDirSpec, doomSpec.name);
        if (err != noErr)
        {
            // if move failed tell user to try agian later
            return TRY_LATER;
        }
    }
        
    return DONE;
}

Here is the call graph for this function:

Definition at line 304 of file InstallCleanupMac.cpp.

{
    OSErr err;
    FSSpec fsProg, fsAlias;
    long strtDirID = 0;
    short strtVRefNum = 0;
    FInfo info;
    AliasHandle aliasH;

    if (!aAlias)
        return;
        
    // find cwd
    err = GetProgramSpec(&fsProg);
    if (err != noErr)
        return;  // fail silently
     
    // get startup items folder
    err = FindFolder(kOnSystemDisk, kStartupFolderType, kCreateFolder, 
                     &strtVRefNum, &strtDirID);
    if (err != noErr)
        return;
             
    // check that an alias to ourselves doesn't already
    // exist in the Startup Items folder
    err = FSMakeFSSpec(strtVRefNum, strtDirID, fsProg.name, &fsAlias);
    if (err == noErr)
    {
        // one's already there; not sure it's us so delete and recreate
        // (being super paranoid; but hey it's a mac)
        err = FSpDelete(&fsAlias);
        if (err != noErr)
            return;  // fail silently
    }
      
    // create the alias file
    err = NewAliasMinimal(&fsProg, &aliasH);
    if (err != noErr) 
        return;
        
    FSpGetFInfo(&fsProg, &info);
    FSpCreateResFile(&fsAlias, info.fdCreator, info.fdType, smRoman);
    short refNum = FSpOpenResFile(&fsAlias, fsRdWrPerm);
    if (refNum != -1)
    {
        UseResFile(refNum);
        AddResource((Handle)aliasH, rAliasType, 0, fsAlias.name);
        ReleaseResource((Handle)aliasH);
        UpdateResFile(refNum);
        CloseResFile(refNum);
    }
    else
    {
        ReleaseResource((Handle)aliasH);
        FSpDelete(&fsAlias);
        return;  // non-fatal error
    }

    // mark newly created file as an alias file
    FSpGetFInfo(&fsAlias, &info);
    info.fdFlags |= kIsAlias;
    FSpSetFInfo(&fsAlias, &info);    
    
    *aAlias = fsAlias;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 371 of file InstallCleanupMac.cpp.

{
    // try to delete the alias
    FSpDelete(aAlias);
}

Here is the caller graph for this function:

int strcasecmp ( const char *  str1,
const char *  str2 
)

Case-insensitive string comparison.

Definition at line 70 of file InstallCleanupMac.cpp.

{
    char    currentChar1, currentChar2;

    while (1) {
    
        currentChar1 = *str1;
        currentChar2 = *str2;
        
        if ((currentChar1 >= 'a') && (currentChar1 <= 'z'))
            currentChar1 += ('A' - 'a');
        
        if ((currentChar2 >= 'a') && (currentChar2 <= 'z'))
            currentChar2 += ('A' - 'a');
                
        if (currentChar1 == '\0')
            break;
    
        if (currentChar1 != currentChar2)
            return currentChar1 - currentChar2;
            
        str1++;
        str2++;
    
    }
    
    return currentChar1 - currentChar2;
}

Variable Documentation

Definition at line 60 of file InstallCleanupMac.cpp.

Definition at line 60 of file InstallCleanupMac.cpp.

Definition at line 61 of file InstallCleanupMac.cpp.