/** @copydoc VBOXHDDBACKEND::pfnCheckIfValid */ static DECLCALLBACK(int) rawCheckIfValid(const char *pszFilename, PVDINTERFACE pVDIfsDisk, PVDINTERFACE pVDIfsImage, VDTYPE *penmType) { LogFlowFunc(("pszFilename=\"%s\" pVDIfsDisk=%#p pVDIfsImage=%#p\n", pszFilename, pVDIfsDisk, pVDIfsImage)); PVDIOSTORAGE pStorage = NULL; uint64_t cbFile; int rc = VINF_SUCCESS; char *pszSuffix = NULL; PVDINTERFACEIOINT pIfIo = VDIfIoIntGet(pVDIfsImage); AssertPtrReturn(pIfIo, VERR_INVALID_PARAMETER); if ( !VALID_PTR(pszFilename) || !*pszFilename) { rc = VERR_INVALID_PARAMETER; goto out; } pszSuffix = RTPathSuffix(pszFilename); /* * Open the file and read the footer. */ rc = vdIfIoIntFileOpen(pIfIo, pszFilename, VDOpenFlagsToFileOpenFlags(VD_OPEN_FLAGS_READONLY, false /* fCreate */), &pStorage); if (RT_SUCCESS(rc)) rc = vdIfIoIntFileGetSize(pIfIo, pStorage, &cbFile); /* Try to guess the image type based on the extension. */ if ( RT_SUCCESS(rc) && pszSuffix) { if ( !RTStrICmp(pszSuffix, ".iso") || !RTStrICmp(pszSuffix, ".cdr")) /* DVD images. */ { /* Note that there are ISO images smaller than 1 MB; it is impossible to distinguish * between raw floppy and CD images based on their size (and cannot be reliably done * based on contents, either). */ if (cbFile % 2048) rc = VERR_VD_RAW_SIZE_MODULO_2048; else if (cbFile <= 32768) rc = VERR_VD_RAW_SIZE_OPTICAL_TOO_SMALL; else { *penmType = VDTYPE_DVD; rc = VINF_SUCCESS; } } else if ( !RTStrICmp(pszSuffix, ".img") || !RTStrICmp(pszSuffix, ".ima") || !RTStrICmp(pszSuffix, ".dsk") || !RTStrICmp(pszSuffix, ".flp") || !RTStrICmp(pszSuffix, ".vfd")) /* Floppy images */ { if (cbFile % 512) rc = VERR_VD_RAW_SIZE_MODULO_512; else if (cbFile > RAW_MAX_FLOPPY_IMG_SIZE) rc = VERR_VD_RAW_SIZE_FLOPPY_TOO_BIG; else { *penmType = VDTYPE_FLOPPY; rc = VINF_SUCCESS; } } else rc = VERR_VD_RAW_INVALID_HEADER; } else rc = VERR_VD_RAW_INVALID_HEADER; if (pStorage) vdIfIoIntFileClose(pIfIo, pStorage); out: LogFlowFunc(("returns %Rrc\n", rc)); return rc; }
/** * Figure the type of a file/dir based on path and FS object info. * * @returns The type. * @param pszPath The path to the file/dir. * @param pObjInfo The object information, symlinks followed. */ static RTDBGSYMCACHEFILETYPE rtDbgSymCacheFigureType2(const char *pszPath, PCRTFSOBJINFO pObjInfo) { const char *pszName = RTPathFilename(pszPath); const char *pszExt = RTPathSuffix(pszName); if (pszExt) pszExt++; else pszExt = ""; if ( RTFS_IS_DIRECTORY(pObjInfo->Attr.fMode) || (pObjInfo->Attr.fMode & RTFS_DOS_DIRECTORY)) /** @todo OS X samba reports reparse points in /Volumes/ that we cannot resolve. */ { /* Skip directories shouldn't bother with. */ if ( !RTStrICmp(pszName, ".Trashes") || !RTStrICmp(pszName, ".$RESCYCLE.BIN") || !RTStrICmp(pszName, "System.kext") /* Usually only plugins here, so skip it. */ ) return RTDBGSYMCACHEFILETYPE_IGNORE; /* Directories can also be bundles on the mac. */ if (!RTStrICmp(pszExt, "dSYM")) return RTDBGSYMCACHEFILETYPE_DEBUG_BUNDLE; for (unsigned i = 0; i < RT_ELEMENTS(g_apszBundleSuffixes) - 1; i++) if (!RTStrICmp(pszExt, &g_apszBundleSuffixes[i][1])) return RTDBGSYMCACHEFILETYPE_IMAGE_BUNDLE; return RTDBGSYMCACHEFILETYPE_DIR; } if (!RTFS_IS_FILE(pObjInfo->Attr.fMode)) return RTDBGSYMCACHEFILETYPE_INVALID; /* Select image vs debug info based on extension. */ if ( !RTStrICmp(pszExt, "pdb") || !RTStrICmp(pszExt, "dbg") || !RTStrICmp(pszExt, "sym") || !RTStrICmp(pszExt, "dwo") || !RTStrICmp(pszExt, "dwp") || !RTStrICmp(pszExt, "debug") || !RTStrICmp(pszExt, "dsym") || !RTStrICmp(pszExt, "dwarf") || !RTStrICmp(pszExt, "map") || !RTStrICmp(pszExt, "cv")) return RTDBGSYMCACHEFILETYPE_DEBUG_FILE; /* Filter out a bunch of files which obviously shouldn't be images. */ if ( !RTStrICmp(pszExt, "txt") || !RTStrICmp(pszExt, "html") || !RTStrICmp(pszExt, "htm") || !RTStrICmp(pszExt, "rtf") || !RTStrICmp(pszExt, "zip") || !RTStrICmp(pszExt, "doc") || !RTStrICmp(pszExt, "gz") || !RTStrICmp(pszExt, "bz2") || !RTStrICmp(pszExt, "xz") || !RTStrICmp(pszExt, "kmk") || !RTStrICmp(pszExt, "c") || !RTStrICmp(pszExt, "cpp") || !RTStrICmp(pszExt, "h") || !RTStrICmp(pszExt, "m") || !RTStrICmp(pszExt, "mm") || !RTStrICmp(pszExt, "asm") || !RTStrICmp(pszExt, "S") || !RTStrICmp(pszExt, "inc") || !RTStrICmp(pszExt, "sh") ) return RTDBGSYMCACHEFILETYPE_IGNORE; if ( !RTStrICmp(pszName, "Makefile") || !RTStrICmp(pszName, "GNUmakefile") || !RTStrICmp(pszName, "createsymbolfiles") || !RTStrICmp(pszName, "kgmacros") ) return RTDBGSYMCACHEFILETYPE_IGNORE; return RTDBGSYMCACHEFILETYPE_IMAGE_FILE; }
/** The actual implemenation code for @a createServiceFile. */ bool createServiceFileCore(char **ppachTemplate, struct SERVICEPARAMETERS *pParameters) { /* The size of the template data we have read. */ size_t cchTemplate = 0; /* The size of the buffer we have allocated. */ size_t cbBuffer = 0; /* How much of the template data we have written out. */ size_t cchWritten = 0; int rc = VINF_SUCCESS; /* First of all read in the file. */ while (rc != VINF_EOF) { size_t cchRead; if (cchTemplate == cbBuffer) { cbBuffer += READ_SIZE; *ppachTemplate = (char *)RTMemRealloc((void *)*ppachTemplate, cbBuffer); } if (!*ppachTemplate) { RTStrmPrintf(g_pStdErr, "Out of memory.\n"); return false; } rc = RTStrmReadEx(g_pStdIn, *ppachTemplate + cchTemplate, cbBuffer - cchTemplate, &cchRead); if (RT_FAILURE(rc)) { RTStrmPrintf(g_pStdErr, "Error reading input: %Rrc\n", rc); return false; } if (!cchRead) rc = VINF_EOF; cchTemplate += cchRead; } while (true) { /* Find the next '%' character if any and write out up to there (or the * end if there is no '%'). */ char *pchNext = (char *) memchr((void *)(*ppachTemplate + cchWritten), '%', cchTemplate - cchWritten); size_t cchToWrite = pchNext ? pchNext - *ppachTemplate - cchWritten : cchTemplate - cchWritten; rc = RTStrmWrite(g_pStdOut, *ppachTemplate + cchWritten, cchToWrite); if (RT_FAILURE(rc)) { RTStrmPrintf(g_pStdErr, "Error writing output: %Rrc\n", rc); return false; } cchWritten += cchToWrite; if (!pchNext) break; /* And substitute any of our well-known strings. We favour code * readability over efficiency here. */ if (getSequence(*ppachTemplate, cchTemplate, &cchWritten, COMMAND, sizeof(COMMAND) - 1)) { if (!pParameters->pcszCommand) { RTStrmPrintf(g_pStdErr, "--command not specified.\n"); return false; } if (!writeCommand(pParameters->enmFormat, pParameters->pcszCommand)) return false; } else if (getSequence(*ppachTemplate, cchTemplate, &cchWritten, ARGUMENTS, sizeof(ARGUMENTS) - 1)) { if ( pParameters->pcszArguments && !writeQuoted(pParameters->enmFormat, pParameters->pcszArguments)) return false; } else if (getSequence(*ppachTemplate, cchTemplate, &cchWritten, DESCRIPTION, sizeof(DESCRIPTION) - 1)) { if (!pParameters->pcszDescription) { RTStrmPrintf(g_pStdErr, "--description not specified.\n"); return false; } if (!writePrintableString(pParameters->enmFormat, pParameters->pcszDescription)) return false; } else if (getSequence(*ppachTemplate, cchTemplate, &cchWritten, SERVICE_NAME, sizeof(SERVICE_NAME) - 1)) { if ( !pParameters->pcszCommand && !pParameters->pcszServiceName) { RTStrmPrintf(g_pStdErr, "Neither --command nor --service-name specified.\n"); return false; } if (pParameters->pcszServiceName) { if (!writePrintableString(pParameters->enmFormat, pParameters->pcszServiceName)) return false; } else { const char *pcszFileName = RTPathFilename(pParameters->pcszCommand); const char *pcszSuffix = RTPathSuffix(pParameters->pcszCommand); char *pszName = RTStrDupN(pcszFileName, pcszSuffix ? pcszSuffix - pcszFileName : RTPATH_MAX); bool fRc; if (!pszName) { RTStrmPrintf(g_pStdErr, "Out of memory.\n"); return false; } fRc = writePrintableString(pParameters->enmFormat, pszName); RTStrFree(pszName); if (!fRc) return false; } } else if (getSequence(*ppachTemplate, cchTemplate, &cchWritten, HAVE_ONESHOT, sizeof(HAVE_ONESHOT) - 1)) { if (!pParameters->fOneShot) skipLine(*ppachTemplate, cchTemplate, &cchWritten); } else if (getSequence(*ppachTemplate, cchTemplate, &cchWritten, HAVE_DAEMON, sizeof(HAVE_DAEMON) - 1)) { if (pParameters->fOneShot) skipLine(*ppachTemplate, cchTemplate, &cchWritten); } else if (getSequence(*ppachTemplate, cchTemplate, &cchWritten, STOP_COMMAND, sizeof(STOP_COMMAND) - 1)) { if ( pParameters->pcszStopCommand && !writeCommand(pParameters->enmFormat, pParameters->pcszStopCommand)) return false; } else if (getSequence(*ppachTemplate, cchTemplate, &cchWritten, STOP_ARGUMENTS, sizeof(STOP_ARGUMENTS) - 1)) { if ( pParameters->pcszStopArguments && !writeQuoted(pParameters->enmFormat, pParameters->pcszStopArguments)) return false; } else if (getSequence(*ppachTemplate, cchTemplate, &cchWritten, HAVE_STOP_COMMAND, sizeof(HAVE_STOP_COMMAND) - 1)) { if (!pParameters->pcszStopCommand) skipLine(*ppachTemplate, cchTemplate, &cchWritten); } else if (getSequence(*ppachTemplate, cchTemplate, &cchWritten, NO_STOP_COMMAND, sizeof(NO_STOP_COMMAND) - 1)) { if (pParameters->pcszStopCommand) skipLine(*ppachTemplate, cchTemplate, &cchWritten); } else if (getSequence(*ppachTemplate, cchTemplate, &cchWritten, STATUS_COMMAND, sizeof(STATUS_COMMAND) - 1)) { if ( pParameters->pcszStatusCommand && !writeCommand(pParameters->enmFormat, pParameters->pcszStatusCommand)) return false; } else if (getSequence(*ppachTemplate, cchTemplate, &cchWritten, STATUS_ARGUMENTS, sizeof(STATUS_ARGUMENTS) - 1)) { if ( pParameters->pcszStatusArguments && !writeQuoted(pParameters->enmFormat, pParameters->pcszStatusArguments)) return false; } else if (getSequence(*ppachTemplate, cchTemplate, &cchWritten, HAVE_STATUS_COMMAND, sizeof(HAVE_STATUS_COMMAND) - 1)) { if (!pParameters->pcszStatusCommand) skipLine(*ppachTemplate, cchTemplate, &cchWritten); } else if (getSequence(*ppachTemplate, cchTemplate, &cchWritten, NO_STATUS_COMMAND, sizeof(NO_STATUS_COMMAND) - 1)) { if (pParameters->pcszStatusCommand) skipLine(*ppachTemplate, cchTemplate, &cchWritten); } else if (getSequence(*ppachTemplate, cchTemplate, &cchWritten, "%%", 2)) { rc = RTStrmPutCh(g_pStdOut, '%'); if (RT_FAILURE(rc)) { RTStrmPrintf(g_pStdErr, "Error writing output: %Rrc\n", rc); return false; } } else { RTStrmPrintf(g_pStdErr, "Unknown substitution sequence in input at \"%.*s\"\n", RT_MIN(16, cchTemplate - cchWritten), *ppachTemplate + cchWritten); return false; } } return true; }