diff options
Diffstat (limited to 'storage.c')
-rw-r--r-- | storage.c | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/storage.c b/storage.c new file mode 100644 index 0000000..10bd74a --- /dev/null +++ b/storage.c @@ -0,0 +1,142 @@ +/*************************************************************** -*- c++ -*- + * Copyright (c) 2003,2004 by Marcel Wiesweg * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "storage.h" + +int Storage::doCleanUp() { + DIR *top=opendir(root); + int pagesDeleted=0; + if (top) { + struct dirent *chandir, path; + struct stat chandirstat; + char fullPath[PATH_MAX]; + while ( (!readdir_r(top, &path, &chandir) && chandir != NULL) ) { + if (strcmp(chandir->d_name, "..")==0 || strcmp(chandir->d_name, ".")==0) + continue; + snprintf(fullPath, PATH_MAX, "%s/%s", root, chandir->d_name); + if (stat(fullPath, &chandirstat)==0) { + if (S_ISDIR(chandirstat.st_mode)) { + pagesDeleted+=cleanSubDir(fullPath); + } + } + } + closedir(top); + } else { + esyslog("OSD-Teletext: Error opening teletext storage directory \"%s\": %s", root, strerror(errno)); + } + return pagesDeleted; +} + +int Storage::cleanSubDir(const char *dir) { + static bool reportedError=false; //avoid filling up syslog + DIR *d=opendir(dir); + bool hadError=false; + int bytesDeleted=0; + if (d) { + struct dirent *txtfile, path; + struct stat txtfilestat; + char fullPath[PATH_MAX]; + int filesize; + while ( (!readdir_r(d, &path, &txtfile) && txtfile != NULL) ) { + int len=strlen(txtfile->d_name); + //check that the file end with .vtx to avoid accidents and disasters + if (strcmp(txtfile->d_name+len-4, ".vtx")==0) { + snprintf(fullPath, PATH_MAX, "%s/%s", dir, txtfile->d_name); + stat(fullPath, &txtfilestat); + filesize=actualFileSize(txtfilestat.st_size); + int ret=unlink(fullPath); + if (ret==0) + bytesDeleted+=filesize; + else + hadError=ret; + } + } + closedir(d); + rmdir(dir); + } else { + if (!reportedError) { + esyslog("OSD-Teletext: Error opening teletext storage subdirectory \"%s\": %s", dir, strerror(errno)); + reportedError=true; + } + } + + if (hadError && !reportedError) { + esyslog("OSD-Teletext: Error removing teletext storage subdirectory \"%s\": %s", dir, strerror(hadError)); + reportedError=true; + } + return bytesDeleted; +} + +Storage::Storage() + : byteCount(0), failedFreeSpace(false) +{ +} + +Storage::~Storage() { +} + +void Storage::freeSpace() { + //there might be a situation where only the current directory is left and + //occupies the whole space. We cannot delete anything. Don't waste time scanning. + if (failedFreeSpace) + return; + + //printf("freeSpace()\n"); + time_t min=time(0); + char minDir[PATH_MAX]; + char fullPath[PATH_MAX]; + DIR *top=opendir(getRootDir()); + if (top) { + int haveDir=0; + struct dirent *chandir, path; + struct stat chandirstat; + while ( (!readdir_r(top, &path, &chandir) && chandir != NULL) ) { + if (strcmp(chandir->d_name, "..")==0 || strcmp(chandir->d_name, ".")==0) + continue; + snprintf(fullPath, PATH_MAX, "%s/%s", getRootDir(), chandir->d_name); + if (stat(fullPath, &chandirstat)==0) { + if (S_ISDIR(chandirstat.st_mode)) { + if (chandirstat.st_ctime < min && strcmp(fullPath, currentDir)) { + min=chandirstat.st_ctime; + strcpy(minDir, fullPath); + haveDir++; + } + } + } + } + closedir(top); + + //if haveDir, only current directory present, which must not be deleted + if (haveDir>=2) + byteCount-=cleanSubDir(minDir); + else + failedFreeSpace=true; + } +} + +bool Storage::exists(const char* file) { + struct stat s; + return (stat(file, &s)==0); +} + +void Storage::getFilename(char *buffer, int bufLength, PageID page) { + snprintf(buffer, bufLength, "%s/%s/%03x_%02x.vtx", getRootDir(), + *page.channel.ToString(), page.page, page.subPage); +} + +void Storage::prepareDirectory(tChannelID chan) { + currentDir = cString::sprintf("%s/%s", root, *chan.ToString()); + if (!MakeDirs(currentDir, 1)) { + esyslog("OSD-Teletext: Error preparing directory for channel \"%s\"", + *chan.ToString()); + return; + } + failedFreeSpace=false; +} |