/* * FireflyCommonConstants.h * * Created by Mike Kobb on 7/12/06. * Copyright 2006 Roku LLC. All rights reserved. * * This file contains common constants and types needed by both the * prefs pane and helper apps. */ #ifndef __ORG_FIREFLYMEDIASERVER_FIREFLY_COMMON_H #define __ORG_FIREFLYMEDIASERVER_FIREFLY_COMMON_H #include // used by GetProcesses #define FIREFLY_SERVER_NAME "firefly" #define FIREFLY_DIR_NAME "Firefly" #define FIREFLY_CONF_NAME "firefly.conf" #define FF_PREFS_DOMAIN "org.fireflymediaserver.firefly" #define FF_PREFS_LAUNCH_AT_LOGIN "org.fireflymediaserver.launchAtLogin" #define FF_PREFS_SHOW_MENU_EXTRA "org.fireflymediaserver.showMenuExtra" // Define this to enable certain debug output //#define FIREFLY_DEBUG typedef enum { kFireflyStartInvalid = 0, kFireflyStartSuccess = 1, kFireflyStartFail = 2 } FireflyStartResult; typedef enum { kFireflyStopInvalid = 0, kFireflyStopSuccess = 1, kFireflyStopFail = 2 } FireflyStopResult; typedef enum { kFireflyRestartInvalid = 0, kFireflyRestartSuccess = 1, kFireflyRestartFail = 2 } FireflyRestartResult; typedef enum { kFireflyRescanInvalid = 0, kFireflyRescanSuccess = 1, kFireflyRescanFail = 2 } FireflyRescanResult; typedef enum { kFireflyStatusInvalid, kFireflyStatusStopped, kFireflyStatusStarting, kFireflyStatusActive, kFireflyStatusScanning, kFireflyStatusStopping, kFireflyStatusRestarting, kFireflyStatusStartFailed, kFireflyStatusCrashed } FireflyServerStatus; static NSString* StringForFireflyStatus( FireflyServerStatus inStatus ) { NSString *retVal = nil; switch( inStatus ) { case kFireflyStatusStopped: retVal = NSLocalizedString( @"Firefly is not running", @"Status message for Firefly" ); break; case kFireflyStatusStarting: retVal = NSLocalizedString( @"Firefly is starting", @"Status message for Firefly" ); break; case kFireflyStatusActive: retVal = NSLocalizedString( @"Firefly is running", @"Status message for Firefly" ); break; case kFireflyStatusScanning: retVal = NSLocalizedString( @"Firefly is scanning the library", @"Status message for Firefly" ); break; case kFireflyStatusStopping: retVal = NSLocalizedString( @"Firefly is stopping", @"Status message for Firefly" ); break; case kFireflyStatusRestarting: retVal = NSLocalizedString( @"Firefly is restarting", @"Status message for Firefly" ); break; case kFireflyStatusStartFailed: retVal = NSLocalizedString( @"Firefly failed to start", @"Status message for Firefly" ); break; case kFireflyStatusCrashed: retVal = NSLocalizedString( @"Firefly stopped unexpectedly", @"Status message for Firefly" ); break; case kFireflyStatusInvalid: default: retVal = NSLocalizedString( @"Firefly status is unknown", @"Status message for Firefly" ); break; } return retVal; } // =========================================================================== // Process management the Unix way -- Finding if the server is already // running, or finding a specific process // =========================================================================== // This just makes syntax more convenient (don't have to say 'struct' everyplace) typedef struct kinfo_proc kinfo_proc; // ------------------------------------------------------------------------ // GetProcesses // // Static utility function allocates and returns an array of kinfo_proc // structures representing the currently-running processes on the machine. // The calling function is responsible for disposing the returned pointer // with free() // // Because Firefly runs as a BSD daemon, the Process Manager is not useful // in finding it. Instead, we have to talk to the BSD layer. This code // was provided by Apple in a tech note. // ------------------------------------------------------------------------ static void GetProcesses( kinfo_proc **outResult, size_t *outLength) { int err; kinfo_proc * result; BOOL done; static const int name[] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0 }; // Declaring name as const requires us to cast it when passing it to // sysctl because the prototype doesn't include the const modifier. // (That's the Apple comment, but they don't say *why* they made it const...) size_t length; // We call sysctl with result == NULL and length == 0. // That will succeed, and set length to the appropriate length. // We then allocate a buffer of that size and call sysctl again // with that buffer. If that succeeds, we're done. If that fails // with ENOMEM, we have to throw away our buffer and loop. Note // that the loop causes use to call sysctl with NULL again; this // is necessary because the ENOMEM failure case sets length to // the amount of data returned, not the amount of data that // could have been returned. result = NULL; done = NO; do { // Call sysctl with a NULL buffer. length = 0; err = sysctl( (int *) name, (sizeof(name) / sizeof(*name)) - 1, NULL, &length, NULL, 0); if (err == -1) err = errno; // Allocate an appropriately sized buffer based on the results // from the previous call. if (err == 0) { result = malloc(length); if (result == NULL) err = ENOMEM; } // Call sysctl again with the new buffer. If we get an ENOMEM // error, toss away our buffer and start again. if (err == 0) { err = sysctl( (int *) name, (sizeof(name) / sizeof(*name)) - 1, result, &length, NULL, 0); if (err == -1) err = errno; if (err == 0) done = YES; else if (err == ENOMEM) { free(result); result = NULL; err = 0; } } } while (err == 0 && !done); // Clean up and establish post conditions. if( err != 0 ) { if( result != NULL) free(result); *outResult = NULL; *outLength = 0; } if( err == 0 ) { *outResult = result; *outLength = length; } } // __ORG_FIREFLYMEDIASERVER_FIREFLY_COMMON_H #endif