/** * Open a sqlite3 database * * @param filename DB filename * @param errmsg If open db failed, a error information will be stored in * errmsg if you pass this parameterment. * * @return A new SwsDB object, or NULL if something error happens */ SwsDB *sws_open_db(const char *filename, char **errmsg) { int ret; sqlite3 *db = NULL; if (!filename) { if (errmsg) { SET_ERRMSG(errmsg, "Filename is null"); } return NULL; } ret = sqlite3_open(filename, &db); if (ret != SQLITE_OK) { /** * NB: should close db though we open this db failed, * or else a memory will leak */ sqlite3_close(db); char msg[128]; snprintf(msg, sizeof(msg), "Open file: %s failed, errcode is %d", filename, ret); SET_ERRMSG(errmsg, msg); return NULL; } return db; }
/** * Excute a SQL directly, dont need to open DB and close DB * * @param filename * @param sql * @param errmsg * * @return 0 if excute successfully, else return -1. */ int sws_exec_sql_directly(const char *filename, const char *sql, char **errmsg) { int ret; SwsDB *db = NULL; if (!filename || !sql) { SET_ERRMSG(errmsg, "Some parameterment is null"); goto failed; } db = sws_open_db(filename, errmsg); if (!db) { goto failed; } ret = sws_exec_sql(db, sql, errmsg); if (ret) { goto failed; } sws_close_db(db, NULL); return 0; failed: if (db) sws_close_db(db, NULL); return -1; }
static BOOL MyDoConnect (NetRecord *pmNetRecord, char *pmOpenStr, int *pmPort, char *pmNetAddr) { char *myPtr = strchr (pmOpenStr, ':'); int myPort; NET_ADDR myAddr; if (myPtr == NULL) { // Missing address SET_ERRNO (E_NET_MISSING_ADDRESS); return FALSE; } *myPtr = 0; myPtr++; myPort = atol (pmOpenStr); if (myPort == 0) { SET_ERRNO (E_NET_INVALID_PORT); return FALSE; } // Check for the ":b" at the end signalling the stream is binary // (i.e. no line end conversions to be done.) if (strchr (myPtr, ':') != NULL) { char *myBinaryPtr; myBinaryPtr = strchr (myPtr, ':'); *myBinaryPtr++ = 0; if (strcmp (myBinaryPtr, "b") == 0) { pmNetRecord -> binary = TRUE; } else { SET_ERRMSG (E_NET_BAD_ADDRESS, "No colons allowed in network address"); return FALSE; } } myAddr = MDIONet_GetNetworkAddrByString (myPtr); if (myAddr == NULL) { return FALSE; } // Set debugging information *pmPort = myPort; if (pmNetAddr != NULL) { strcpy (pmNetAddr, myPtr); } return MDIONet_Connect (pmNetRecord -> socket, pmNetRecord -> sockAddr, myPort, myAddr); } // MyDoConnect
void MIOFile_Rename (OOTstring pmPathName, OOTstring pmNewPathName) { char myPathName [1024]; char myNewPathName [1024]; // Convert to full path name if (!MIOFile_ConvertPath (pmPathName, NULL, myPathName, NO_TRAILING_SLASH)) { // if MIOFile_ConvertPath returned false, then the error message was // set to indicate why. return; } // Check that file to be copied exists if (!MDIOFile_Exists (myPathName, FILE_OR_DIR)) { // if MDIOFile_Exists returned false, then the error message was set // to indicate why. return; } // Convert to full path name if (!MIOFile_ConvertPath (pmNewPathName, NULL, myNewPathName, NO_TRAILING_SLASH)) { // if MIOFile_ConvertPath returned false, then the error message was // set to indicate why. return; } if (MDIOFile_Exists (myNewPathName, FILE_ONLY)) { SET_ERRMSG (E_FSYS_FILE_EXISTS, "A data file '%s' already exists", myNewPathName); } else if (MIODir_Exists (myNewPathName)) { SET_ERRMSG (E_FSYS_FILE_EXISTS, "A directory '%s' already exists", myNewPathName); } else { // MIODir_Exists may have set the error code. SET_ERRNO (E_NO_ERROR); MDIOFile_Rename (myPathName, myNewPathName); } } // MIOFile_Rename
/** * Close a sqlite3 database * * @param db * @param errmsg */ void sws_close_db(SwsDB *db, char **errmsg) { int ret; if (!db) { SET_ERRMSG(errmsg, "Filename is null"); return ; } ret = sqlite3_close(db); if (ret != SQLITE_OK) { char msg[128]; snprintf(msg, sizeof(msg), "Close DB failed: %s", sqlite3_errmsg(db)); SET_ERRMSG(errmsg, msg); return ; } }
/** * Start a query * * @param db * @param sql * @param stmt * @param errmsg * * @return 0 if start successfully, else return -1 and stored error * information in errmsg if errmsg is not null. */ int sws_query_start(SwsDB* db, const char* sql, SwsStmt** stmt, char** errmsg) { int ret; if (!db || !sql || !stmt) { SET_ERRMSG(errmsg, "Some parameterment is null"); return -1; } ret = sqlite3_prepare_v2(db, sql, -1, (sqlite3_stmt**)stmt, 0); if (ret != SQLITE_OK) { char msg[512]; snprintf(msg, sizeof(msg), "\"%s\" failed: %s", sql, sqlite3_errmsg(db)); SET_ERRMSG(errmsg, msg); return -1; } return 0; }
BOOL MDIOFile_GetDefaultPathForWindowsVolume (char pmDriveLetter, char *pmPath) { char myDrive [4], *myPathPart; UINT myPrevErrorMode; int myReturnCode; myDrive [0] = pmDriveLetter; myDrive [1] = ':'; myDrive [2] = '\\'; myDrive [3] = '\0'; myPrevErrorMode = SetErrorMode (SEM_FAILCRITICALERRORS); myReturnCode = GetDriveType (myDrive); SetErrorMode (myPrevErrorMode); if (myReturnCode == DRIVE_UNKNOWN) { SET_ERRMSG (E_FSYS_DISK_DRIVE_INVALID, "'%c' is not a valid drive", pmDriveLetter); return FALSE; } if (myReturnCode == DRIVE_NO_ROOT_DIR) { SET_ERRMSG (E_FSYS_DISK_DRIVE_INVALID, "No disk in '%c'", pmDriveLetter); return FALSE; } myDrive [2] = '.'; myReturnCode = GetFullPathName (myDrive, 1023, pmPath, &myPathPart); if (myReturnCode == 0) { SET_ERRMSG (E_FSYS_DISK_DRIVE_INVALID, "Unable to get default directory of '%c'", pmDriveLetter); return FALSE; } return TRUE; } // MDIOFile_GetDefaultPathForWindowsVolume
/** * Query next result * * @param stmt * @param errmsg * * @return 0 if query successfully, else return -1 and stored error * information in errmsg if errmsg is not null. */ int sws_query_next(SwsStmt *stmt, char **errmsg) { int ret; if (!stmt) { SET_ERRMSG(errmsg, "Some parameterment is null"); return -1; } ret = sqlite3_step(stmt); if (ret != SQLITE_ROW) { char msg[128]; snprintf(msg, sizeof(msg), "Query failed, errcode: %d", ret); SET_ERRMSG(errmsg, msg); return -1; } return 0; }
BOOL MDIOFile_Exists (const char *pmPathName, BOOL pmDataFileOnly) { UINT myPrevErrorMode; DWORD myWindowsAttributes; // Set the error mode so that missing disks fail normally // Load the first file in the directory myPrevErrorMode = SetErrorMode (SEM_FAILCRITICALERRORS); myWindowsAttributes = GetFileAttributes (pmPathName); SetErrorMode (myPrevErrorMode); if (myWindowsAttributes == (DWORD) -1) { DWORD myError = GetLastError (); if (myError == ERROR_FILE_NOT_FOUND) { SET_ERRMSG (E_FSYS_FILE_NOT_FOUND, "'%s' not found", pmPathName); } else if (myError == ERROR_PATH_NOT_FOUND) { SET_ERRMSG (E_FSYS_PATH_NOT_FOUND, "Path not found (couldn't find the directory " "that '%s' is in)", pmPathName); } else { MDIO_ProcessMSWindowsError (myError); } return FALSE; } if (pmDataFileOnly && ((myWindowsAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)) { SET_ERRMSG (E_DIR_IS_A_FILE, "'%s' is a directory", pmPathName); return FALSE; } return TRUE; } // MDIOFile_Exists
/** * * * @param stmt * @param errmsg * * @return 0 if end successfully, else return -1 and stored error * information in errmsg if errmsg is not null. */ int sws_query_end(SwsStmt *stmt, char **errmsg) { int ret; if (!stmt) { SET_ERRMSG(errmsg, "Some parameterment is null"); return -1; } ret = sqlite3_finalize(stmt); if (ret != SQLITE_OK) { char msg[64]; snprintf(msg, sizeof(msg), "End query failed, errcode: %d", ret); SET_ERRMSG(errmsg, msg); return -1; } return 0; }
/** * Excute a sql sentence * * @param db * @param sql Sql sentence you want to excute * @param errmsg * * @return 0 if everything is ok, else return -1 */ int sws_exec_sql(SwsDB *db, const char *sql, char **errmsg) { char *err = NULL; int ret = 0; if (!db || !sql) { SET_ERRMSG(errmsg, "Some parameterment is null"); return -1; } ret = sqlite3_exec(db, sql, NULL, NULL, &err); if (ret != SQLITE_OK) { char msg[512]; snprintf(msg, sizeof(msg), "\"%s\" failed: %s", sql, err); SET_ERRMSG(errmsg, msg); sqlite3_free(err); return -1; } return 0; }
/** * * * @param stmt * @param clm_index Column number * @param buf Store query result * @param buflen Max length of buffer which store query result in * @param errmsg * * @return 0 if query successfully, else return -1 and stored error * information in errmsg if errmsg is not null. */ int sws_query_column(SwsStmt *stmt, int clm_index, char *buf, int buflen, char **errmsg) { const unsigned char *result; if (!stmt || clm_index <0 || !buf || buflen <= 0) { SET_ERRMSG(errmsg, "Some parameterment is null"); return -1; } result = sqlite3_column_text(stmt, clm_index); if (!result) { char msg[64]; snprintf(msg, sizeof(msg), "Query %d column failed", clm_index); SET_ERRMSG(errmsg, msg); return -1; } snprintf(buf, buflen, "%s", result); return 0; }
void MIONet_GetCookies (const OOTstring pmURL, OOTstring pmCookieName [], OOTint pmCookieNameArraySize, OOTstring pmCookieValue [], OOTint pmCookieValueArraySize) { int myNumCookies = MDIONet_GetNumCookies (pmURL); if (myNumCookies > pmCookieNameArraySize) { SET_ERRMSG (E_NET_ARRAY_TOO_SMALL, "Cookie name array of %d is too small " "(%d cookies to be read)", pmCookieNameArraySize, myNumCookies); return; } if (myNumCookies > pmCookieValueArraySize) { SET_ERRMSG (E_NET_ARRAY_TOO_SMALL, "Cookie value array of %d is too small " "(%d cookies to be read)", pmCookieNameArraySize, myNumCookies); return; } MIONet_GetCookies (pmURL, pmCookieName, pmCookieNameArraySize, pmCookieValue, pmCookieValueArraySize); } // MIONet_GetCookies
/** * Query next result * * @param stmt * @param errmsg * * @return 0 if query successfully, else return -1 and stored error * information in errmsg if errmsg is not null. */ SwsRetCode sws_query_next(SwsStmt* stmt, char** errmsg) { int ret; if (!stmt) { SET_ERRMSG(errmsg, "Some parameterment is null"); return SWS_FAILED; } ret = sqlite3_step(stmt); if (ret == SQLITE_ROW) return SWS_OK; else if (ret == SQLITE_DONE) return SWS_FAILED; else if (ret == SQLITE_OK) return SWS_OK; else return SWS_FAILED; }
void MDIOFile_Status (const char *pmPathName, int *pmFileSize, int *pmAttrib, int *pmFileTime) { UINT myPrevErrorMode; DWORD myWindowsAttributes; OSVERSIONINFO myOSVersionInfo; int myOOTAttributes; HANDLE myHandle; FILETIME myCreationTime, myLastAccessTime, myLastWriteTime; DWORD mySize, myHighSize; LONGLONG myLongTime; int myTime; char *myPtr; // Set default values *pmFileSize = -1; *pmAttrib = -1; *pmFileTime = -1; // Set the error mode so that missing disks fail normally // Load the first file in the directory myPrevErrorMode = SetErrorMode (SEM_FAILCRITICALERRORS); myWindowsAttributes = GetFileAttributes (pmPathName); SetErrorMode (myPrevErrorMode); if (myWindowsAttributes == (DWORD) -1) { DWORD myError = GetLastError (); if (myError == ERROR_FILE_NOT_FOUND) { SET_ERRMSG (E_FSYS_FILE_NOT_FOUND, "'%s' not found", pmPathName); } else if (myError == ERROR_PATH_NOT_FOUND) { SET_ERRMSG (E_FSYS_PATH_NOT_FOUND, "Path not found (couldn't find the directory " "that '%s' is in)", pmPathName); } else { MDIO_ProcessMSWindowsError (myError); } return; } // Get the file attributes myOOTAttributes = OOT_ATTR_READ | OOT_ATTR_OWNER_READ | OOT_ATTR_GROUP_READ | OOT_ATTR_OTHER_READ; if ((myWindowsAttributes & FILE_ATTRIBUTE_READONLY) == 0) { myOOTAttributes |= OOT_ATTR_WRITE | OOT_ATTR_OWNER_WRITE | OOT_ATTR_GROUP_WRITE | OOT_ATTR_OTHER_WRITE; } if (myWindowsAttributes & FILE_ATTRIBUTE_HIDDEN) { myOOTAttributes |= OOT_ATTR_HIDDEN; } if (myWindowsAttributes & FILE_ATTRIBUTE_SYSTEM) { myOOTAttributes |= OOT_ATTR_SYSTEM; } if (myWindowsAttributes & FILE_ATTRIBUTE_DIRECTORY) { myOOTAttributes |= OOT_ATTR_DIR; } if (myWindowsAttributes & FILE_ATTRIBUTE_ARCHIVE) { myOOTAttributes |= OOT_ATTR_ARCHIVE; } // Set the OS version ZeroMemory (&myOSVersionInfo, sizeof (myOSVersionInfo)); myOSVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx (&myOSVersionInfo); // You cannot use CreateFile on a directory under Win 95/98/Me if ((myWindowsAttributes & FILE_ATTRIBUTE_DIRECTORY) && (myOSVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)) { WIN32_FIND_DATA myFindData; myPrevErrorMode = SetErrorMode (SEM_FAILCRITICALERRORS); myHandle = FindFirstFile (pmPathName, &myFindData); SetErrorMode (myPrevErrorMode); // Unfortunately, you cannot use FindFirstFile on a root directory // under Win95/98/Me. (I don't think you can actually get the file // date of the root directory.) if (myHandle == (HANDLE) INVALID_HANDLE_VALUE) { MDIO_ProcessMSWindowsError (GetLastError ()); return; } // Get the file time // Turing times use Unix style time. myLongTime = ((LONGLONG) myFindData.ftLastWriteTime.dwHighDateTime) << 32; myLongTime += myFindData.ftLastWriteTime.dwLowDateTime; myLongTime /= 10000000L; // Convert to seconds myLongTime -= 11644473600; // Convert from Jan 1, 1601 to Jan 1, 1970 *pmFileTime = (unsigned long) myLongTime; *pmAttrib = myOOTAttributes; *pmFileSize = 0; return; } myPtr = strrchr (pmPathName, '.'); if ((myPtr != NULL) && ((_stricmp (myPtr, ".exe") == 0) || (_stricmp (myPtr, ".com") == 0) || (_stricmp (myPtr, ".bat") == 0) || (_stricmp (myPtr, ".cmd") == 0))) { myOOTAttributes |= OOT_ATTR_EXECUTE | OOT_ATTR_OWNER_EXECUTE | OOT_ATTR_GROUP_EXECUTE | OOT_ATTR_OTHER_EXECUTE; } // Get the file time and size myPrevErrorMode = SetErrorMode (SEM_FAILCRITICALERRORS); if (myWindowsAttributes & FILE_ATTRIBUTE_DIRECTORY) { myHandle = CreateFile (pmPathName, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); } else { myHandle = CreateFile (pmPathName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); } SetErrorMode (myPrevErrorMode); // If call failed, then return FALSE if (myHandle == (HANDLE) INVALID_HANDLE_VALUE) { MDIO_ProcessMSWindowsError (GetLastError ()); return; } // Get the file time myPrevErrorMode = SetErrorMode (SEM_FAILCRITICALERRORS); if (!GetFileTime (myHandle, &myCreationTime, &myLastAccessTime, &myLastWriteTime)) { CloseHandle (myHandle); SetErrorMode (myPrevErrorMode); MDIO_ProcessMSWindowsError (GetLastError ()); return; } // The file time is in local time for Windows 95, and in UTC for Win NT // Turing times use Unix style time. myLongTime = ((LONGLONG) myLastWriteTime.dwHighDateTime) << 32; myLongTime += myLastWriteTime.dwLowDateTime; myLongTime /= 10000000L; // Convert to seconds myLongTime -= 11644473600; // Convert from Jan 1, 1601 to Jan 1, 1970 myTime = (unsigned long) myLongTime; if (myWindowsAttributes & FILE_ATTRIBUTE_DIRECTORY) { // Directory doesn't have a file size. CloseHandle (myHandle); SetErrorMode (myPrevErrorMode); *pmAttrib = myOOTAttributes; *pmFileSize = 0; *pmFileTime = myTime; return; } // Get the file size mySize = GetFileSize (myHandle, &myHighSize); if (mySize == -1) { CloseHandle (myHandle); SetErrorMode (myPrevErrorMode); MDIO_ProcessMSWindowsError (GetLastError ()); return; } CloseHandle (myHandle); SetErrorMode (myPrevErrorMode); *pmAttrib = myOOTAttributes;; *pmFileSize = mySize; *pmFileTime = myTime; } // MDIOFile_Status
static BOOL MyConvertToTuringPath (const char *pmMDPathName, char *pmTuringPath, int *pmPathType) { char myPath [1024]; char ch; char *mySrcPtr, *myDestPtr; int myNumElements = 0; BOOL myIsServerStylePath = FALSE; // Initialize type of path *pmPathType = 0; // First, convert all the backslashes to forward slashes // (maps path types 15-19 to 1 - 5) strcpy (myPath, pmMDPathName); while ((myDestPtr = strchr (myPath, '\\')) != NULL) { *myDestPtr = PATH_SEP; } mySrcPtr = myPath; myDestPtr = pmTuringPath; // Okay, let's determine what type of file we're dealing with here. return TRUE; // It can start with // (1) "elementEOS", "element/" // (2) "%ootEOS", "%homeEOS", "%oot/", "%home/" // (3) "/elementEOS", "/element{/:}" // (4) "x:/" // (5) "//element/" // (6) "volume:/" // (7) "x:EOS" // (8) ":element{/:}" // (9) "::" // (10) "volume:" // (11) "%oot:" // (2a) "%ootEOS", "%homeEOS" if ((strcmp (myPath, "%oot") == 0) || (strcmp (myPath, "%home") == 0)) { strcpy (pmTuringPath, myPath); // Set type of path *pmPathType = ABSOLUTE_PATH; return TRUE; } // (7) "x:EOS" else if (isalpha (myPath [0]) && (myPath [1] == ':') && (myPath [2] == 0)) { strcpy (pmTuringPath, myPath); strcat (pmTuringPath, PATH_SEP_STR); // Set type of path *pmPathType = ABSOLUTE_NO_DIR_PATH | WINDOWS_TYPE_PATH; return TRUE; } // (2b) "%oot/", "%home/" else if ((strncmp (myPath, "%oot/", 5) == 0) || (strncmp (myPath, "%home/", 6) == 0)) { while (*mySrcPtr != PATH_SEP) { *myDestPtr++ = *mySrcPtr++; } *myDestPtr++ = *mySrcPtr++; // Set type of path *pmPathType = ABSOLUTE_PATH; } // (11) "%oot:" else if ((strncmp (myPath, "%oot:", 5) == 0) || (strncmp (myPath, "%home:", 6) == 0)) { while (*mySrcPtr != ':') { *myDestPtr++ = *mySrcPtr++; } *myDestPtr++ = PATH_SEP; mySrcPtr++; // Set type of path *pmPathType = ABSOLUTE_PATH; } // (4) "x:/" else if (isalpha (*mySrcPtr) && (myPath [1] == ':') && (myPath [2] == PATH_SEP)) { int i; for (i = 0 ; i < 3 ; i++) { *myDestPtr++ = *mySrcPtr++; } // Set type of path *pmPathType = ABSOLUTE_PATH | WINDOWS_TYPE_PATH; } // (5) "//element/" else if ((myPath [0] == PATH_SEP) && (myPath [1] == PATH_SEP) && MyIsElement (&myPath [2])) { *myDestPtr++ = *mySrcPtr++; *myDestPtr++ = *mySrcPtr++; ch = *mySrcPtr; while ((ch != PATH_SEP) && (ch != ':') && (ch != '%') && (ch != 0)) { *myDestPtr++ = *mySrcPtr++; ch = *mySrcPtr; } if (ch != PATH_SEP) { SET_ERRMSG (E_FSYS_MALFORMED_PATHNAME, "Bad UNC format path ('%s'). Must be '//server/share'", pmMDPathName); pmTuringPath [0] = 0; return FALSE; } *myDestPtr++ = *mySrcPtr++; // Set type of path *pmPathType = ABSOLUTE_PATH | WINDOWS_TYPE_PATH; myIsServerStylePath = TRUE; } // (3) "/elementEOS", "/element{/:}" else if ((myPath [0] == PATH_SEP) && MyIsElement (&myPath [1])) { *myDestPtr++ = *mySrcPtr++; ch = *mySrcPtr; while ((ch != PATH_SEP) && (ch != ':') && (ch != '%') && (ch != 0)) { *myDestPtr++ = *mySrcPtr++; ch = *mySrcPtr; } if (ch == '%') { SET_ERRMSG (E_FSYS_BAD_CHAR_IN_PATHNAME, "Illegal character in '%s'. %% can only appear " "in path name as part of '%oot' or '%home'", pmMDPathName); pmTuringPath [0] = 0; return FALSE; } else if (ch == 0) { *myDestPtr++ = 0; return TRUE; } else if (ch == PATH_SEP) { *myDestPtr++ = *mySrcPtr++; } else // ch == ':' { *myDestPtr++ = PATH_SEP; mySrcPtr++; while (*mySrcPtr == ':') { *myDestPtr++ = '.'; *myDestPtr++ = '.'; *myDestPtr++ = PATH_SEP; mySrcPtr++; } } // Set type of path if (stOS == OS_UNIXLIKE) { *pmPathType = ABSOLUTE_PATH; } else { *pmPathType = ABSOLUTE_NO_VOL_PATH; } } // (9) "::" else if ((myPath [0] == ':') && (myPath [1] == ':')) { mySrcPtr++; while (*mySrcPtr == ':') { *myDestPtr++ = '.'; *myDestPtr++ = '.'; *myDestPtr++ = PATH_SEP; mySrcPtr++; } // Set type of path *pmPathType = RELATIVE_PATH; } // (8) ":element{/:}" else if ((myPath [0] == ':') && MyIsElement (&myPath [1])) { // This is a Macintosh-style relative path mySrcPtr++; ch = *mySrcPtr; while ((ch != PATH_SEP) && (ch != ':') && (ch != '%') && (ch != 0)) { *myDestPtr++ = *mySrcPtr++; ch = *mySrcPtr; } if (ch == '%') { SET_ERRMSG (E_FSYS_BAD_CHAR_IN_PATHNAME, "Illegal character in '%s'. %% can only appear " "in path name as part of '%oot' or '%home'", pmMDPathName); pmTuringPath [0] = 0; return FALSE; } else if (ch == 0) { *myDestPtr++ = 0; return TRUE; } else if (ch == PATH_SEP) { *myDestPtr++ = *mySrcPtr++; } else // ch == ':' { *myDestPtr++ = PATH_SEP; mySrcPtr++; while (*mySrcPtr == ':') { *myDestPtr++ = '.'; *myDestPtr++ = '.'; *myDestPtr++ = PATH_SEP; mySrcPtr++; } } // Set type of path *pmPathType = RELATIVE_PATH; } // (1) "elementEOS", "element/", (6) "volume:/", (10) "volume:" else if (MyIsElement (myPath)) { ch = *mySrcPtr; while ((ch != PATH_SEP) && (ch != ':') && (ch != '%') && (ch != 0)) { *myDestPtr++ = *mySrcPtr++; ch = *mySrcPtr; } if (ch == '%') { SET_ERRMSG (E_FSYS_BAD_CHAR_IN_PATHNAME, "Illegal character in '%s'. %% can only appear " "in path name as part of '%oot' or '%home'", pmMDPathName); pmTuringPath [0] = 0; return FALSE; } // (1a) else if (ch == 0) { *myDestPtr++ = *mySrcPtr++; // Set type of path *pmPathType = RELATIVE_PATH; return TRUE; } // (1b) else if (ch == PATH_SEP) { *myDestPtr++ = *mySrcPtr++; // Set type of path *pmPathType = RELATIVE_PATH; } // (6) or (10) else if (ch == ':') { *myDestPtr++ = *mySrcPtr++; ch = *mySrcPtr; // (6) if (ch == PATH_SEP) { *myDestPtr++ = *mySrcPtr++; } // (10) else if (MyIsElement (mySrcPtr)) { *myDestPtr++ = PATH_SEP; } else { SET_ERRMSG (E_FSYS_MALFORMED_PATHNAME, "Malformed pathname in '%s'. Macintosh path name " "format is 'volume:folder:folder:file'", pmMDPathName); pmTuringPath [0] = 0; return FALSE; } // Set type of path *pmPathType = ABSOLUTE_PATH | MACOS_TYPE_PATH; } } else { SET_ERRMSG (E_FSYS_MALFORMED_PATHNAME, "Malformed pathname in '%s'", pmMDPathName); pmTuringPath [0] = 0; return FALSE; } // We've now converted the first element. We should now point at // the next element or the end of file. while (*mySrcPtr != 0) { if (!MyIsElement (mySrcPtr)) { SET_ERRMSG (E_FSYS_MALFORMED_PATHNAME, "Malformed pathname in '%s'", pmMDPathName); pmTuringPath [0] = 0; return FALSE; } ch = *mySrcPtr; while ((ch != PATH_SEP) && (ch != ':') && (ch != '%') && (ch != 0)) { *myDestPtr++ = *mySrcPtr++; ch = *mySrcPtr; } if (ch == 0) { // The format of //server/share should always have a terminating / if ((myIsServerStylePath) && (myNumElements == 0)) { *myDestPtr++ = '/'; } *myDestPtr++ = *mySrcPtr++; return TRUE; } else if (ch == PATH_SEP) { *myDestPtr++ = *mySrcPtr++; myNumElements++; } else if (ch == '%') { SET_ERRMSG (E_FSYS_BAD_CHAR_IN_PATHNAME, "Illegal character in '%s'. %% can only appear " "in path name as part of '%oot' or '%home'", pmMDPathName); pmTuringPath [0] = 0; return FALSE; } else if (ch == ':') { // Colon has special meaning on Macintosh *myDestPtr++ = PATH_SEP; mySrcPtr++; while (*mySrcPtr == ':') { *myDestPtr++ = '.'; *myDestPtr++ = '.'; *myDestPtr++ = PATH_SEP; mySrcPtr++; } } } *myDestPtr = 0; return TRUE; } // MyConvertToTuringPath
BOOL MIOFile_ConvertPath (const char *pmMDUserPath, char *pmAbsolutePath, char *pmMDAbsolutePath, BOOL pmAllowTrailingSlash) { char myTuringUserPath [4096]; int myPathType; char myPath [4096], myAbsolutePath [4096]; char *myPtr, *myStart, *myDestPtr; // Note that a Turing Path is UNIX like if (!MyConvertToTuringPath (pmMDUserPath, myTuringUserPath, &myPathType)) { return FALSE; } if ((stOS != OS_WINDOWS) && (myPathType & WINDOWS_TYPE_PATH)) { SET_ERRMSG (E_FSYS_MALFORMED_PATHNAME, "Attempt to use a Windows style pathname (%s) on a " "non-Windows system", pmMDUserPath); return FALSE; } if ((stOS != OS_MACOS) && (myPathType & MACOS_TYPE_PATH)) { SET_ERRMSG (E_FSYS_MALFORMED_PATHNAME, "Attempt to use a Macintosh style pathname (%s) on a " "non-Macintosh system", pmMDUserPath); return FALSE; } // // There are a number of different file types possible at this point, // each with different flags: // // RELATIVE_PATH "a/b/c" // ABSOLUTE_PATH "%oot/a/b/c" // ABSOLUTE_NO_VOL_PATH "/a/b/c" (Win/Mac assume default vol) // ABSOLUTE_PATH [WINDOWS] "x:/a/b/c" // ABSOLUTE_PATH [WINDOWS] "//server/a/b/c" // ABSOLUTE_PATH [MACOS] "volume:/a/b/c" // ABSOLUTE_NO_DIR_PATH [WINDOWS] "x:" (Win assume default directory) // if (myPathType & RELATIVE_PATH) { // // RELATIVE_PATH "a/b/c" // strcpy (myPath, stExecutionDir); // Add the relative directory strcat (myPath, myTuringUserPath); } else { if ((strncmp (myTuringUserPath, "%oot", 4) == 0) || (strncmp (myTuringUserPath, "%home", 5) == 0)) { // // ABSOLUTE_PATH "%oot/a/b/c" // if (strcmp (myTuringUserPath, "%oot") == 0) { strcpy (myPath, stOOTDir); } else if (strcmp (myTuringUserPath, "%home") == 0) { strcpy (myPath, stHomeDir); } else if (strncmp (myTuringUserPath, "%oot/", 5) == 0) { strcpy (myPath, stOOTDir); strcat (myPath, &myTuringUserPath [5]); } else if (strncmp (myTuringUserPath, "%home/", 6) == 0) { strcpy (myPath, stHomeDir); strcat (myPath, &myTuringUserPath [6]); } else { EdInt_HaltEnvironment (IDS_MIO_FILEFAIL, __FILE__, __LINE__, 0, 401); } } else if (myPathType & ABSOLUTE_NO_VOL_PATH) { // // ABSOLUTE_NO_VOL_PATH "/a/b/c" (Win/Mac assume default vol) // if (stOS == OS_UNIXLIKE) { EdInt_HaltEnvironment (IDS_MIO_FILEFAIL, __FILE__, __LINE__, 0, 402); } // Copy the volume name from the execution directory strcpy (myPath, stExecutionDir); myPtr = myPath; while ((*myPtr != ':') && (*myPtr != 0)) { myPtr++; } if (*myPtr == 0) { EdInt_HaltEnvironment (IDS_MIO_FILEFAIL, __FILE__, __LINE__, 0, 403); } // Copy the user path after the execution directory volume myPtr++; strcpy (myPtr, myTuringUserPath); } else if (myPathType & ABSOLUTE_NO_DIR_PATH) { // // ABSOLUTE_NO_DIR_PATH [WINDOWS] "x:" (Win assume default directory) // if (stOS != OS_WINDOWS) { EdInt_HaltEnvironment (IDS_MIO_FILEFAIL, __FILE__, __LINE__, 0, 404); } if (!MDIOFile_GetDefaultPathForWindowsVolume (myTuringUserPath [0], myPath)) { // Error message is set by MDIOFile_GetDefault... return FALSE; } } else { // // We don't actually have to do any additional work for the // following. // // ABSOLUTE_PATH [WINDOWS] "x:/a/b/c" // ABSOLUTE_PATH [WINDOWS] "//server/a/b/c" // ABSOLUTE_PATH [MACOS] "volume:/a/b/c" // strcpy (myPath, myTuringUserPath); } } // // myPath is now in one of the following forms: // /a/b/c" (UNIX only) [/] // "x:/a/b/c" (WINDOWS only) [x:/] // "//server/share/a/b/c" (WINDOWS only) [//server/share/] // "volume:/a/b/c" (MACOS only) [volume:/] // // First, mark where the start of the path is // if ((myPath [0] == PATH_SEP) && (myPath [1] == PATH_SEP)) { myPtr = &myPath [2]; // myPtr now points at beginning of server name // Skip over server name while ((*myPtr != PATH_SEP) && (*myPtr != 0)) { myPtr++; } if (*myPtr == 0) { EdInt_HaltEnvironment (IDS_MIO_FILEFAIL, __FILE__, __LINE__, 0, 405); } // Skip over share name myPtr++; // myPtr now points at beginning of share name while ((*myPtr != PATH_SEP) && (*myPtr != 0)) { myPtr++; } } else if (myPath [0] == PATH_SEP) { myPtr = myPath; } else { myPtr = myPath; // Skip over volume name while ((*myPtr != ':') && (*myPtr != 0)) { myPtr++; } if (*myPtr == 0) { EdInt_HaltEnvironment (IDS_MIO_FILEFAIL, __FILE__, __LINE__, 0, 406); } myPtr++; } if (*myPtr == 0) { EdInt_HaltEnvironment (IDS_MIO_FILEFAIL, __FILE__, __LINE__, 0, 407); } myPtr++; // myPtr is now pointing at ^ [//server/share/^ or d:/^] strncpy (myAbsolutePath, myPath, myPtr - myPath); myStart = &myAbsolutePath [myPtr - myPath]; myDestPtr = myStart; // Now factor out the ".."'s while (*myPtr != 0) { if ((strncmp (myPtr, "../", 3) == 0) || (strcmp (myPtr, "..") == 0)) { // // Handle ".." // // Remove directory and last / if (myDestPtr == myStart) { SET_ERRMSG (E_FSYS_MALFORMED_PATHNAME, "Attempt to move up ('..') in the root directory ('%s')", pmMDUserPath); return FALSE; } else { myDestPtr--; do { myDestPtr--; } while (*myDestPtr != PATH_SEP); myDestPtr++; } // Skip over '..' if (strncmp (myPtr, "../", 3) == 0) { myPtr += 3; } else { // Special case: if ".." at the end of the line, we don't want // to end with a /, *unless* we're at the root. *sigh*. myPtr += 2; if (myDestPtr != myStart) { myDestPtr--; } } } else if ((strncmp (myPtr, "./", 2) == 0) || (strcmp (myPtr, ".") == 0)) { // // Handle "." // if (strncmp (myPtr, "./", 2) == 0) { myPtr += 2; } else { // Special case: if "." at the end of the line, we don't want // to end with a /, *unless* we're at the root. *sigh*. myPtr += 1; if (myDestPtr != myStart) { myDestPtr--; } } } else { // // Handle path element // if (*myPtr == PATH_SEP) { SET_ERRMSG (E_FSYS_MALFORMED_PATHNAME, "'//' not allowed in path name (%s)", myAbsolutePath); return FALSE; } while ((*myPtr != PATH_SEP) && (*myPtr != 0)) { *myDestPtr++ = *myPtr++; } } if (*myPtr == PATH_SEP) { *myDestPtr++ = *myPtr++; } } // while (*myPtr != 0) *myDestPtr = 0; // Remove any trailing "/" unless it's the root directory slash myDestPtr--; if ((*myDestPtr == PATH_SEP) && (myDestPtr > myStart)) { if (pmAllowTrailingSlash) { *myDestPtr = 0; } else { SET_ERRMSG (E_FSYS_MALFORMED_PATHNAME, "No trailing slash allowed in a file path name", myAbsolutePath); return FALSE; } } // // At this point we have a Turing style absolute path in myAbsolutePath // // Copy to pmAbsolutePath if necessary if (pmAbsolutePath != NULL) { strcpy (pmAbsolutePath, myAbsolutePath); } // If we don't need an MD absolute path, exit. if (pmMDAbsolutePath == NULL) { return TRUE; } if (stOS == OS_UNIXLIKE) { strcpy (pmMDAbsolutePath, myAbsolutePath); } else if (stOS == OS_WINDOWS) { strcpy (pmMDAbsolutePath, myAbsolutePath); myPtr = pmMDAbsolutePath; while (*myPtr != 0) { if (*myPtr == PATH_SEP) { *myPtr = '\\'; } myPtr++; } } else if (stOS == OS_MACOS) { // TW Work to do here } else { EdInt_HaltEnvironment (IDS_MIO_FILEFAIL, __FILE__, __LINE__, 0, 301); } return TRUE; } // MIOFile_ConvertPath