diff options
Diffstat (limited to 'src/datafiles.c')
-rw-r--r-- | src/datafiles.c | 563 |
1 files changed, 4 insertions, 559 deletions
diff --git a/src/datafiles.c b/src/datafiles.c index a051704be..920c0e5ef 100644 --- a/src/datafiles.c +++ b/src/datafiles.c @@ -23,529 +23,6 @@ static time_t lastwarn = 0; /*************************************************************************/ /** - * Return the version number on the file. Return 0 if there is no version - * number or the number doesn't make sense (i.e. less than 1 or greater - * than FILE_VERSION). - * @param f dbFile Struct Member - * @return int 0 if failure, 1 > is the version number - */ -int get_file_version(dbFILE * f) -{ - FILE *fp = f->fp; - int version = - fgetc(fp) << 24 | fgetc(fp) << 16 | fgetc(fp) << 8 | fgetc(fp); - if (ferror(fp)) { - log_perror("Error reading version number on %s", f->filename); - return 0; - } else if (feof(fp)) { - alog("Error reading version number on %s: End of file detected", - f->filename); - return 0; - } else if (version < 1) { - alog("Invalid version number (%d) on %s", version, f->filename); - return 0; - } - return version; -} - -/*************************************************************************/ - -/** - * Write the current version number to the file. - * @param f dbFile Struct Member - * @return 0 on error, 1 on success. - */ -int write_file_version(dbFILE * f, uint32 version) -{ - FILE *fp = f->fp; - if (fputc(version >> 24 & 0xFF, fp) < 0 || - fputc(version >> 16 & 0xFF, fp) < 0 || - fputc(version >> 8 & 0xFF, fp) < 0 || - fputc(version & 0xFF, fp) < 0) { - log_perror("Error writing version number on %s", f->filename); - return 0; - } - return 1; -} - -/*************************************************************************/ - -/** - * Open the database for reading - * @param service If error whom to return the error as - * @param filename File to open as the database - * @return dbFile struct - */ -static dbFILE *open_db_read(const char *service, const char *filename) -{ - dbFILE *f; - FILE *fp; - - f = new dbFILE; - if (!f) { - log_perror("Can't read %s database %s", service, filename); - if (time(NULL) - lastwarn > Config.WarningTimeout) { - ircdproto->SendGlobops(NULL, - "Write error on %s: Memory allocation failed", - filename); - lastwarn = time(NULL); - } - return NULL; - } - strscpy(f->filename, filename, sizeof(f->filename)); - f->mode = 'r'; - fp = fopen(f->filename, "rb"); - if (!fp) { - int errno_save = errno; - if (errno != ENOENT) - log_perror("Can not read %s database %s", service, - f->filename); - if (time(NULL) - lastwarn > Config.WarningTimeout) { - ircdproto->SendGlobops(NULL, "Write error on %s: %s", f->filename, - strerror(errno)); - lastwarn = time(NULL); - } - delete f; - errno = errno_save; - return NULL; - } - f->fp = fp; - f->backupfp = NULL; - return f; -} - -/*************************************************************************/ - -/** - * Open the database for writting - * @param service If error whom to return the error as - * @param filename File to open as the database - * @param version Database Version - * @return dbFile struct - */ -static dbFILE *open_db_write(const char *service, const char *filename, - uint32 version) -{ - dbFILE *f; - int fd; -#ifdef _WIN32 - char buffer[_MAX_PATH]; - char win32filename[MAXPATHLEN]; - - /* Get the current working directory: */ - if (_getcwd(buffer, _MAX_PATH) == NULL) { - alog("Warning: Unable to set Current working directory"); - } -#endif - - f = new dbFILE; - if (!f) { - log_perror("Can not read %s database %s", service, filename); - return NULL; - } - strscpy(f->filename, filename, sizeof(f->filename)); -#ifndef _WIN32 - filename = f->filename; -#else - snprintf(win32filename, sizeof(win32filename), "%s\\%s", buffer, - f->filename); - filename = win32filename; -#endif - f->mode = 'w'; - - *f->backupname = 0; - snprintf(f->backupname, sizeof(f->backupname), "%s.save", filename); - if (!*f->backupname || strcmp(f->backupname, filename) == 0) { - int errno_save = errno; - alog("Opening %s database %s for write: Filename too long", - service, filename); - delete f; - errno = errno_save; - return NULL; - } -#ifndef _WIN32 - unlink(filename); -#else - DeleteFile(filename); -#endif - f->backupfp = fopen(filename, "rb"); -#ifdef _WIN32 - if (!MoveFileExA(filename, f->backupname, MOVEFILE_COPY_ALLOWED) - && GetLastError() != ENOENT) { - int errno_save = GetLastError(); -#else - if (rename(filename, f->backupname) < 0 && errno != ENOENT) { - int errno_save = errno; -#endif - - static int walloped = 0; - if (!walloped) { - walloped++; - ircdproto->SendGlobops(NULL, "Can not back up %s database %s", - service, filename); - } -#ifdef _WIN32 - if (debug) { - if (errno == ENOENT) { - alog("debug: Error %d (ENOENT) : the file or directory does not exist", errno); - } else if (errno == EACCES) { - alog("debug: Error %d (EACCES) : error while attempting to access file", errno); - } else { - alog("debug: Error %d", errno); - } - } -#else - if (debug) { - alog("debug: Error %d", errno); - } -#endif - errno = errno_save; - log_perror("Can not back up %s database %s", service, filename); - if (!Config.NoBackupOkay) { - if (f->backupfp) - fclose(f->backupfp); - delete f; - errno = errno_save; - return NULL; - } - *f->backupname = 0; - } -#ifndef _WIN32 - unlink(filename); -#else - DeleteFile(filename); -#endif - /* Use open() to avoid people sneaking a new file in under us */ -#ifndef _WIN32 - fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0666); -#else - fd = open(filename, O_WRONLY | O_CREAT | O_EXCL | _O_BINARY, 0666); -#endif - f->fp = fdopen(fd, "wb"); /* will fail and return NULL if fd < 0 */ - if (!f->fp || !write_file_version(f, version)) { - int errno_save = errno; - static int walloped = 0; - if (!walloped) { - walloped++; - ircdproto->SendGlobops(NULL, "Can't write to %s database %s", - service, filename); - } - errno = errno_save; - log_perror("Can't write to %s database %s", service, filename); - if (f->fp) { - fclose(f->fp); -#ifndef _WIN32 - unlink(filename); -#else - DeleteFile(filename); -#endif - } - if (*f->backupname && rename(f->backupname, filename) < 0) - log_perror("Cannot restore backup copy of %s", filename); - - /* Then the Lord said unto Moses, thou shalt free what thou hast malloced - * -- codemastr */ - delete f; - errno = errno_save; - return NULL; - } - return f; -} - -/*************************************************************************/ - -/** - * Open a database file for reading (*mode == 'r') or writing (*mode == 'w'). - * Return the stream pointer, or NULL on error. When opening for write, it - * is an error for rename() to return an error (when backing up the original - * file) other than ENOENT, if NO_BACKUP_OKAY is not defined; it is an error - * if the version number cannot be written to the file; and it is a fatal - * error if opening the file for write fails and the backup was successfully - * made but cannot be restored. - * @param service If error whom to return the error as - * @param filename File to open as the database - * @param mode Mode for writting or reading - * @param version Database Version - * @return dbFile struct - */ -dbFILE *open_db(const char *service, const char *filename, - const char *mode, uint32 version) -{ - if (*mode == 'r') { - return open_db_read(service, filename); - } else if (*mode == 'w') { - return open_db_write(service, filename, version); - } else { - errno = EINVAL; - return NULL; - } -} - -/*************************************************************************/ - -/** - * Restore the database file to its condition before open_db(). This is - * identical to close_db() for files open for reading; however, for files - * open for writing, we first attempt to restore any backup file before - * closing files. - * @param dbFile struct - * @return void - */ -void restore_db(dbFILE * f) -{ - int errno_save = errno; - - if (f->mode == 'w') { - int ok = 0; /* Did we manage to restore the old file? */ - errno = errno_save = 0; - if (*f->backupname && strcmp(f->backupname, f->filename) != 0) { - if (rename(f->backupname, f->filename) == 0) - ok = 1; - } - if (!ok && f->backupfp) { - char buf[1024]; - unsigned int i; - ok = 1; - if (fseek(f->fp, 0, SEEK_SET) < 0) - ok = 0; - while (ok && (i = fread(buf, 1, sizeof(buf), f->backupfp)) > 0) { - if (fwrite(buf, 1, i, f->fp) != i) - ok = 0; - } - if (ok) { - fflush(f->fp); - ftruncate(fileno(f->fp), ftell(f->fp)); - } - } - if (!ok && errno > 0) - log_perror("Unable to restore backup of %s", f->filename); - errno_save = errno; - if (f->backupfp) - fclose(f->backupfp); - if (*f->backupname) -#ifndef _WIN32 - unlink(f->backupname); -#else - DeleteFile(f->backupname); -#endif - } - fclose(f->fp); - if (!errno_save) - errno_save = errno; - delete f; - errno = errno_save; -} - -/*************************************************************************/ - -/** - * Close a database file. If the file was opened for write, remove the - * backup we (may have) created earlier. - * @param dbFile struct - * @return void - */ -void close_db(dbFILE * f) -{ - if (f->mode == 'w' && *f->backupname - && strcmp(f->backupname, f->filename) != 0) { - if (f->backupfp) - fclose(f->backupfp); -#ifndef _WIN32 - unlink(f->backupname); -#else - DeleteFile(f->backupname); -#endif - } - fclose(f->fp); - delete f; -} - -/*************************************************************************/ - -/** - * Read and write 2- and 4-byte quantities, pointers, and strings. All - * multibyte values are stored in big-endian order (most significant byte - * first). A pointer is stored as a byte, either 0 if NULL or 1 if not, - * and read pointers are returned as either (void *)0 or (void *)1. A - * string is stored with a 2-byte unsigned length (including the trailing - * \0) first; a length of 0 indicates that the string pointer is NULL. - * Written strings are truncated silently at 65534 bytes, and are always - * null-terminated. - * - * @param ret 16bit integer to write - * @param dbFile struct - * @return -1 on error, 0 otherwise. - */ -int read_int16(uint16 * ret, dbFILE * f) -{ - int c1, c2; - - c1 = fgetc(f->fp); - c2 = fgetc(f->fp); - if (c1 == EOF || c2 == EOF) - return -1; - *ret = c1 << 8 | c2; - return 0; -} - -/*************************************************************************/ - -/** - * Write a 16bit integer - * - * @param ret 16bit integer to write - * @param dbFile struct - * @return -1 on error, 0 otherwise. - */ -int write_int16(uint16 val, dbFILE * f) -{ - if (fputc((val >> 8) & 0xFF, f->fp) == EOF - || fputc(val & 0xFF, f->fp) == EOF) { - return -1; - } - return 0; -} - -/*************************************************************************/ - -/** - * Read a unsigned 32bit integer - * - * @param ret unsigned 32bit integer to read - * @param dbFile struct - * @return -1 on error, 0 otherwise. - */ -int read_int32(uint32 * ret, dbFILE * f) -{ - int c1, c2, c3, c4; - - c1 = fgetc(f->fp); - c2 = fgetc(f->fp); - c3 = fgetc(f->fp); - c4 = fgetc(f->fp); - if (c1 == EOF || c2 == EOF || c3 == EOF || c4 == EOF) - return -1; - *ret = c1 << 24 | c2 << 16 | c3 << 8 | c4; - return 0; -} - -/*************************************************************************/ - -/** - * Write a unsigned 32bit integer - * - * @param ret unsigned 32bit integer to write - * @param dbFile struct - * @return -1 on error, 0 otherwise. - */ -int write_int32(uint32 val, dbFILE * f) -{ - if (fputc((val >> 24) & 0xFF, f->fp) == EOF) - return -1; - if (fputc((val >> 16) & 0xFF, f->fp) == EOF) - return -1; - if (fputc((val >> 8) & 0xFF, f->fp) == EOF) - return -1; - if (fputc((val) & 0xFF, f->fp) == EOF) - return -1; - return 0; -} - -/*************************************************************************/ - -/** - * Read Pointer - * - * @param ret pointer to read - * @param dbFile struct - * @return -1 on error, 0 otherwise. - */ -int read_ptr(void **ret, dbFILE * f) -{ - int c; - - c = fgetc(f->fp); - if (c == EOF) - return -1; - *ret = (c ? reinterpret_cast<void *>(1) : reinterpret_cast<void *>(0)); - return 0; -} - -/*************************************************************************/ - -/** - * Write Pointer - * - * @param ret pointer to write - * @param dbFile struct - * @return -1 on error, 0 otherwise. - */ -int write_ptr(const void *ptr, dbFILE * f) -{ - if (fputc(ptr ? 1 : 0, f->fp) == EOF) - return -1; - return 0; -} - -/*************************************************************************/ - -/** - * Read String - * - * @param ret string - * @param dbFile struct - * @return -1 on error, 0 otherwise. - */ -int read_string(char **ret, dbFILE * f) -{ - char *s; - uint16 len; - - if (read_int16(&len, f) < 0) - return -1; - if (len == 0) { - *ret = NULL; - return 0; - } - s = new char[len]; - if (len != fread(s, 1, len, f->fp)) { - delete [] s; - return -1; - } - *ret = s; - return 0; -} - -/*************************************************************************/ - -/** - * Write String - * - * @param ret string - * @param dbFile struct - * @return -1 on error, 0 otherwise. - */ -int write_string(const char *s, dbFILE * f) -{ - uint32 len; - - if (!s) - return write_int16(0, f); - len = strlen(s); - if (len > 65534) - len = 65534; - if (write_int16(static_cast<uint16>(len + 1), f) < 0) - return -1; - if (len > 0 && fwrite(s, 1, len, f->fp) != len) - return -1; - if (fputc(0, f->fp) == EOF) - return -1; - return 0; -} - -/*************************************************************************/ - -/** * Renames a database * * @param name Database to name @@ -587,59 +64,31 @@ static void remove_backups() strftime(ext, sizeof(ext), "%Y%m%d", &tm); snprintf(path, sizeof(path), "backups/%s.%s", Config.NickDBName, ext); -#ifndef _WIN32 - unlink(path); -#else DeleteFile(path); -#endif + snprintf(path, sizeof(path), "backups/%s.%s", Config.ChanDBName, ext); -#ifndef _WIN32 - unlink(path); -#else DeleteFile(path); -#endif + snprintf(path, sizeof(path), "backups/%s.%s", Config.OperDBName, ext); -#ifndef _WIN32 - unlink(path); -#else DeleteFile(path); -#endif + snprintf(path, sizeof(path), "backups/%s.%s", Config.NewsDBName, ext); -#ifndef _WIN32 - unlink(path); -#else DeleteFile(path); -#endif + snprintf(path, sizeof(path), "backups/%s.%s", Config.ExceptionDBName, ext); -#ifndef _WIN32 - unlink(path); -#else DeleteFile(path); -#endif if (Config.s_BotServ) { snprintf(path, sizeof(path), "backups/%s.%s", Config.BotDBName, ext); -#ifndef _WIN32 - unlink(path); -#else DeleteFile(path); -#endif } if (Config.s_HostServ) { snprintf(path, sizeof(path), "backups/%s.%s", Config.HostDBName, ext); -#ifndef _WIN32 - unlink(path); -#else DeleteFile(path); -#endif } if (Config.NSEmailReg) { snprintf(path, sizeof(path), "backups/%s.%s", Config.PreNickDBName, ext); -#ifndef _WIN32 - unlink(path); -#else DeleteFile(path); -#endif } } @@ -749,11 +198,7 @@ void ModuleRemoveBackups(const char *dbname) strftime(ext, sizeof(ext), "%Y%m%d", &tm); snprintf(path, sizeof(path), "backups/%s.%s", dbname, ext); -#ifndef _WIN32 - unlink(path); -#else DeleteFile(path); -#endif } /*************************************************************************/ |