PsychError SCREENComputer(void) { const char *majorStructFieldNames[]={"macintosh", "windows", "osx" ,"linux", "kern", "hw", "processUserLongName", "processUserShortName", "consoleUserName", "machineName", "localHostName", "location", "MACAddress", "system" }; const char *kernStructFieldNames[]={"ostype", "osrelease", "osrevision", "version","hostname"}; const char *hwStructFieldNames[]={"machine", "model", "ncpu", "physmem", "usermem", "busfreq", "cpufreq"}; int numMajorStructDimensions=1, numKernStructDimensions=1, numHwStructDimensions=1; int numMajorStructFieldNames=14, numKernStructFieldNames=5, numHwStructFieldNames=7; PsychGenericScriptType *kernStruct, *hwStruct, *majorStruct; //char tempStr[CTL_MAXNAME]; //this seems like a bug in Darwin, CTL_MAXNAME is shorter than the longest name. char tempStr[256], *ethernetMACStr; size_t tempIntSize, tempStrSize, tempULongIntSize; int mib[2]; int tempInt; unsigned long int tempULongInt; char *tempStrPtr; CFStringRef tempCFStringRef; psych_bool stringSuccess; int stringLengthChars, ethernetMACStrSizeBytes; long gestaltResult; OSErr gestaltError; // Str255 systemVersionStr, systemVersionStrForward; int i,strIndex, bcdDigit, lengthSystemVersionString; long osMajor, osMinor, osBugfix; char systemVersionStr[256]; //all subfunctions should have these two lines PsychPushHelp(useString, synopsisString, seeAlsoString); if(PsychIsGiveHelp()){PsychGiveHelp();return(PsychError_none);}; PsychErrorExit(PsychCapNumOutputArgs(1)); PsychErrorExit(PsychCapNumInputArgs(0)); //fill the major struct PsychAllocOutStructArray(1, FALSE, numMajorStructDimensions, numMajorStructFieldNames, majorStructFieldNames, &majorStruct); PsychSetStructArrayDoubleElement("macintosh", 0, 0, majorStruct); PsychSetStructArrayDoubleElement("windows", 0, 0, majorStruct); PsychSetStructArrayDoubleElement("linux", 0, 0, majorStruct); PsychSetStructArrayDoubleElement("osx", 0, 1, majorStruct); //fill the kern struct and implant it within the major struct PsychAllocOutStructArray(-1, FALSE, numKernStructDimensions, numKernStructFieldNames, kernStructFieldNames, &kernStruct); mib[0]=CTL_KERN; mib[1]=KERN_OSTYPE; tempStrSize=sizeof(tempStr); ReportSysctlError(sysctl(mib, 2, tempStr, &tempStrSize, NULL, 0)); PsychSetStructArrayStringElement("ostype", 0, tempStr, kernStruct); mib[1]=KERN_OSRELEASE; tempStrSize=sizeof(tempStr); ReportSysctlError(sysctl(mib, 2, tempStr, &tempStrSize, NULL, 0)); PsychSetStructArrayStringElement("osrelease", 0, tempStr, kernStruct); mib[1]=KERN_OSREV; tempIntSize=sizeof(tempInt); ReportSysctlError(sysctl(mib, 2, &tempInt, &tempIntSize, NULL, 0)); PsychSetStructArrayDoubleElement("osrevision", 0, (double)tempInt, kernStruct); mib[1]=KERN_VERSION; tempStrSize=sizeof(tempStr); ReportSysctlError(sysctl(mib, 2, tempStr, &tempStrSize, NULL, 0)); PsychSetStructArrayStringElement("version", 0, tempStr, kernStruct); mib[1]=KERN_HOSTNAME; tempStrSize=sizeof(tempStr); ReportSysctlError(sysctl(mib, 2, tempStr, &tempStrSize, NULL, 0)); PsychSetStructArrayStringElement("hostname", 0, tempStr, kernStruct); PsychSetStructArrayStructElement("kern",0, kernStruct, majorStruct); //fill the hw struct and implant it within the major struct PsychAllocOutStructArray(-1, FALSE, numHwStructDimensions, numHwStructFieldNames, hwStructFieldNames, &hwStruct); mib[0]=CTL_HW; mib[1]=HW_MACHINE; tempStrSize=sizeof(tempStr); ReportSysctlError(sysctl(mib, 2, tempStr, &tempStrSize, NULL, 0)); PsychSetStructArrayStringElement("machine", 0, tempStr, hwStruct); mib[1]=HW_MODEL; tempStrSize=sizeof(tempStr); ReportSysctlError(sysctl(mib, 2, tempStr, &tempStrSize, NULL, 0)); PsychSetStructArrayStringElement("model", 0, tempStr, hwStruct); mib[1]=HW_NCPU; tempIntSize=sizeof(tempInt); ReportSysctlError(sysctl(mib, 2, &tempInt, &tempIntSize, NULL, 0)); PsychSetStructArrayDoubleElement("ncpu", 0, (double)tempInt, hwStruct); mib[1]=HW_MEMSIZE; long long tempLongInt; tempULongIntSize=sizeof(tempLongInt); ReportSysctlError(sysctl(mib, 2, &tempLongInt, &tempULongIntSize, NULL, 0)); PsychSetStructArrayDoubleElement("physmem", 0, (double)tempLongInt, hwStruct); mib[1]=HW_USERMEM; tempULongIntSize=sizeof(tempULongInt); ReportSysctlError(sysctl(mib, 2, &tempULongInt, &tempULongIntSize, NULL, 0)); PsychSetStructArrayDoubleElement("usermem", 0, (double)tempULongInt, hwStruct); mib[1]=HW_BUS_FREQ; tempULongIntSize=sizeof(tempULongInt); ReportSysctlError(sysctl(mib, 2, &tempULongInt, &tempULongIntSize, NULL, 0)); PsychSetStructArrayDoubleElement("busfreq", 0, (double)tempULongInt, hwStruct); mib[1]=HW_CPU_FREQ; tempULongIntSize=sizeof(tempULongInt); ReportSysctlError(sysctl(mib, 2, &tempULongInt, &tempULongIntSize, NULL, 0)); PsychSetStructArrayDoubleElement("cpufreq", 0, (double)tempULongInt, hwStruct); PsychSetStructArrayStructElement("hw",0, hwStruct, majorStruct); //fill in the process user, console user and machine name in the root struct. tempCFStringRef= CSCopyMachineName(); if (tempCFStringRef) { stringLengthChars=(int) CFStringGetMaximumSizeForEncoding(CFStringGetLength(tempCFStringRef), kCFStringEncodingUTF8); tempStrPtr=malloc(sizeof(char) * (stringLengthChars+1)); stringSuccess= CFStringGetCString(tempCFStringRef, tempStrPtr, stringLengthChars+1, kCFStringEncodingUTF8); if(stringSuccess) { PsychSetStructArrayStringElement("machineName", 0, tempStrPtr, majorStruct); } else { PsychSetStructArrayStringElement("machineName", 0, "UNKNOWN! QUERY FAILED DUE TO EMPTY OR PROBLEMATIC NAME.", majorStruct); } free(tempStrPtr); CFRelease(tempCFStringRef); } else { PsychSetStructArrayStringElement("machineName", 0, "UNKNOWN! QUERY FAILED DUE TO EMPTY OR PROBLEMATIC NAME.", majorStruct); } tempCFStringRef= CSCopyUserName(TRUE); //use short name if (tempCFStringRef) { stringLengthChars=(int) CFStringGetMaximumSizeForEncoding(CFStringGetLength(tempCFStringRef), kCFStringEncodingUTF8); tempStrPtr=malloc(sizeof(char) * (stringLengthChars+1)); stringSuccess= CFStringGetCString(tempCFStringRef, tempStrPtr, stringLengthChars+1, kCFStringEncodingUTF8); if(stringSuccess) { PsychSetStructArrayStringElement("processUserShortName", 0, tempStrPtr, majorStruct); } else { PsychSetStructArrayStringElement("processUserShortName", 0, "UNKNOWN! QUERY FAILED DUE TO EMPTY OR PROBLEMATIC NAME.", majorStruct); } free(tempStrPtr); CFRelease(tempCFStringRef); } else { PsychSetStructArrayStringElement("processUserShortName", 0, "UNKNOWN! QUERY FAILED DUE TO EMPTY OR PROBLEMATIC NAME.", majorStruct); } tempCFStringRef= CSCopyUserName(FALSE); //use long name if (tempCFStringRef) { stringLengthChars=(int) CFStringGetMaximumSizeForEncoding(CFStringGetLength(tempCFStringRef), kCFStringEncodingUTF8); tempStrPtr=malloc(sizeof(char) * (stringLengthChars+1)); stringSuccess= CFStringGetCString(tempCFStringRef, tempStrPtr, stringLengthChars+1, kCFStringEncodingUTF8); if(stringSuccess) { PsychSetStructArrayStringElement("processUserLongName", 0, tempStrPtr, majorStruct); } else { PsychSetStructArrayStringElement("processUserLongName", 0, "UNKNOWN! QUERY FAILED DUE TO EMPTY OR PROBLEMATIC NAME.", majorStruct); } free(tempStrPtr); CFRelease(tempCFStringRef); } else { PsychSetStructArrayStringElement("processUserLongName", 0, "UNKNOWN! QUERY FAILED DUE TO EMPTY OR PROBLEMATIC NAME.", majorStruct); } tempCFStringRef= SCDynamicStoreCopyConsoleUser(NULL, NULL, NULL); if (tempCFStringRef) { stringLengthChars=(int) CFStringGetMaximumSizeForEncoding(CFStringGetLength(tempCFStringRef), kCFStringEncodingUTF8); tempStrPtr=malloc(sizeof(char) * (stringLengthChars+1)); stringSuccess= CFStringGetCString(tempCFStringRef, tempStrPtr, stringLengthChars+1, kCFStringEncodingUTF8); if(stringSuccess) { PsychSetStructArrayStringElement("consoleUserName", 0, tempStrPtr, majorStruct); } else { PsychSetStructArrayStringElement("consoleUserName", 0, "UNKNOWN! QUERY FAILED DUE TO EMPTY OR PROBLEMATIC NAME.", majorStruct); } free(tempStrPtr); CFRelease(tempCFStringRef); } else { PsychSetStructArrayStringElement("consoleUserName", 0, "UNKNOWN! QUERY FAILED DUE TO EMPTY OR PROBLEMATIC NAME.", majorStruct); } tempCFStringRef= SCDynamicStoreCopyLocalHostName(NULL); if (tempCFStringRef) { stringLengthChars=(int) CFStringGetMaximumSizeForEncoding(CFStringGetLength(tempCFStringRef), kCFStringEncodingUTF8); tempStrPtr=malloc(sizeof(char) * (stringLengthChars+1)); stringSuccess= CFStringGetCString(tempCFStringRef, tempStrPtr, stringLengthChars+1, kCFStringEncodingUTF8); if(stringSuccess) { PsychSetStructArrayStringElement("localHostName", 0, tempStrPtr, majorStruct); } else { PsychSetStructArrayStringElement("localHostName", 0, "UNKNOWN! QUERY FAILED DUE TO EMPTY OR PROBLEMATIC NAME.", majorStruct); } free(tempStrPtr); CFRelease(tempCFStringRef); } else { PsychSetStructArrayStringElement("localHostName", 0, "UNKNOWN! QUERY FAILED DUE TO EMPTY OR PROBLEMATIC NAME.", majorStruct); } tempCFStringRef= SCDynamicStoreCopyLocation(NULL); if (tempCFStringRef) { stringLengthChars=(int) CFStringGetMaximumSizeForEncoding(CFStringGetLength(tempCFStringRef), kCFStringEncodingUTF8); tempStrPtr=malloc(sizeof(char) * (stringLengthChars+1)); stringSuccess= CFStringGetCString(tempCFStringRef, tempStrPtr, stringLengthChars+1, kCFStringEncodingUTF8); if(stringSuccess) { PsychSetStructArrayStringElement("location", 0, tempStrPtr, majorStruct); } else { PsychSetStructArrayStringElement("location", 0, "UNKNOWN! QUERY FAILED DUE TO EMPTY OR PROBLEMATIC NAME.", majorStruct); } free(tempStrPtr); CFRelease(tempCFStringRef); } else { PsychSetStructArrayStringElement("location", 0, "UNKNOWN! QUERY FAILED DUE TO EMPTY OR PROBLEMATIC NAME.", majorStruct); } //Add the ethernet MAC address of the primary ethernet interface to the stuct. This can serve as a unique identifier for the computer. ethernetMACStrSizeBytes=GetPrimaryEthernetAddressStringLengthBytes(TRUE)+1; ethernetMACStr=(char*) malloc(sizeof(char) * ethernetMACStrSizeBytes); GetPrimaryEthernetAddressString(ethernetMACStr, TRUE, TRUE); PsychSetStructArrayStringElement("MACAddress", 0, ethernetMACStr, majorStruct); free(ethernetMACStr); //Add the system version string: Gestalt(gestaltSystemVersionMajor, &osMajor); Gestalt(gestaltSystemVersionMinor, &osMinor); Gestalt(gestaltSystemVersionBugFix, &osBugfix); sprintf(systemVersionStr, "Mac OS %i.%i.%i", osMajor, osMinor, osBugfix); //embed it in the return struct PsychSetStructArrayStringElement("system", 0, systemVersionStr, majorStruct); /* OLD DEAD Implementation, left for now as a reference... //Add the system version string: gestaltError=Gestalt(gestaltSystemVersion, &gestaltResult); //The result is a four-digit value stored in BCD in the lower 16-bits of the result. There are implicit decimal // points between the last three digis. For example Mac OS 10.3.6 is: // // 0000 0000 0000 0000 0001 0000 0011 0110 // 1 0 3 6 // 1 0. 3. 6 strIndex=0; //4th digit. bcdDigit=gestaltResult & 15; gestaltResult= gestaltResult>>4; strIndex=strIndex+sprintf(systemVersionStr+strIndex, "%i", bcdDigit); //decimal point strIndex=strIndex+sprintf(systemVersionStr+strIndex, "%s", "."); //3rd digit bcdDigit=gestaltResult & 15; gestaltResult= gestaltResult>>4; strIndex=strIndex+sprintf(systemVersionStr+strIndex, "%i", bcdDigit); //decimal point strIndex=strIndex+sprintf(systemVersionStr+strIndex, "%s", "."); //second digit //2nd digit. bcdDigit=gestaltResult & 15; gestaltResult= gestaltResult>>4; strIndex=strIndex+sprintf(systemVersionStr+strIndex, "%i", bcdDigit); //1st digit bcdDigit=gestaltResult & 15; gestaltResult= gestaltResult>>4; strIndex=strIndex+sprintf(systemVersionStr+strIndex, "%i", bcdDigit); //preface with "Mac OS " strIndex=strIndex+sprintf(systemVersionStr+strIndex, "%s", " SO caM"); //reverse to make it forward lengthSystemVersionString=strlen(systemVersionStr); for(i=0;i<lengthSystemVersionString;i++){ systemVersionStrForward[lengthSystemVersionString-1-i]=systemVersionStr[i]; } systemVersionStrForward[lengthSystemVersionString]='\0'; //embed it in the return struct PsychSetStructArrayStringElement("system", 0, systemVersionStrForward, majorStruct); */ return(PsychError_none); }
PsychError SCREENComputer(void) { const char *majorStructFieldNames[]={"macintosh", "windows", "osx" ,"linux", "kern", "hw", "processUserLongName", "processUserShortName", "consoleUserName", "machineName", "localHostName", "location", "MACAddress", "system", "gstreamer", "supported" }; const char *kernStructFieldNames[]={"ostype", "osrelease", "osrevision", "version","hostname"}; const char *hwStructFieldNames[]={"machine", "model", "ncpu", "physmem", "usermem", "busfreq", "cpufreq"}; int numMajorStructDimensions=-1, numKernStructDimensions=-1, numHwStructDimensions=-1; int numMajorStructFieldNames=16, numKernStructFieldNames=5, numHwStructFieldNames=7; PsychGenericScriptType *kernStruct, *hwStruct, *majorStruct; //char tempStr[CTL_MAXNAME]; //this seems like a bug in Darwin, CTL_MAXNAME is shorter than the longest name. char tempStr[256], *ethernetMACStr; size_t tempIntSize, tempStrSize, tempULongIntSize; int mib[2]; int tempInt; psych_uint64 tempULongInt; char *tempStrPtr; CFStringRef tempCFStringRef; psych_bool stringSuccess; int stringLengthChars, ethernetMACStrSizeBytes; long gestaltResult; OSErr gestaltError; int i,strIndex, bcdDigit, lengthSystemVersionString; int osMajor, osMinor, osBugfix; char systemVersionStr[256]; //all subfunctions should have these two lines PsychPushHelp(useString, synopsisString, seeAlsoString); if(PsychIsGiveHelp()){PsychGiveHelp();return(PsychError_none);}; PsychErrorExit(PsychCapNumOutputArgs(1)); PsychErrorExit(PsychCapNumInputArgs(0)); //fill the major struct PsychAllocOutStructArray(1, FALSE, numMajorStructDimensions, numMajorStructFieldNames, majorStructFieldNames, &majorStruct); PsychSetStructArrayDoubleElement("macintosh", 0, 0, majorStruct); PsychSetStructArrayDoubleElement("windows", 0, 0, majorStruct); PsychSetStructArrayDoubleElement("linux", 0, 0, majorStruct); PsychSetStructArrayDoubleElement("osx", 0, 1, majorStruct); // Official support status: PsychSetStructArrayStringElement("supported", 0, (char*) PsychSupportStatus(), majorStruct); // GStreamer availability and rough version: #if defined(PTB_USE_GSTREAMER) #if GST_CHECK_VERSION(1,0,0) PsychSetStructArrayDoubleElement("gstreamer", 0, 1 * 10000 + 0 * 100 + 0, majorStruct); #else PsychSetStructArrayDoubleElement("gstreamer", 0, 0 * 10000 + 10 * 100 + 0, majorStruct); #endif #else PsychSetStructArrayDoubleElement("gstreamer", 0, 0, majorStruct); #endif //fill the kern struct and implant it within the major struct PsychAllocOutStructArray(-1, FALSE, numKernStructDimensions, numKernStructFieldNames, kernStructFieldNames, &kernStruct); mib[0]=CTL_KERN; mib[1]=KERN_OSTYPE; tempStrSize=sizeof(tempStr); ReportSysctlError(sysctl(mib, 2, tempStr, &tempStrSize, NULL, 0)); PsychSetStructArrayStringElement("ostype", 0, tempStr, kernStruct); mib[1]=KERN_OSRELEASE; tempStrSize=sizeof(tempStr); ReportSysctlError(sysctl(mib, 2, tempStr, &tempStrSize, NULL, 0)); PsychSetStructArrayStringElement("osrelease", 0, tempStr, kernStruct); mib[1]=KERN_OSREV; tempIntSize=sizeof(tempInt); ReportSysctlError(sysctl(mib, 2, &tempInt, &tempIntSize, NULL, 0)); PsychSetStructArrayDoubleElement("osrevision", 0, (double)tempInt, kernStruct); mib[1]=KERN_VERSION; tempStrSize=sizeof(tempStr); ReportSysctlError(sysctl(mib, 2, tempStr, &tempStrSize, NULL, 0)); PsychSetStructArrayStringElement("version", 0, tempStr, kernStruct); mib[1]=KERN_HOSTNAME; tempStrSize=sizeof(tempStr); ReportSysctlError(sysctl(mib, 2, tempStr, &tempStrSize, NULL, 0)); PsychSetStructArrayStringElement("hostname", 0, tempStr, kernStruct); PsychSetStructArrayStructElement("kern",0, kernStruct, majorStruct); //fill the hw struct and implant it within the major struct PsychAllocOutStructArray(-1, FALSE, numHwStructDimensions, numHwStructFieldNames, hwStructFieldNames, &hwStruct); mib[0]=CTL_HW; mib[1]=HW_MACHINE; tempStrSize=sizeof(tempStr); ReportSysctlError(sysctl(mib, 2, tempStr, &tempStrSize, NULL, 0)); PsychSetStructArrayStringElement("machine", 0, tempStr, hwStruct); mib[1]=HW_MODEL; tempStrSize=sizeof(tempStr); ReportSysctlError(sysctl(mib, 2, tempStr, &tempStrSize, NULL, 0)); PsychSetStructArrayStringElement("model", 0, tempStr, hwStruct); mib[1]=HW_NCPU; tempIntSize=sizeof(tempInt); ReportSysctlError(sysctl(mib, 2, &tempInt, &tempIntSize, NULL, 0)); PsychSetStructArrayDoubleElement("ncpu", 0, (double)tempInt, hwStruct); mib[1]=HW_MEMSIZE; tempULongIntSize=sizeof(tempULongInt); tempULongInt = 0; ReportSysctlError(sysctl(mib, 2, &tempULongInt, &tempULongIntSize, NULL, 0)); PsychSetStructArrayDoubleElement("physmem", 0, (double)tempULongInt, hwStruct); mib[1]=HW_USERMEM; tempULongIntSize=sizeof(tempULongInt); tempULongInt = 0; ReportSysctlError(sysctlbyname("hw.usermem", &tempULongInt, &tempULongIntSize, NULL, 0)); PsychSetStructArrayDoubleElement("usermem", 0, (double)tempULongInt, hwStruct); mib[1]=HW_BUS_FREQ; tempULongIntSize=sizeof(tempULongInt); tempULongInt = 0; ReportSysctlError(sysctlbyname("hw.busfrequency", &tempULongInt, &tempULongIntSize, NULL, 0)); PsychSetStructArrayDoubleElement("busfreq", 0, (double)tempULongInt, hwStruct); mib[1]=HW_CPU_FREQ; tempULongIntSize=sizeof(tempULongInt); tempULongInt = 0; ReportSysctlError(sysctlbyname("hw.cpufrequency", &tempULongInt, &tempULongIntSize, NULL, 0)); PsychSetStructArrayDoubleElement("cpufreq", 0, (double)tempULongInt, hwStruct); PsychSetStructArrayStructElement("hw",0, hwStruct, majorStruct); //fill in the process user, console user and machine name in the root struct. tempCFStringRef = SCDynamicStoreCopyComputerName(NULL, NULL); if (tempCFStringRef) { stringLengthChars=(int) CFStringGetMaximumSizeForEncoding(CFStringGetLength(tempCFStringRef), kCFStringEncodingASCII); tempStrPtr=malloc(sizeof(char) * (stringLengthChars+1)); stringSuccess= CFStringGetCString(tempCFStringRef, tempStrPtr, stringLengthChars+1, kCFStringEncodingASCII); if(stringSuccess) { PsychSetStructArrayStringElement("machineName", 0, tempStrPtr, majorStruct); } else { PsychSetStructArrayStringElement("machineName", 0, "UNKNOWN! QUERY FAILED DUE TO EMPTY OR PROBLEMATIC NAME.", majorStruct); } free(tempStrPtr); CFRelease(tempCFStringRef); } else { PsychSetStructArrayStringElement("machineName", 0, "UNKNOWN! QUERY FAILED DUE TO EMPTY OR PROBLEMATIC NAME.", majorStruct); } struct passwd* thisUser = getpwuid(getuid()); if (thisUser) { PsychSetStructArrayStringElement("processUserShortName", 0, thisUser->pw_name, majorStruct); } else { PsychSetStructArrayStringElement("processUserShortName", 0, "UNKNOWN! QUERY FAILED DUE TO EMPTY OR PROBLEMATIC NAME.", majorStruct); } PsychSetStructArrayStringElement("processUserLongName", 0, PsychCocoaGetFullUsername(), majorStruct); tempCFStringRef= SCDynamicStoreCopyConsoleUser(NULL, NULL, NULL); if (tempCFStringRef) { stringLengthChars=(int) CFStringGetMaximumSizeForEncoding(CFStringGetLength(tempCFStringRef), kCFStringEncodingASCII); tempStrPtr=malloc(sizeof(char) * (stringLengthChars+1)); stringSuccess= CFStringGetCString(tempCFStringRef, tempStrPtr, stringLengthChars+1, kCFStringEncodingASCII); if(stringSuccess) { PsychSetStructArrayStringElement("consoleUserName", 0, tempStrPtr, majorStruct); } else { PsychSetStructArrayStringElement("consoleUserName", 0, "UNKNOWN! QUERY FAILED DUE TO EMPTY OR PROBLEMATIC NAME.", majorStruct); } free(tempStrPtr); CFRelease(tempCFStringRef); } else { PsychSetStructArrayStringElement("consoleUserName", 0, "UNKNOWN! QUERY FAILED DUE TO EMPTY OR PROBLEMATIC NAME.", majorStruct); } tempCFStringRef= SCDynamicStoreCopyLocalHostName(NULL); if (tempCFStringRef) { stringLengthChars=(int) CFStringGetMaximumSizeForEncoding(CFStringGetLength(tempCFStringRef), kCFStringEncodingASCII); tempStrPtr=malloc(sizeof(char) * (stringLengthChars+1)); stringSuccess= CFStringGetCString(tempCFStringRef, tempStrPtr, stringLengthChars+1, kCFStringEncodingASCII); if(stringSuccess) { PsychSetStructArrayStringElement("localHostName", 0, tempStrPtr, majorStruct); } else { PsychSetStructArrayStringElement("localHostName", 0, "UNKNOWN! QUERY FAILED DUE TO EMPTY OR PROBLEMATIC NAME.", majorStruct); } free(tempStrPtr); CFRelease(tempCFStringRef); } else { PsychSetStructArrayStringElement("localHostName", 0, "UNKNOWN! QUERY FAILED DUE TO EMPTY OR PROBLEMATIC NAME.", majorStruct); } tempCFStringRef= SCDynamicStoreCopyLocation(NULL); if (tempCFStringRef) { stringLengthChars=(int) CFStringGetMaximumSizeForEncoding(CFStringGetLength(tempCFStringRef), kCFStringEncodingASCII); tempStrPtr=malloc(sizeof(char) * (stringLengthChars+1)); stringSuccess= CFStringGetCString(tempCFStringRef, tempStrPtr, stringLengthChars+1, kCFStringEncodingASCII); if(stringSuccess) { PsychSetStructArrayStringElement("location", 0, tempStrPtr, majorStruct); } else { PsychSetStructArrayStringElement("location", 0, "UNKNOWN! QUERY FAILED DUE TO EMPTY OR PROBLEMATIC NAME.", majorStruct); } free(tempStrPtr); CFRelease(tempCFStringRef); } else { PsychSetStructArrayStringElement("location", 0, "UNKNOWN! QUERY FAILED DUE TO EMPTY OR PROBLEMATIC NAME.", majorStruct); } //Add the ethernet MAC address of the primary ethernet interface to the stuct. This can serve as a unique identifier for the computer. ethernetMACStrSizeBytes=GetPrimaryEthernetAddressStringLengthBytes(TRUE)+1; ethernetMACStr=(char*) malloc(sizeof(char) * ethernetMACStrSizeBytes); GetPrimaryEthernetAddressString(ethernetMACStr, TRUE, TRUE); PsychSetStructArrayStringElement("MACAddress", 0, ethernetMACStr, majorStruct); free(ethernetMACStr); //Add the system version string: PsychCocoaGetOSXVersion(&osMajor, &osMinor, &osBugfix); sprintf(systemVersionStr, "Mac OS %i.%i.%i", osMajor, osMinor, osBugfix); //embed it in the return struct PsychSetStructArrayStringElement("system", 0, systemVersionStr, majorStruct); return(PsychError_none); }