|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* swinst.c : hrSWInstalledTable data access
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Copyright (C) 2007 Apple, Inc. All rights reserved.
|
|
Packit |
fcad23 |
* Use is subject to license terms specified in the COPYING file
|
|
Packit |
fcad23 |
* distributed with the Net-SNMP package.
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
#include <net-snmp/net-snmp-config.h>
|
|
Packit |
fcad23 |
#include <net-snmp/net-snmp-features.h>
|
|
Packit |
fcad23 |
#include <net-snmp/net-snmp-includes.h>
|
|
Packit |
fcad23 |
#include <net-snmp/agent/net-snmp-agent-includes.h>
|
|
Packit |
fcad23 |
#include <net-snmp/library/container.h>
|
|
Packit |
fcad23 |
#include <net-snmp/library/dir_utils.h>
|
|
Packit |
fcad23 |
#include <net-snmp/library/snmp_debug.h>
|
|
Packit |
fcad23 |
#include <net-snmp/data_access/swinst.h>
|
|
Packit |
fcad23 |
#include "swinst_private.h"
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#include <stdlib.h>
|
|
Packit |
fcad23 |
#include <unistd.h>
|
|
Packit |
fcad23 |
#include <dirent.h>
|
|
Packit |
fcad23 |
#include <sys/stat.h>
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#define __APPLE_API_EVOLVING 1
|
|
Packit |
fcad23 |
#include <sys/acl.h> /* or else CoreFoundation.h barfs */
|
|
Packit |
fcad23 |
#undef __APPLE_API_EVOLVING
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#include <CoreFoundation/CoreFoundation.h>
|
|
Packit |
fcad23 |
#include <ApplicationServices/ApplicationServices.h>
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
netsnmp_feature_require(container_directory)
|
|
Packit |
fcad23 |
netsnmp_feature_require(date_n_time)
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/* ---------------------------------------------------------------------
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
static int _add_applications_in_dir(netsnmp_container *, const char* path);
|
|
Packit |
fcad23 |
static int32_t _index;
|
|
Packit |
fcad23 |
static int _check_bundled_app(CFURLRef currentURL, CFStringRef *name,
|
|
Packit |
fcad23 |
CFStringRef *info, const char* path);
|
|
Packit |
fcad23 |
static int _check_classic_app(CFURLRef currentURL, CFStringRef *name,
|
|
Packit |
fcad23 |
CFStringRef *info, const char* path);
|
|
Packit |
fcad23 |
static netsnmp_container *dirs = NULL;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/* ---------------------------------------------------------------------
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
void
|
|
Packit |
fcad23 |
netsnmp_swinst_arch_init( void )
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
struct stat stat_buf;
|
|
Packit |
fcad23 |
const char *default_dirs[] = {
|
|
Packit |
fcad23 |
"/Applications",
|
|
Packit |
fcad23 |
"/Applications (Mac OS 9)",
|
|
Packit |
fcad23 |
"/System/Library/CoreServices",
|
|
Packit |
fcad23 |
"/System/Library/Extensions",
|
|
Packit |
fcad23 |
"/System/Library/Services"
|
|
Packit |
fcad23 |
#ifdef TEST
|
|
Packit |
fcad23 |
, "/Developer/Applications"
|
|
Packit |
fcad23 |
, "/Volumes/audX/Applications (Mac OS 9)"
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
};
|
|
Packit |
fcad23 |
int i, count = sizeof(default_dirs)/sizeof(default_dirs[0]);
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* create the container, if needed
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
if (NULL == dirs) {
|
|
Packit |
fcad23 |
dirs = netsnmp_container_find("directory_container:cstring");
|
|
Packit |
fcad23 |
if (NULL == dirs) {
|
|
Packit |
fcad23 |
snmp_log(LOG_ERR, "couldn't allocate container for dir list\n");
|
|
Packit |
fcad23 |
return;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
dirs->container_name = strdup("directory search list");
|
|
Packit |
fcad23 |
netsnmp_binary_array_options_set(dirs, 1, CONTAINER_KEY_UNSORTED);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* add dirs
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
for(i = 0; i < count; ++i) {
|
|
Packit |
fcad23 |
char * tmp;
|
|
Packit |
fcad23 |
/** xxx: get/save the last mod date? */
|
|
Packit |
fcad23 |
if(-1 == stat(default_dirs[i], &stat_buf)) {
|
|
Packit |
fcad23 |
DEBUGMSGTL(("swinst:arch:darwin", "skipping dir %s\n",
|
|
Packit |
fcad23 |
default_dirs[i]));
|
|
Packit |
fcad23 |
continue;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
DEBUGMSGTL(("swinst:arch:darwin", "adding dir %s\n",
|
|
Packit |
fcad23 |
default_dirs[i]));
|
|
Packit |
fcad23 |
tmp = strdup(default_dirs[i]);
|
|
Packit |
fcad23 |
if (NULL == tmp) {
|
|
Packit |
fcad23 |
snmp_log(LOG_ERR,"strdup failed\n");
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
CONTAINER_INSERT(dirs, tmp);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
void
|
|
Packit |
fcad23 |
netsnmp_swinst_arch_shutdown( void )
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
netsnmp_directory_container_free(dirs);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/* ---------------------------------------------------------------------
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
int
|
|
Packit |
fcad23 |
netsnmp_swinst_arch_load( netsnmp_container *container, u_int flags )
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
netsnmp_iterator *it;
|
|
Packit |
fcad23 |
const char *dir;
|
|
Packit |
fcad23 |
int rc;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
DEBUGMSGTL(("swinst:arch:darwin", "load\n"));
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (NULL == dirs) {
|
|
Packit |
fcad23 |
DEBUGMSGTL(("swinst:arch:darwin", "no dirs to scan!\n"));
|
|
Packit |
fcad23 |
return -1;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
_index = 0;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
it = CONTAINER_ITERATOR(dirs);
|
|
Packit |
fcad23 |
for (dir = ITERATOR_FIRST(it); dir; dir = ITERATOR_NEXT(it)) {
|
|
Packit |
fcad23 |
rc = _add_applications_in_dir(container, dir);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
ITERATOR_RELEASE(it);
|
|
Packit |
fcad23 |
DEBUGMSGTL(("swinst:arch:darwin", "loaded %d apps\n",_index));
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
return 0;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
static void
|
|
Packit |
fcad23 |
_dump_flags(u_long flags)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
static struct {
|
|
Packit |
fcad23 |
const char*name;
|
|
Packit |
fcad23 |
u_long bits;
|
|
Packit |
fcad23 |
} names[] = {
|
|
Packit |
fcad23 |
{ "kLSItemInfoIsPlainFile", 0x00000001 },
|
|
Packit |
fcad23 |
{ "kLSItemInfoIsPackage", 0x00000002 },
|
|
Packit |
fcad23 |
{ "kLSItemInfoIsApplication", 0x00000004 },
|
|
Packit |
fcad23 |
{ "kLSItemInfoIsContainer", 0x00000008 },
|
|
Packit |
fcad23 |
{ "kLSItemInfoIsAliasFile", 0x00000010 },
|
|
Packit |
fcad23 |
{ "kLSItemInfoIsSymlink", 0x00000020 },
|
|
Packit |
fcad23 |
{ "kLSItemInfoIsInvisible", 0x00000040 },
|
|
Packit |
fcad23 |
{ "kLSItemInfoIsNativeApp", 0x00000080 },
|
|
Packit |
fcad23 |
{ "kLSItemInfoIsClassicApp", 0x00000100 },
|
|
Packit |
fcad23 |
{ "kLSItemInfoAppPrefersNative", 0x00000200 },
|
|
Packit |
fcad23 |
{ "kLSItemInfoAppPrefersClassic", 0x00000400 },
|
|
Packit |
fcad23 |
{ "kLSItemInfoAppIsScriptable", 0x00000800 },
|
|
Packit |
fcad23 |
{ "kLSItemInfoIsVolume", 0x00001000 },
|
|
Packit |
fcad23 |
{ "kLSItemInfoExtensionIsHidden", 0x00100000 }
|
|
Packit |
fcad23 |
};
|
|
Packit |
fcad23 |
int i, count = sizeof(names)/sizeof(names[0]);
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
for(i = 0; i < count; ++i) {
|
|
Packit |
fcad23 |
if (flags & names[i].bits) {
|
|
Packit |
fcad23 |
DEBUGMSGTL(("swinst:arch:darwin:flags", "\t%s\n",
|
|
Packit |
fcad23 |
names[i].name));
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
static int
|
|
Packit |
fcad23 |
_add_applications_in_dir(netsnmp_container *container, const char* path)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
netsnmp_container *files;
|
|
Packit |
fcad23 |
netsnmp_iterator *it;
|
|
Packit |
fcad23 |
const char *file;
|
|
Packit |
fcad23 |
netsnmp_swinst_entry *entry = NULL;
|
|
Packit |
fcad23 |
struct stat stat_buf;
|
|
Packit |
fcad23 |
size_t date_len;
|
|
Packit |
fcad23 |
u_char *date_buf;
|
|
Packit |
fcad23 |
int rc = 0;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
CFStringRef currentPath = NULL;
|
|
Packit |
fcad23 |
CFURLRef currentURL = NULL;
|
|
Packit |
fcad23 |
LSItemInfoRecord itemInfoRecord;
|
|
Packit |
fcad23 |
CFStringRef prodName = NULL;
|
|
Packit |
fcad23 |
CFStringRef version = NULL;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
DEBUGMSGTL(("swinst:arch:darwin", " adding files from %s\n", path));
|
|
Packit |
fcad23 |
files = netsnmp_directory_container_read(NULL, path, 0);
|
|
Packit |
fcad23 |
if (NULL == files) {
|
|
Packit |
fcad23 |
snmp_log(LOG_ERR, "swinst: could not read directory %s\n", path);
|
|
Packit |
fcad23 |
return -1;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
it = CONTAINER_ITERATOR(files);
|
|
Packit |
fcad23 |
if (NULL == it) {
|
|
Packit |
fcad23 |
snmp_log(LOG_ERR, "could not get iterator\n");
|
|
Packit |
fcad23 |
netsnmp_directory_container_free(files);
|
|
Packit |
fcad23 |
return -1;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
for (file = ITERATOR_FIRST(it);
|
|
Packit |
fcad23 |
file;
|
|
Packit |
fcad23 |
file = ITERATOR_NEXT(it),
|
|
Packit |
fcad23 |
CFRelease(currentPath),
|
|
Packit |
fcad23 |
CFRelease(currentURL)) {
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
int rc2 = 0;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
currentPath =
|
|
Packit |
fcad23 |
CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, file,
|
|
Packit |
fcad23 |
kCFStringEncodingUTF8,
|
|
Packit |
fcad23 |
kCFAllocatorNull);
|
|
Packit |
fcad23 |
currentURL =
|
|
Packit |
fcad23 |
CFURLCreateWithFileSystemPath(kCFAllocatorDefault, currentPath,
|
|
Packit |
fcad23 |
kCFURLPOSIXPathStyle, true);
|
|
Packit |
fcad23 |
LSCopyItemInfoForURL(currentURL,
|
|
Packit |
fcad23 |
kLSRequestBasicFlagsOnly|kLSRequestAppTypeFlags,
|
|
Packit |
fcad23 |
&itemInfoRecord);
|
|
Packit |
fcad23 |
if((0 == itemInfoRecord.flags) ||
|
|
Packit |
fcad23 |
(kLSItemInfoIsPlainFile == itemInfoRecord.flags) ||
|
|
Packit |
fcad23 |
(itemInfoRecord.flags & kLSItemInfoIsInvisible) ||
|
|
Packit |
fcad23 |
(itemInfoRecord.flags & kLSItemInfoIsAliasFile)) {
|
|
Packit |
fcad23 |
continue;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
/** recurse on non-application containers (i.e. directory) */
|
|
Packit |
fcad23 |
if ((itemInfoRecord.flags & kLSItemInfoIsContainer) &&
|
|
Packit |
fcad23 |
(!(itemInfoRecord.flags & kLSItemInfoIsApplication))) {
|
|
Packit |
fcad23 |
netsnmp_directory_container_read(files, file, 0);
|
|
Packit |
fcad23 |
continue;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/** skip any other non-application files */
|
|
Packit |
fcad23 |
if (!(itemInfoRecord.flags & kLSItemInfoIsApplication)) {
|
|
Packit |
fcad23 |
continue;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if ((itemInfoRecord.flags & kLSItemInfoIsPackage) ||
|
|
Packit |
fcad23 |
(itemInfoRecord.flags & kLSItemInfoIsContainer)) {
|
|
Packit |
fcad23 |
rc2 = _check_bundled_app(currentURL, &prodName, &version, file);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
else if ((itemInfoRecord.flags & kLSItemInfoIsClassicApp) ||
|
|
Packit |
fcad23 |
(itemInfoRecord.flags & kLSItemInfoIsPlainFile)) {
|
|
Packit |
fcad23 |
rc2 = _check_classic_app(currentURL, &prodName, &version, file);
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
snmp_log(LOG_ERR,"swinst shouldn't get here: %s\n", file);
|
|
Packit |
fcad23 |
_dump_flags(itemInfoRecord.flags);
|
|
Packit |
fcad23 |
continue;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
if (rc2) { /* not an app. if directory, recurse; else continue */
|
|
Packit |
fcad23 |
_dump_flags(itemInfoRecord.flags);
|
|
Packit |
fcad23 |
if (1 == rc2)
|
|
Packit |
fcad23 |
netsnmp_directory_container_read(files, file, 0);
|
|
Packit |
fcad23 |
continue;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* allocate entry
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
entry = netsnmp_swinst_entry_create(++_index);
|
|
Packit |
fcad23 |
if (NULL == entry) {
|
|
Packit |
fcad23 |
snmp_log(LOG_ERR, "error creating swinst entry\n");
|
|
Packit |
fcad23 |
rc = -1;
|
|
Packit |
fcad23 |
SNMP_CFRelease(prodName);
|
|
Packit |
fcad23 |
SNMP_CFRelease(version);
|
|
Packit |
fcad23 |
CFRelease(currentPath);
|
|
Packit |
fcad23 |
CFRelease(currentURL);
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
entry->swName_len =
|
|
Packit |
fcad23 |
snprintf(entry->swName, sizeof(entry->swName),
|
|
Packit |
fcad23 |
"%s %s", CFStringGetCStringPtr(prodName,0),
|
|
Packit |
fcad23 |
CFStringGetCStringPtr(version,0));
|
|
Packit |
fcad23 |
if (entry->swName_len >= sizeof(entry->swName))
|
|
Packit |
fcad23 |
entry->swName_len = sizeof(entry->swName)-1;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
DEBUGMSGTL(("swinst:arch:darwin", "\t%s %s\n", file, entry->swName));
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/** get the last mod date */
|
|
Packit |
fcad23 |
if(stat(file, &stat_buf) != -1) {
|
|
Packit |
fcad23 |
date_buf = date_n_time(&stat_buf.st_mtime, &date_len);
|
|
Packit |
fcad23 |
entry->swDate_len = date_len;
|
|
Packit |
fcad23 |
memcpy(entry->swDate, date_buf, entry->swDate_len);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
CONTAINER_INSERT(container, entry);
|
|
Packit |
fcad23 |
entry = NULL;
|
|
Packit |
fcad23 |
SNMP_CFRelease(prodName);
|
|
Packit |
fcad23 |
SNMP_CFRelease(version);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
ITERATOR_RELEASE(it);
|
|
Packit |
fcad23 |
netsnmp_directory_container_free(files);
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
return rc;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
static int
|
|
Packit |
fcad23 |
_check_bundled_app(CFURLRef currentURL, CFStringRef *prodName,
|
|
Packit |
fcad23 |
CFStringRef *version, const char* file)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
CFBundleRef theBundle = NULL;
|
|
Packit |
fcad23 |
CFDictionaryRef infoDict = NULL;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if ((NULL == prodName) || (NULL == version))
|
|
Packit |
fcad23 |
return -1;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
theBundle = CFBundleCreate (kCFAllocatorDefault, currentURL);
|
|
Packit |
fcad23 |
if(theBundle == NULL)
|
|
Packit |
fcad23 |
return -1; /* not a bundle */
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
infoDict = CFBundleGetInfoDictionary(theBundle);
|
|
Packit |
fcad23 |
if(0 == CFDictionaryGetCount(infoDict)) {
|
|
Packit |
fcad23 |
SNMP_CFRelease(theBundle);
|
|
Packit |
fcad23 |
return 1; /* directory */
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
*prodName = (CFStringRef)
|
|
Packit |
fcad23 |
CFDictionaryGetValue (infoDict, CFSTR("CFBundleName"));
|
|
Packit |
fcad23 |
if (NULL == *prodName) {
|
|
Packit |
fcad23 |
*prodName = (CFStringRef)
|
|
Packit |
fcad23 |
CFDictionaryGetValue (infoDict, CFSTR("CFBundleDisplayName"));
|
|
Packit |
fcad23 |
if (NULL == *prodName) {
|
|
Packit |
fcad23 |
*prodName = (CFStringRef) CFDictionaryGetValue (infoDict,
|
|
Packit |
fcad23 |
CFSTR("CFBundleExecutable"));
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
if(NULL == *prodName) {
|
|
Packit |
fcad23 |
DEBUGMSGTL(("swinst:arch:darwin", "\tmissing name: %s\n",file));
|
|
Packit |
fcad23 |
/*CFShow(infoDict);*/
|
|
Packit |
fcad23 |
SNMP_CFRelease(theBundle);
|
|
Packit |
fcad23 |
return -1;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
*version = (CFStringRef)
|
|
Packit |
fcad23 |
CFDictionaryGetValue (infoDict, CFSTR("CFBundleShortVersionString"));
|
|
Packit |
fcad23 |
if(NULL == *version) {
|
|
Packit |
fcad23 |
*version = (CFStringRef)
|
|
Packit |
fcad23 |
CFDictionaryGetValue (infoDict, CFSTR("CFBundleVersion"));
|
|
Packit |
fcad23 |
if (*version == NULL)
|
|
Packit |
fcad23 |
*version = (CFStringRef) CFDictionaryGetValue (infoDict,
|
|
Packit |
fcad23 |
CFSTR("CFBundleGetInfoString"));
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
if(NULL == *version) {
|
|
Packit |
fcad23 |
DEBUGMSGTL(("swinst:arch:darwin", "\tmissing version: %s\n",file));
|
|
Packit |
fcad23 |
/*CFShow(infoDict);*/
|
|
Packit |
fcad23 |
SNMP_CFRelease(theBundle);
|
|
Packit |
fcad23 |
return -1;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if(theBundle != NULL) {
|
|
Packit |
fcad23 |
CFRetain(*prodName);
|
|
Packit |
fcad23 |
CFRetain(*version);
|
|
Packit |
fcad23 |
SNMP_CFRelease(theBundle);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
return 0;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
static int
|
|
Packit |
fcad23 |
_check_classic_app(CFURLRef currentURL, CFStringRef *prodName,
|
|
Packit |
fcad23 |
CFStringRef *version, const char* file)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* get info for classic or single-file apps
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
FSRef theFSRef;
|
|
Packit |
fcad23 |
int theResFile;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if ((NULL == prodName) || (NULL == version))
|
|
Packit |
fcad23 |
return -1;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
*prodName = CFURLCopyLastPathComponent(currentURL);
|
|
Packit |
fcad23 |
if (! CFURLGetFSRef(currentURL, &theFSRef)) {
|
|
Packit |
fcad23 |
DEBUGMSGTL(("swinst:arch:darwin", "GetFSRef failed: %s\n", file));
|
|
Packit |
fcad23 |
SNMP_CFRelease(*prodName);
|
|
Packit |
fcad23 |
return -1;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
theResFile = FSOpenResFile(&theFSRef, fsRdPerm);
|
|
Packit |
fcad23 |
if (ResError() != noErr) {
|
|
Packit |
fcad23 |
DEBUGMSGTL(("swinst:arch:darwin", "FSOpenResFile failed: %s\n", file));
|
|
Packit |
fcad23 |
SNMP_CFRelease(*prodName);
|
|
Packit |
fcad23 |
return -1;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
VersRecHndl versHandle = (VersRecHndl)Get1IndResource('vers', 1);
|
|
Packit |
fcad23 |
if (versHandle != NULL) {
|
|
Packit |
fcad23 |
*version = CFStringCreateWithPascalString(kCFAllocatorDefault,
|
|
Packit |
fcad23 |
(**versHandle).shortVersion, kCFStringEncodingMacRoman);
|
|
Packit |
fcad23 |
if (*version == NULL) {
|
|
Packit |
fcad23 |
StringPtr longVersionPtr = (**versHandle).shortVersion;
|
|
Packit |
fcad23 |
longVersionPtr = (StringPtr)(((Ptr) longVersionPtr) +
|
|
Packit |
fcad23 |
1 + ((unsigned char) *longVersionPtr));
|
|
Packit |
fcad23 |
*version = CFStringCreateWithPascalString(kCFAllocatorDefault,
|
|
Packit |
fcad23 |
longVersionPtr, kCFStringEncodingMacRoman);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
ReleaseResource((Handle)versHandle);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
CloseResFile(theResFile);
|
|
Packit |
fcad23 |
if(*version == NULL) {
|
|
Packit |
fcad23 |
DEBUGMSGTL(("swinst:arch:darwin",
|
|
Packit |
fcad23 |
"\tmissing classic/file version: %s\n", file));
|
|
Packit |
fcad23 |
SNMP_CFRelease(*prodName);
|
|
Packit |
fcad23 |
return -1;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
return 0;
|
|
Packit |
fcad23 |
}
|