1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 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;
struct stat chandirstat;
char fullPath[PATH_MAX];
while ((chandir = readdir(top)) != 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("osdteletext: 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;
struct stat txtfilestat;
char fullPath[PATH_MAX];
int filesize;
while ((txtfile = readdir(d)) != NULL) {
int len=strlen(txtfile->d_name);
//check that the file end with .vtx5 to avoid accidents and disasters
if (strcmp(txtfile->d_name+len-5, ".vtx5")==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("osdteletext: Error opening teletext storage subdirectory \"%s\": %s", dir, strerror(errno));
reportedError=true;
}
}
if (hadError && !reportedError) {
esyslog("osdteletext: 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;
struct stat chandirstat;
while ((chandir = readdir(top)) != 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.vtx5", 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("osdteletext: Error preparing directory for channel \"%s\"",
*chan.ToString());
return;
}
failedFreeSpace=false;
}
|