/* -*- 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 #include "file.h" #include #include #include #include #include // For ntoh* #include #include File::File(char *fn, char* ext, Info *i) { char path[256]; info = i; 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); delete filename; delete extension; } int File::Open() { char fname[256]; if(fd) 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 1000 files are created in one day, something is terribly wrong! if(num > 1000) { info->error("Something is wrong with the path [%s]!", fname); exit(1); } } 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::Write(char* data, int size) { return Write((void*)data, size); } int File::Write(unsigned long long int val) { int res; int written = 0; unsigned long int *h_u = (unsigned long int *)&val; unsigned long int *h_l = (unsigned long int *)(((char*)&val) + sizeof(unsigned long int)); *h_u = htonl(*h_u); *h_l = htonl(*h_l); if((res = Write((void*)h_l, sizeof(*h_l))) < 0) { return res; } written += res; if((res = Write((void*)h_u, sizeof(*h_u))) < 0) { return res; } written += res; return written; } int File::Write(long long int val) { int res; int written = 0; unsigned long int *h_u = (unsigned long int *)&val; unsigned long int *h_l = (unsigned long int *)(((char*)&val) + sizeof(unsigned long int)); *h_u = htonl(*h_u); *h_l = htonl(*h_l); if((res = Write((void*)h_l, sizeof(*h_l))) < 0) { return res; } written += res; if((res = Write((void*)h_u, sizeof(*h_u))) < 0) { return res; } written += res; return written; } int File::Write(long int val) { val = htonl(val); return Write((char*)&val, sizeof(val)); } int File::Write(unsigned long int val) { val = htonl(val); return Write((char*)&val, sizeof(val)); } int File::Write(int val) { val = htonl(val); return Write((char*)&val, sizeof(val)); } int File::Write(unsigned int val) { val = htonl(val); return Write((char*)&val, sizeof(val)); } int File::Write(short int val) { val = htons(val); return Write((char*)&val, sizeof(val)); } int File::Write(unsigned short int val) { val = htons(val); return Write((char*)&val, sizeof(val)); } 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; } #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*/