/* setrsrc.c * =========================================================================== * * PUBLIC DOMAIN NOTICE * National Center for Biotechnology Information (NCBI) * * This software/database is a "United States Government Work" under the * terms of the United States Copyright Act. It was written as part of * the author's official duties as a United States Government employee and * thus cannot be copyrighted. This software/database is freely available * to the public for use. The National Library of Medicine and the U.S. * Government do not place any restriction on its use or reproduction. * We would, however, appreciate having the NCBI and the author cited in * any work or product based on this material * * Although all reasonable efforts have been taken to ensure the accuracy * and reliability of the software and data, the NLM and the U.S. * Government do not and cannot warrant the performance or results that * may be obtained by using this software or data. The NLM and the U.S. * Government disclaim all warranties, express or implied, including * warranties of performance, merchantability or fitness for any particular * purpose. * * =========================================================================== * * File Name: setrsrc.c * * Author: Jonathan Kans * * Version Creation Date: 10/4/02 * * $Revision: 1.6 $ * * File Description: * * Sets type and creator of files to get around a bug that prevents * CodeWarrior from seeing and loading them if they were checked out * directly on Mac OS X - later bug fixed but still needs to be set * in order to debug file under CodeWarrior * * Modifications: * -------------------------------------------------------------------------- * Date Name Description of modification * ------- ---------- ----------------------------------------------------- * * * ========================================================================== */ #include #include #include #include #define DIRDELIMCHAR ':' #define DIRDELIMSTRN ":" static void MyC2PStr (char *ioStr) { size_t len = strlen (ioStr); if (len > 255) { len = 255; } memmove (ioStr + 1, ioStr, len); ioStr [0] = len; } static void MyP2CStr (StringPtr ioStr) { Byte len = ioStr [0]; memmove (ioStr, ioStr + 1, len); ioStr [len] = '\0'; } static char * MyStrMove (char * to, char * from) { while (*from != '\0') { *to = *from; to++; from++; } *to = '\0'; return to; } static char * MyFileBuildPath (char * root, char * sub_path, char * filename) { char * tmp; unsigned char dir_start = 0; if (root == 0) return 0; tmp = root; if (*tmp != '\0') { dir_start = 1; while (*tmp != '\0') { tmp++; } if ((*(tmp - 1) != DIRDELIMCHAR) && (dir_start)) { *tmp = DIRDELIMCHAR; tmp++; *tmp = '\0'; } } if (sub_path != 0) { if ((dir_start) && (*sub_path == DIRDELIMCHAR)) { sub_path++; } tmp = MyStrMove (tmp, sub_path); if (*(tmp-1) != DIRDELIMCHAR) { *tmp = DIRDELIMCHAR; tmp++; *tmp = '\0'; } } if (filename != 0) { MyStrMove (tmp, filename); } return root; } static char * MyStrSave (const char * from) { size_t len; char * to; len = strlen (from); to = malloc (len + 1); if (to != 0) { memcpy (to, from, len + 1); } return to; } typedef struct valnde { unsigned char choice; void * ptrvalue; struct valnde * next; } ValNde, * ValNdePtr; static ValNdePtr ValNdeNew (ValNdePtr vnp) { ValNdePtr newnode; newnode = (ValNdePtr) malloc (sizeof (ValNde)); if (newnode == 0) { return 0; } newnode->choice = 0; newnode->ptrvalue = 0; newnode->next = 0; if (vnp != 0) { while (vnp->next != NULL) { vnp = vnp->next; } vnp->next = newnode; } return newnode; } static ValNdePtr ValNdeAdd (ValNdePtr * head) { ValNdePtr newnode; if (head != 0) { newnode = ValNdeNew (*head); if (*head == 0) { *head = newnode; } } else { newnode = ValNdeNew (0); } return newnode; } static ValNdePtr ValNdeCopyStr (ValNdePtr * head, int choice, char * str) { ValNdePtr newnode; if (str == 0) return 0; newnode = ValNdeAdd (head); if (newnode != NULL) { newnode->choice = (unsigned char) choice; newnode->ptrvalue = MyStrSave (str); } return newnode; } static ValNdePtr ValNdeFreeData (ValNdePtr vnp) { ValNdePtr next; while (vnp != 0) { free (vnp->ptrvalue); next = vnp->next; free (vnp); vnp = next; } return 0; } static ValNdePtr MyDirCatalog (char * pathname) { long dirID; OSErr err; short index; unsigned short num; char path [256]; CInfoPBRec pbc; HParamBlockRec pbh; short vRefNum; ValNdePtr vnp = 0; if (pathname != NULL && pathname [0] != '\0') { strncpy (path, pathname, sizeof (path)); MyC2PStr ((char *) path); memset ((void *) (&pbh), 0, sizeof (HParamBlockRec)); pbh.volumeParam.ioNamePtr = (StringPtr) path; pbh.volumeParam.ioVolIndex = -1; err = PBHGetVInfo (&pbh, FALSE); if (err != noErr) return NULL; vRefNum = pbh.volumeParam.ioVRefNum; strncpy (path, pathname, sizeof (path)); MyC2PStr ((char *) path); memset ((void *) (&pbc), 0, sizeof (CInfoPBRec)); pbc.dirInfo.ioNamePtr = (StringPtr) path; pbc.dirInfo.ioVRefNum = vRefNum; err = PBGetCatInfo (&pbc, FALSE); if (err != noErr) return NULL; if (pbc.dirInfo.ioFlAttrib & 16) { num = pbc.dirInfo.ioDrNmFls; dirID = pbc.dirInfo.ioDrDirID; for (index = 1; index <= num; index++) { memset ((void *) (&pbc), 0, sizeof (CInfoPBRec)); pbc.dirInfo.ioNamePtr = (StringPtr) path; pbc.dirInfo.ioVRefNum = vRefNum; pbc.dirInfo.ioFDirIndex = index; pbc.dirInfo.ioDrDirID = dirID; pbc.dirInfo.ioACUser = 0; err = PBGetCatInfo (&pbc, FALSE); if (err == noErr) { MyP2CStr ((StringPtr) path); if (pbc.dirInfo.ioFlAttrib & 16) { ValNdeCopyStr (&vnp, 1, path); } else { ValNdeCopyStr (&vnp, 0, path); } } } } } return vnp; } static int IsSuffix (char * filename, char * suffix) { size_t flen; size_t slen; flen = strlen (filename); slen = strlen (suffix); if (slen >= flen) return false; if (strcmp (filename + flen - slen, suffix) == 0) return true; return false; } static void SetTypeCreator (char * directory, char * filename, OSType creator, OSType type) { OSErr fError; FInfo fInfo; char path [256]; strncpy (path, directory, sizeof (path)); MyFileBuildPath (path, NULL, filename); MyC2PStr ((char *) path); fError = HGetFInfo (0, 0, (StringPtr) path, &fInfo); if (fError == noErr) { if (fInfo.fdCreator == creator && fInfo.fdType == type) return; fInfo.fdCreator = creator; fInfo.fdType = type; fError = HSetFInfo (0, 0, (StringPtr) path, &fInfo); } } static void RecurseDir (char * directory, char * subpath) { ValNdePtr head; char path [256]; char * str; ValNdePtr vnp; strncpy (path, directory, sizeof (path)); MyFileBuildPath (path, subpath, NULL); head = MyDirCatalog (path); for (vnp = head; vnp != NULL; vnp = vnp->next) { if (vnp->choice == 0) { str = (char *) vnp->ptrvalue; if (str == 0 || *str == '\0') continue; if (IsSuffix (str, ".h") || IsSuffix (str, ".hpp") || IsSuffix (str, ".c") || IsSuffix (str, ".cpp") || IsSuffix (str, ".r")) { SetTypeCreator (path, str, 'ttxt', 'TEXT'); } else if (IsSuffix (str, ".met")) { if (strstr (path, "ncbi:make:") || strstr (path, "compilers:mac_prj:")) { SetTypeCreator (path, str, 'ToyS', 'TEXT'); } } else if (IsSuffix (str, ".mcp")) { if (strstr (path, "ncbi:link:macmet:") || strstr (path, "compilers:mac_prj:")) { SetTypeCreator (path, str, 'CWIE', 'MMPr'); } } else if (IsSuffix (str, ".plc")) { if (strstr (path, "ncbi:link:macmet:") || strstr (path, "compilers:mac_prj:")) { SetTypeCreator (path, str, 'ttxt', 'TEXT'); } } /* set type/creator */ } else if (vnp->choice == 1) { str = (char *) vnp->ptrvalue; RecurseDir (path, str); } } ValNdeFreeData (head); } static void MyProgramPath (char * buf, size_t maxsize) { FSSpec apFileSpec; CInfoPBRec block; short nErr; char path [256]; ProcessInfoRec pirec; ProcessSerialNumber psn; char temp [256]; GetCurrentProcess (&psn); pirec.processInfoLength = sizeof (ProcessInfoRec); pirec.processName = NULL; pirec.processAppSpec = &apFileSpec; GetProcessInformation (&psn, &pirec); MyP2CStr ((StringPtr) apFileSpec.name); if (buf != NULL && maxsize > 0) { *buf = '\0'; memset (&block, 0, sizeof (CInfoPBRec)); strncpy (path, (char *) apFileSpec.name, sizeof (path)); block.dirInfo.ioNamePtr = (StringPtr) path; block.dirInfo.ioDrParID = apFileSpec.parID; do { strcpy (temp, path); block.dirInfo.ioVRefNum = apFileSpec.vRefNum; block.dirInfo.ioFDirIndex = -1; block.dirInfo.ioDrDirID = block.dirInfo.ioDrParID; nErr = PBGetCatInfo (&block, FALSE); if (nErr != noErr) break; MyP2CStr ((StringPtr) path); strcat (path, DIRDELIMSTRN); strcat (path, temp); } while (block.dirInfo.ioDrDirID != fsRtDirID); strncpy (buf, path, maxsize); } } extern int main (void) { ValNdePtr head; char path [256]; char * ptr; char * str; ValNdePtr vnp; MyProgramPath (path, sizeof (path)); /* remove program name to get path to program */ ptr = strrchr (path, DIRDELIMCHAR); if (ptr != 0) { *ptr = '\0'; } /* back out to application bundle directory */ ptr = strstr (path, ":Contents:MacOS"); if (ptr != 0) { *ptr = '\0'; /* and then to parent directory of application */ ptr = strrchr (path, DIRDELIMCHAR); if (ptr != 0) { *ptr = '\0'; } } /* process files within parent directory of program*/ RecurseDir ((char *) path, 0); /* look for executable in ncbi:link:macmet directory */ ptr = strstr (path, ":ncbi:link:macmet"); if (ptr != 0) { *ptr = '\0'; } else { /* otherwise look for ncbi and ncbi_cxx directories as siblings of parent */ ptr = strrchr (path, DIRDELIMCHAR); if (ptr != 0) { *ptr = '\0'; } } head = MyDirCatalog (path); for (vnp = head; vnp != NULL; vnp = vnp->next) { if (vnp->choice == 1) { str = (char *) vnp->ptrvalue; if (strcmp (str, "ncbi") == 0 || strcmp (str, "ncbi_cxx") == 0) { RecurseDir ((char *) path, str); } } } ValNdeFreeData (head); return 0; }