summaryrefslogtreecommitdiff
path: root/apt-pkg/contrib/fileutl.cc
diff options
context:
space:
mode:
Diffstat (limited to 'apt-pkg/contrib/fileutl.cc')
-rw-r--r--apt-pkg/contrib/fileutl.cc214
1 files changed, 214 insertions, 0 deletions
diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc
new file mode 100644
index 000000000..6048ff0bb
--- /dev/null
+++ b/apt-pkg/contrib/fileutl.cc
@@ -0,0 +1,214 @@
+// -*- mode: cpp; mode: fold -*-
+// Description /*{{{*/
+// $Id: fileutl.cc,v 1.1 1998/07/02 02:58:13 jgg Exp $
+/* ######################################################################
+
+ File Utilities
+
+ CopyFile - Buffered copy of a single file
+ GetLock - dpkg compatible lock file manipulation (fcntl)
+
+ This source is placed in the Public Domain, do with it what you will
+ It was originally written by Jason Gunthorpe.
+
+ ##################################################################### */
+ /*}}}*/
+// Include Files /*{{{*/
+#include <fileutl.h>
+#include <pkglib/error.h>
+
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/fcntl.h>
+#include <sys/types.h>
+ /*}}}*/
+
+// CopyFile - Buffered copy of a file /*{{{*/
+// ---------------------------------------------------------------------
+/* The caller is expected to set things so that failure causes erasure */
+bool CopyFile(File From,File To)
+{
+ if (From.IsOpen() == false || To.IsOpen() == false)
+ return false;
+
+ // Buffered copy between fds
+ unsigned char *Buf = new unsigned char[64000];
+ long Size;
+ while ((Size = read(From.Fd(),Buf,64000)) > 0)
+ {
+ if (To.Write(Buf,Size) == false)
+ {
+ delete [] Buf;
+ return false;
+ }
+ }
+
+ delete [] Buf;
+ return true;
+}
+ /*}}}*/
+// GetLock - Gets a lock file /*{{{*/
+// ---------------------------------------------------------------------
+/* This will create an empty file of the given name and lock it. Once this
+ is done all other calls to GetLock in any other process will fail with
+ -1. The return result is the fd of the file, the call should call
+ close at some time. */
+int GetLock(string File,bool Errors)
+{
+ int FD = open(File.c_str(),O_RDWR | O_CREAT | O_TRUNC,0640);
+ if (FD < 0)
+ {
+ if (Errors == true)
+ _error->Errno("open","Could not open lock file %s",File.c_str());
+ return -1;
+ }
+
+ // Aquire a write lock
+ struct flock fl;
+ fl.l_type= F_WRLCK;
+ fl.l_whence= SEEK_SET;
+ fl.l_start= 0;
+ fl.l_len= 1;
+ if (fcntl(FD,F_SETLK,&fl) == -1)
+ {
+ if (Errors == true)
+ _error->Errno("open","Could not get lock %s",File.c_str());
+ close(FD);
+ return -1;
+ }
+
+ return FD;
+}
+ /*}}}*/
+// FileExists - Check if a file exists /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool FileExists(string File)
+{
+ struct stat Buf;
+ if (stat(File.c_str(),&Buf) != 0)
+ return false;
+ return true;
+}
+ /*}}}*/
+// SafeGetCWD - This is a safer getcwd that returns a dynamic string /*{{{*/
+// ---------------------------------------------------------------------
+/* We return / on failure. */
+string SafeGetCWD()
+{
+ // Stash the current dir.
+ char S[300];
+ S[0] = 0;
+ if (getcwd(S,sizeof(S)) == 0)
+ return "/";
+ return S;
+}
+ /*}}}*/
+
+// File::File - Open a file /*{{{*/
+// ---------------------------------------------------------------------
+/* The most commonly used open mode combinations are given with Mode */
+File::File(string FileName,OpenMode Mode, unsigned long Perms)
+{
+ Flags = 0;
+ switch (Mode)
+ {
+ case ReadOnly:
+ iFd = open(FileName.c_str(),O_RDONLY);
+ break;
+
+ case WriteEmpty:
+ unlink(FileName.c_str());
+ iFd = open(FileName.c_str(),O_RDWR | O_CREAT | O_EXCL,Perms);
+ break;
+
+ case WriteExists:
+ iFd = open(FileName.c_str(),O_RDWR);
+ break;
+ }
+
+ if (iFd < 0)
+ _error->Errno("open","Could not open file %s",FileName.c_str());
+ else
+ this->FileName = FileName;
+}
+ /*}}}*/
+// File::~File - Closes the file /*{{{*/
+// ---------------------------------------------------------------------
+/* If the proper modes are selected then we close the Fd and possibly
+ unlink the file on error. */
+File::~File()
+{
+ Close();
+}
+ /*}}}*/
+// File::Read - Read a bit of the file /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool File::Read(void *To,unsigned long Size)
+{
+ if (read(iFd,To,Size) != (signed)Size)
+ {
+ Flags |= Fail;
+ return _error->Errno("read","Read error");
+ }
+
+ return true;
+}
+ /*}}}*/
+// File::Write - Write to the file /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool File::Write(void *From,unsigned long Size)
+{
+ if (write(iFd,From,Size) != (signed)Size)
+ {
+ Flags |= Fail;
+ return _error->Errno("write","Write error");
+ }
+
+ return true;
+}
+ /*}}}*/
+// File::Seek - Seek in the file /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool File::Seek(unsigned long To)
+{
+ if (lseek(iFd,To,SEEK_SET) != (signed)To)
+ {
+ Flags |= Fail;
+ return _error->Error("Unable to seek to %u",To);
+ }
+
+ return true;
+}
+ /*}}}*/
+// File::Size - Return the size of the file /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+unsigned long File::Size()
+{
+ struct stat Buf;
+ if (fstat(iFd,&Buf) != 0)
+ return _error->Errno("fstat","Unable to determine the file size");
+ return Buf.st_size;
+}
+ /*}}}*/
+// File::Close - Close the file if the close flag is set /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool File::Close()
+{
+ bool Res = true;
+ if ((Flags & AutoClose) == AutoClose)
+ if (close(iFd) != 0)
+ Res &= _error->Errno("close","Problem closing the file");
+
+ if ((Flags & Fail) == Fail && (Flags & DelOnFail) == DelOnFail &&
+ FileName.empty() == false)
+ if (unlink(FileName.c_str()) != 0)
+ Res &= _error->Warning("unlnk","Problem unlinking the file");
+ return Res;
+}
+ /*}}}*/