/* -*- 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 "file.h" #include "configuration.h" #include "info.h" #include #include #include #include #include #include // For ntoh* #include #include File::File(const char *fn, const char* ext) { char path[256]; 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); MIaV::info->info("This session contains the following files..."); for(unsigned int cnt = 0; cnt < filelist.size(); cnt ++) { MIaV::info->info("[%s]", filelist[cnt].c_str()); } // std::string *trash = MIaV::config->readString("server_trash"); // std::string *later = MIaV::config->readString("server_later"); std::string trash; if(MIaV::config->get("server_trash", &trash)) MIaV::info->error("Could not read [server_trash] symbol from config file."); std::string later; if(MIaV::config->get("server_later", &later)) MIaV::info->error("Could not read [server_later] symbol from config file."); switch(savestate) { case NO_CHANGE: MIaV::info->warn("File had no savestate!"); break; case SAVE: MIaV::info->info("Files in this session is to be saved."); break; case DELETE: MIaV::info->info("Files in this session is to be deleted (moved to trash)."); Move((char*)trash.c_str()); break; case LATER: MIaV::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) MIaV::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) { MIaV::info->error("Something is wrong with the path [%s]!", fname); exit(1); } } std::string filename_string(fname); filelist.push_back(filename_string); seqnum ++; MIaV::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) { MIaV::info->info("Wrapping file."); Open(); w = write(fd, data, size); if(w != size) { MIaV::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); MIaV::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; MIaV::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*/