]> git.saurik.com Git - apt.git/blame - apt-pkg/contrib/fileutl.cc
DumpAvail works and apt-cache is complete
[apt.git] / apt-pkg / contrib / fileutl.cc
CommitLineData
578bfd0a
AL
1// -*- mode: cpp; mode: fold -*-
2// Description /*{{{*/
1164783d 3// $Id: fileutl.cc,v 1.5 1998/07/15 05:56:43 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 */
32bool CopyFile(File From,File To)
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 /*}}}*/
110
111// File::File - Open a file /*{{{*/
112// ---------------------------------------------------------------------
113/* The most commonly used open mode combinations are given with Mode */
114File::File(string FileName,OpenMode Mode, unsigned long Perms)
115{
1164783d 116 Flags = AutoClose;
578bfd0a
AL
117 switch (Mode)
118 {
119 case ReadOnly:
120 iFd = open(FileName.c_str(),O_RDONLY);
121 break;
122
123 case WriteEmpty:
124 unlink(FileName.c_str());
125 iFd = open(FileName.c_str(),O_RDWR | O_CREAT | O_EXCL,Perms);
126 break;
127
128 case WriteExists:
129 iFd = open(FileName.c_str(),O_RDWR);
130 break;
131 }
132
133 if (iFd < 0)
134 _error->Errno("open","Could not open file %s",FileName.c_str());
135 else
136 this->FileName = FileName;
137}
138 /*}}}*/
139// File::~File - Closes the file /*{{{*/
140// ---------------------------------------------------------------------
141/* If the proper modes are selected then we close the Fd and possibly
142 unlink the file on error. */
143File::~File()
144{
145 Close();
146}
147 /*}}}*/
148// File::Read - Read a bit of the file /*{{{*/
149// ---------------------------------------------------------------------
150/* */
151bool File::Read(void *To,unsigned long Size)
152{
153 if (read(iFd,To,Size) != (signed)Size)
154 {
155 Flags |= Fail;
156 return _error->Errno("read","Read error");
157 }
158
159 return true;
160}
161 /*}}}*/
162// File::Write - Write to the file /*{{{*/
163// ---------------------------------------------------------------------
164/* */
165bool File::Write(void *From,unsigned long Size)
166{
167 if (write(iFd,From,Size) != (signed)Size)
168 {
169 Flags |= Fail;
170 return _error->Errno("write","Write error");
171 }
172
173 return true;
174}
175 /*}}}*/
176// File::Seek - Seek in the file /*{{{*/
177// ---------------------------------------------------------------------
178/* */
179bool File::Seek(unsigned long To)
180{
181 if (lseek(iFd,To,SEEK_SET) != (signed)To)
182 {
183 Flags |= Fail;
184 return _error->Error("Unable to seek to %u",To);
185 }
186
187 return true;
188}
189 /*}}}*/
190// File::Size - Return the size of the file /*{{{*/
191// ---------------------------------------------------------------------
192/* */
193unsigned long File::Size()
194{
195 struct stat Buf;
196 if (fstat(iFd,&Buf) != 0)
197 return _error->Errno("fstat","Unable to determine the file size");
198 return Buf.st_size;
199}
200 /*}}}*/
201// File::Close - Close the file if the close flag is set /*{{{*/
202// ---------------------------------------------------------------------
203/* */
204bool File::Close()
205{
206 bool Res = true;
207 if ((Flags & AutoClose) == AutoClose)
1164783d 208 if (iFd >= 0 && close(iFd) != 0)
578bfd0a 209 Res &= _error->Errno("close","Problem closing the file");
1164783d
AL
210 iFd = -1;
211
578bfd0a
AL
212 if ((Flags & Fail) == Fail && (Flags & DelOnFail) == DelOnFail &&
213 FileName.empty() == false)
214 if (unlink(FileName.c_str()) != 0)
215 Res &= _error->Warning("unlnk","Problem unlinking the file");
216 return Res;
217}
218 /*}}}*/