summaryrefslogtreecommitdiff
path: root/storage.c
diff options
context:
space:
mode:
Diffstat (limited to 'storage.c')
-rw-r--r--storage.c142
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;
+}