diff options
Diffstat (limited to 'genindex/file.c')
-rw-r--r-- | genindex/file.c | 270 |
1 files changed, 270 insertions, 0 deletions
diff --git a/genindex/file.c b/genindex/file.c new file mode 100644 index 0000000..12abbf1 --- /dev/null +++ b/genindex/file.c @@ -0,0 +1,270 @@ +/* + * A VDR index file generator (C++) + * + * (C) 2003-2006 Stefan Huelswitt <s.huelswitt@gmx.de> + * + * This code 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. + * + * This code 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * Or, point your browser to http://www.gnu.org/copyleft/gpl.html + */ + +#define _LARGEFILE64_SOURCE + +#include <stdlib.h> +#include <stdio.h> +#include <stdarg.h> +#include <unistd.h> +#include <errno.h> +#include <fcntl.h> +#include <string.h> +#include <sys/stat.h> + +#include "file.h" + +#define INDEX "index.vdr" +#define INDEX_ALT "index.vdr.generated" +#define FILENAME "%03d.vdr" + +extern bool quiet; + +// --- cString --------------------------------------------------------------- + +/* RF using tools.h now +class cString { +private: + char *s; +public: + cString(const char *S = NULL, bool TakePointer = false); + cString(const cString &String); + virtual ~cString(); + operator const char * () const { return s; } // for use in (const char *) context + const char * operator*() const { return s; } // for use in (const void *) context (printf() etc.) + cString &operator=(const cString &String); + static cString sprintf(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); + }; +*/ + +cString::cString(const char *S, bool TakePointer) +{ + s = TakePointer ? (char *)S : S ? strdup(S) : NULL; +} + +cString::cString(const cString &String) +{ + s = String.s ? strdup(String.s) : NULL; +} + +cString::~cString() +{ + free(s); +} + +cString &cString::operator=(const cString &String) +{ + if (this == &String) + return *this; + free(s); + s = String.s ? strdup(String.s) : NULL; + return *this; +} + +// vdr tools.c +cString &cString::operator=(const char *String) +{ + if (s == String) + return *this; + free(s); + s = String ? strdup(String) : NULL; + return *this; +} + +cString cString::sprintf(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + char *buffer; + vasprintf(&buffer, fmt, ap); + return cString(buffer, true); +} + +// ----------------------------------------------------------------------------- + +cString AddDirectory(const char *DirName, const char *FileName) +{ + char *buf; + asprintf(&buf, "%s/%s", DirName && *DirName ? DirName : ".", FileName); + return cString(buf, true); +} + +// --- cIndex ------------------------------------------------------------------ + +cIndex::cIndex(const char *Dir) +{ + dir=Dir; f=0; +} + +cIndex::~cIndex() +{ + if(f) fclose(f); +} + +bool cIndex::Open(bool Read) +{ + int r; + cString name=AddDirectory(dir,INDEX); + r=access(name,F_OK); + read=Read; + if(!Read) { + if(r==0) { + if(!quiet) printf("There is an existing index file. Trying alternative filename.\n"); + name=AddDirectory(dir,INDEX_ALT); + r=access(name,F_OK); + if(r==0) printf("Alternative index file exists too. Aborting.\n"); + } + if(r<0) { + if(errno==ENOENT) { + f=fopen(name,"w"); + if(f) return true; + else printf("index file open: %s\n",strerror(errno)); + } + else printf("index file check: %s\n",strerror(errno)); + } + } + else { + if(r==0) { + f=fopen(name,"r"); + if(f) return true; + else printf("index file open: %s\n",strerror(errno)); + } + else printf("index file check: %s\n",strerror(errno)); + } + return false; +} + +bool cIndex::Write(int fileNr, int fileOff, int picType) +{ + if(f && !read) { + struct tIndex in; + in.offset=fileOff; + in.number=fileNr; + in.type=picType; + in.reserved=0; + if(fwrite(&in,sizeof(in),1,f)==1) return true; + else printf("index write failed\n"); + } + else printf("internal: no open write index file\n"); + return false; +} + +bool cIndex::Read(int &fileNr, int &fileOff) +{ + if(f && read) { + struct tIndex in; + if(fread(&in,sizeof(in),1,f)==1) { + fileOff=in.offset; + fileNr=in.number; + return true; + } + else if(!feof(f)) printf("index read failed\n"); + } + else printf("internal: no open read index file\n"); + return false; +} + +// --- cFileName --------------------------------------------------------------- + +cFileName::cFileName(const char *Input, bool LargeOK) +{ + input=Input; largeOK=LargeOK; + fd=-1; + fileno=1; +} + +cFileName::~cFileName() +{ + close(fd); +} + +int cFileName::Open(void) +{ + close(fd); fd=-1; + cString filename; + if(input) filename=input; + else filename=cString::sprintf(FILENAME,fileno); + fd=open64(filename,O_RDONLY); + if(fd>=0) { + struct stat64 st; + if(fstat64(fd,&st)==0) { + if(!(st.st_size>>31) || largeOK) { + size=st.st_size; + if(!quiet) printf("reading from %s \n",*filename); + } + else { + printf("%s: filesize exceeds 2GB limit\n",*filename); + close(fd); fd=-1; + } + } + else { + printf("fstat: %s\n",strerror(errno)); + close(fd); fd=-1; + } + } + else if(fileno==1 || errno!=ENOENT) + printf("open %s: %s\n",*filename,strerror(errno)); + return fd; +} + +int cFileName::OpenWrite(void) +{ + close(fd); fd=-1; + cString filename=AddDirectory(input,cString::sprintf(FILENAME,fileno)); + if(access(filename,F_OK)!=0) { + fd=open64(filename,O_RDWR|O_CREAT,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); + if(fd>=0) { + size=0; + if(!quiet) printf("writing to %s \n",*filename); + } + else printf("open %s: %s\n",*filename,strerror(errno)); + } + else printf("%s: file already exists\n",*filename); + return fd; +} + +int cFileName::NextFile(void) +{ + if(!input) { + fileno++; + return Open(); + } + return -1; +} + +int cFileName::NextWriteFile(void) +{ + fileno++; + return OpenWrite(); +} + +int cFileName::Skip(int nr, int off) +{ + if(fileno!=nr || fd<0) { + fileno=nr; + if(Open()<0) return -1; + } + if(lseek(fd,off,SEEK_SET)<0) { + printf("seek: %s\n",strerror(errno)); + return -1; + } + return fd; +} |