]> git.saurik.com Git - apt.git/blame - apt-pkg/contrib/fileutl.cc
Sync
[apt.git] / apt-pkg / contrib / fileutl.cc
CommitLineData
578bfd0a
AL
1// -*- mode: cpp; mode: fold -*-
2// Description /*{{{*/
8ce4327b 3// $Id: fileutl.cc,v 1.7 1998/08/26 04:52:26 jgg Exp $
578bfd0a
AL
4/* ######################################################################
5
6 File Utilities
7
8 CopyFile - Buffered copy of a single file
9 GetLock - dpkg compatible lock file manipulation (fcntl)
10
11 This source is placed in the Public Domain, do with it what you will
12 It was originally written by Jason Gunthorpe.
13
14 ##################################################################### */
15 /*}}}*/
16// Include Files /*{{{*/
6c139d6e 17#ifdef __GNUG__
094a497d 18#pragma implementation "apt-pkg/fileutl.h"
6c139d6e 19#endif
094a497d
AL
20#include <apt-pkg/fileutl.h>
21#include <apt-pkg/error.h>
578bfd0a
AL
22
23#include <unistd.h>
24#include <sys/stat.h>
25#include <sys/fcntl.h>
26#include <sys/types.h>
27 /*}}}*/
28
29// CopyFile - Buffered copy of a file /*{{{*/
30// ---------------------------------------------------------------------
31/* The caller is expected to set things so that failure causes erasure */
8e06abb2 32bool CopyFile(FileFd From,FileFd To)
578bfd0a
AL
33{
34 if (From.IsOpen() == false || To.IsOpen() == false)
35 return false;
36
37 // Buffered copy between fds
38 unsigned char *Buf = new unsigned char[64000];
39 long Size;
40 while ((Size = read(From.Fd(),Buf,64000)) > 0)
41 {
42 if (To.Write(Buf,Size) == false)
43 {
44 delete [] Buf;
45 return false;
46 }
47 }
48
49 delete [] Buf;
50 return true;
51}
52 /*}}}*/
53// GetLock - Gets a lock file /*{{{*/
54// ---------------------------------------------------------------------
55/* This will create an empty file of the given name and lock it. Once this
56 is done all other calls to GetLock in any other process will fail with
57 -1. The return result is the fd of the file, the call should call
58 close at some time. */
59int GetLock(string File,bool Errors)
60{
61 int FD = open(File.c_str(),O_RDWR | O_CREAT | O_TRUNC,0640);
62 if (FD < 0)
63 {
64 if (Errors == true)
65 _error->Errno("open","Could not open lock file %s",File.c_str());
66 return -1;
67 }
68
69 // Aquire a write lock
70 struct flock fl;
71 fl.l_type= F_WRLCK;
72 fl.l_whence= SEEK_SET;
73 fl.l_start= 0;
74 fl.l_len= 1;
75 if (fcntl(FD,F_SETLK,&fl) == -1)
76 {
77 if (Errors == true)
78 _error->Errno("open","Could not get lock %s",File.c_str());
79 close(FD);
80 return -1;
81 }
82
83 return FD;
84}
85 /*}}}*/
86// FileExists - Check if a file exists /*{{{*/
87// ---------------------------------------------------------------------
88/* */
89bool FileExists(string File)
90{
91 struct stat Buf;
92 if (stat(File.c_str(),&Buf) != 0)
93 return false;
94 return true;
95}
96 /*}}}*/
97// SafeGetCWD - This is a safer getcwd that returns a dynamic string /*{{{*/
98// ---------------------------------------------------------------------
99/* We return / on failure. */
100string SafeGetCWD()
101{
102 // Stash the current dir.
103 char S[300];
104 S[0] = 0;
105 if (getcwd(S,sizeof(S)) == 0)
106 return "/";
107 return S;
108}
109 /*}}}*/
8ce4327b
AL
110// flNotDir - Strip the directory from the filename /*{{{*/
111// ---------------------------------------------------------------------
112/* */
113string flNotDir(string File)
114{
115 string::size_type Res = File.rfind('/');
116 if (Res == string::npos)
117 return File;
118 Res++;
119 return string(File,Res,Res - File.length());
120}
121 /*}}}*/
578bfd0a 122
8e06abb2 123// FileFd::FileFd - Open a file /*{{{*/
578bfd0a
AL
124// ---------------------------------------------------------------------
125/* The most commonly used open mode combinations are given with Mode */
8e06abb2 126FileFd::FileFd(string FileName,OpenMode Mode, unsigned long Perms)
578bfd0a 127{
1164783d 128 Flags = AutoClose;
578bfd0a
AL
129 switch (Mode)
130 {
131 case ReadOnly:
132 iFd = open(FileName.c_str(),O_RDONLY);
133 break;
134
135 case WriteEmpty:
136 unlink(FileName.c_str());
137 iFd = open(FileName.c_str(),O_RDWR | O_CREAT | O_EXCL,Perms);
138 break;
139
140 case WriteExists:
141 iFd = open(FileName.c_str(),O_RDWR);
142 break;
8e06abb2
AL
143
144 // Dont use this in public directories
145 case LockEmpty:
146 iFd = open(FileName.c_str(),O_RDWR | O_CREAT | O_TRUNC,Perms);
147 break;
578bfd0a
AL
148 }
149
150 if (iFd < 0)
151 _error->Errno("open","Could not open file %s",FileName.c_str());
152 else
153 this->FileName = FileName;
154}
155 /*}}}*/
8e06abb2 156// FileFd::~File - Closes the file /*{{{*/
578bfd0a
AL
157// ---------------------------------------------------------------------
158/* If the proper modes are selected then we close the Fd and possibly
159 unlink the file on error. */
8e06abb2 160FileFd::~FileFd()
578bfd0a
AL
161{
162 Close();
163}
164 /*}}}*/
8e06abb2 165// FileFd::Read - Read a bit of the file /*{{{*/
578bfd0a
AL
166// ---------------------------------------------------------------------
167/* */
8e06abb2 168bool FileFd::Read(void *To,unsigned long Size)
578bfd0a
AL
169{
170 if (read(iFd,To,Size) != (signed)Size)
171 {
172 Flags |= Fail;
173 return _error->Errno("read","Read error");
174 }
175
176 return true;
177}
178 /*}}}*/
8e06abb2 179// FileFd::Write - Write to the file /*{{{*/
578bfd0a
AL
180// ---------------------------------------------------------------------
181/* */
8e06abb2 182bool FileFd::Write(void *From,unsigned long Size)
578bfd0a
AL
183{
184 if (write(iFd,From,Size) != (signed)Size)
185 {
186 Flags |= Fail;
187 return _error->Errno("write","Write error");
188 }
189
190 return true;
191}
192 /*}}}*/
8e06abb2 193// FileFd::Seek - Seek in the file /*{{{*/
578bfd0a
AL
194// ---------------------------------------------------------------------
195/* */
8e06abb2 196bool FileFd::Seek(unsigned long To)
578bfd0a
AL
197{
198 if (lseek(iFd,To,SEEK_SET) != (signed)To)
199 {
200 Flags |= Fail;
201 return _error->Error("Unable to seek to %u",To);
202 }
203
204 return true;
205}
206 /*}}}*/
8e06abb2 207// FileFd::Size - Return the size of the file /*{{{*/
578bfd0a
AL
208// ---------------------------------------------------------------------
209/* */
8e06abb2 210unsigned long FileFd::Size()
578bfd0a
AL
211{
212 struct stat Buf;
213 if (fstat(iFd,&Buf) != 0)
214 return _error->Errno("fstat","Unable to determine the file size");
215 return Buf.st_size;
216}
217 /*}}}*/
8e06abb2 218// FileFd::Close - Close the file if the close flag is set /*{{{*/
578bfd0a
AL
219// ---------------------------------------------------------------------
220/* */
8e06abb2 221bool FileFd::Close()
578bfd0a
AL
222{
223 bool Res = true;
224 if ((Flags & AutoClose) == AutoClose)
1164783d 225 if (iFd >= 0 && close(iFd) != 0)
578bfd0a 226 Res &= _error->Errno("close","Problem closing the file");
1164783d
AL
227 iFd = -1;
228
578bfd0a
AL
229 if ((Flags & Fail) == Fail && (Flags & DelOnFail) == DelOnFail &&
230 FileName.empty() == false)
231 if (unlink(FileName.c_str()) != 0)
232 Res &= _error->Warning("unlnk","Problem unlinking the file");
233 return Res;
234}
235 /*}}}*/