uint64_t util_rndGet(uint64_t min, uint64_t max) { if (min > max) { LOG_F("min:%" PRIu64 " > max:%" PRIu64, min, max); } if (util_urandomFd == -1) { if ((util_urandomFd = open("/dev/urandom", O_RDONLY)) == -1) { PLOG_F("Couldn't open /dev/urandom for writing"); } } if (rndIni == false) { if (files_readFromFd(util_urandomFd, (uint8_t *) & rndX, sizeof(rndX)) == false) { PLOG_F("Couldn't read '%zu' bytes from /dev/urandom", sizeof(rndX)); } rndIni = true; } /* MMIX LCG PRNG */ static const uint64_t a = 6364136223846793005ULL; static const uint64_t c = 1442695040888963407ULL; rndX = (a * rndX + c); return ((rndX % (max - min + 1)) + min); }
ssize_t files_readFileToBufMax(char *fileName, uint8_t * buf, size_t fileMaxSz) { int fd = open(fileName, O_RDONLY); if (fd == -1) { PLOG_W("Couldn't open '%s' for R/O", fileName); return -1; } defer { close(fd); }; ssize_t readSz = files_readFromFd(fd, buf, fileMaxSz); if (readSz < 0) { LOG_W("Couldn't read '%s' to a buf", fileName); return -1; } LOG_D("Read '%zu' bytes from '%s'", readSz, fileName); return readSz; }
/* * dstExists argument can be used by caller for cases where existing destination * file requires special handling (e.g. save unique crashes) */ bool files_copyFile(const char *source, const char *destination, bool * dstExists) { if (dstExists) *dstExists = false; if (link(source, destination) == 0) { return true; } else { if (errno == EEXIST) { // Should kick-in before MAC, so avoid the hassle if (dstExists) *dstExists = true; return false; } else { PLOG_D("Couldn't link '%s' as '%s'", source, destination); /* * Don't fail yet as we might have a running env which doesn't allow * hardlinks (e.g. SELinux) */ } } // Now try with a verbose POSIX alternative int inFD, outFD, dstOpenFlags; mode_t dstFilePerms; // O_EXCL is important for saving unique crashes dstOpenFlags = O_CREAT | O_WRONLY | O_EXCL; dstFilePerms = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; inFD = open(source, O_RDONLY); if (inFD == -1) { PLOG_D("Couldn't open '%s' source", source); return false; } defer { close(inFD); }; struct stat inSt; if (fstat(inFD, &inSt) == -1) { PLOG_W("Couldn't fstat(fd='%d' fileName='%s')", inFD, source); return false; } outFD = open(destination, dstOpenFlags, dstFilePerms); if (outFD == -1) { if (errno == EEXIST) { if (dstExists) *dstExists = true; } PLOG_D("Couldn't open '%s' destination", destination); return false; } defer { close(outFD); }; uint8_t *inFileBuf = malloc(inSt.st_size); if (!inFileBuf) { PLOG_W("malloc(%zu) failed", (size_t) inSt.st_size); return false; } defer { free(inFileBuf); }; ssize_t readSz = files_readFromFd(inFD, inFileBuf, (size_t) inSt.st_size); if (readSz < 0) { PLOG_W("Couldn't read '%s' to a buf", source); return false; } if (files_writeToFd(outFD, inFileBuf, readSz) == false) { PLOG_W("Couldn't write '%zu' bytes to file '%s' (fd='%d')", (size_t) readSz, destination, outFD); unlink(destination); return false; } return true; }