diff options
Diffstat (limited to 'lib/file.cc')
-rw-r--r-- | lib/file.cc | 240 |
1 files changed, 240 insertions, 0 deletions
diff --git a/lib/file.cc b/lib/file.cc new file mode 100644 index 0000000..3a59334 --- /dev/null +++ b/lib/file.cc @@ -0,0 +1,240 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + * file.cc + * + * Thu Jun 9 15:31:38 CEST 2005 + * Copyright 2005 Bent Bisballe + * deva@aasimon.org + ****************************************************************************/ + +/* + * This file is part of MIaV. + * + * MIaV 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. + * + * MIaV is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with MIaV; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ +#include <config.h> +#include "file.h" + +#include "miav_config.h" + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <string.h> +#include <unistd.h> + +#include <errno.h> + +// For ntoh* +#include <netinet/in.h> + +#include <stdlib.h> + +File::File(char *fn, char* ext, Info *i) +{ + char path[256]; + + info = i; + + savestate = SAVE; + + filename = new char[strlen(fn) + 1]; + extension = new char[strlen(ext) + 1]; + + strcpy(filename, fn); + strcpy(extension, ext); + + num = 0; + seqnum = 0; + fd = -1; + + int pos = (int)strrchr(filename, '/'); + memset(path, 0, sizeof(path)); + + if(pos) { // pos is NULL, a file will be created in the current dir (Which is bad) + pos -= (int)filename; // Make pos relative to the beginning of the string + strncpy(path, filename, pos); + createPath(path); + } + + Open(); +} + +File::~File() +{ + close(fd); + + info->info("This session contains the following files..."); + for(unsigned int cnt = 0; cnt < filelist.size(); cnt ++) { + info->info("[%s]", filelist[cnt].c_str()); + } + + std::string *trash = config->readString("server_trash"); + std::string *later = config->readString("server_later"); + + switch(savestate) { + case NO_CHANGE: + info->warn("File had no savestate!"); + break; + + case SAVE: + info->info("Files in this session is to be saved."); + break; + + case DELETE: + info->info("Files in this session is to be deleted (moved to trash)."); + Move((char*)trash->c_str()); + break; + + case LATER: + info->info("Files in this session is stored for later decisson."); + Move((char*)later->c_str()); + break; + } + + delete filename; + delete extension; +} + +int File::Move(char *destination) +{ + char newfile[256]; + char filename[256]; + + createPath(destination); + for(unsigned int cnt = 0; cnt < filelist.size(); cnt ++) { + // TODO: Check is the file exists... if not make som noise! + + + // TODO: Move file filelist[cnt] to the destination folder. + strcpy(filename, (char*)filelist[cnt].c_str()); + sprintf(newfile, "%s%s", destination, strrchr(filename, '/')); + if(rename((char*)filelist[cnt].c_str(), newfile) == -1) + info->error("Error moving file %s to %s:", + (char*)filelist[cnt].c_str(), + newfile, + strerror(errno)); + } + return 0; +} + +int File::Open() +{ + char fname[256]; + + if(fd != -1) { + close(fd); + fd = -1; + } + + while(fd == -1) { + if(seqnum) { + // A sequence number > 0 + sprintf(fname, "%s%.3d-%d.%s", filename, num, seqnum, extension); + } else { + // A sequence number of 0 + sprintf(fname, "%s%.3d.%s", filename, num, extension); + } + fd = open(fname, O_CREAT | O_WRONLY | O_ASYNC | O_EXCL, //| O_LARGEFILE + S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + if(fd == -1) num ++; + + // If more than 100 files are created in one day, something is terribly wrong! + if(num > 100) { + info->error("Something is wrong with the path [%s]!", fname); + exit(1); + } + + } + + std::string filename_string(fname); + filelist.push_back(filename_string); + + seqnum ++; + + info->info("Output file: %s", fname); + + return 0; +} + +int File::Write(void* data, int size) +{ + int w; + + w = write(fd, data, size); + + if(w != size) { + info->info("Wrapping file."); + Open(); + w = write(fd, data, size); + if(w != size) { + info->error("Out of diskspace!"); + return -1; + } + } + + return w; +} + +int File::createPath(char* path) +{ + // struct stat stats; + char *subpath; + + subpath = (char*)calloc(strlen(path) + 1, 1); + + strcpy(subpath, path); + + subpath[strrchr(subpath, '/') - subpath] = '\0'; + + if(strlen(subpath) > 0) createPath(subpath); + + info->info("Checking and/or generating directory: %s", path); + + // stat(path, &stats); + //if(!S_ISDIR(stats.st_mode) && S_ISREG(stats.st_mode)) + mkdir(path, S_IRWXU | S_IRGRP | S_IXGRP | S_IXOTH | S_IROTH); + // TODO: Check for creation errors! + + free(subpath); + + return 0; +} + +void File::setSaveState(n_savestate s) +{ + savestate = s; + info->info("SETTING SAVESTATE TO: %d", savestate); +} + +#ifdef __TEST_FILE +#include "info_simple.h" + +int main(int argc, char *argv[]) { + if(argc < 3) { + fprintf(stderr, "usage:\n\ttest_file [filename] [extension]\n"); + return 1; + } + + + InfoSimple info; + File file(argv[1], argv[2], &info); + + unsigned int val = 0x01234567; + file.Write(val); + +} + +#endif/* __TEST_FILE*/ |