]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/findlib/bfile.c
Home page change. Tweak to Win32 Backup API
[bacula/bacula] / bacula / src / findlib / bfile.c
1 /*
2  *  Bacula low level File I/O routines.  This routine simulates
3  *    open(), read(), write(), and close(), but using native routines.
4  *    I.e. on Windows, we use Windows APIs.
5  *
6  *    Kern Sibbald, April MMIII
7  *
8  *   Version $Id$
9  *
10  */
11 /*
12    Copyright (C) 2000-2003 Kern Sibbald and John Walker
13
14    This program is free software; you can redistribute it and/or
15    modify it under the terms of the GNU General Public License as
16    published by the Free Software Foundation; either version 2 of
17    the License, or (at your option) any later version.
18
19    This program is distributed in the hope that it will be useful,
20    but WITHOUT ANY WARRANTY; without even the implied warranty of
21    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22    General Public License for more details.
23
24    You should have received a copy of the GNU General Public
25    License along with this program; if not, write to the Free
26    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
27    MA 02111-1307, USA.
28
29  */
30
31 #include "bacula.h"
32 #include "find.h"
33
34 #ifdef HAVE_CYGWIN
35
36 void unix_name_to_win32(POOLMEM **win32_name, char *name);
37 extern "C" HANDLE get_osfhandle(int fd);
38
39
40 void binit(BFILE *bfd, int use_win_api)
41 {
42    bfd->fid = -1;
43    bfd->mode = BF_CLOSED;
44    bfd->use_win_api = use_win_api;
45    bfd->errmsg = NULL;
46    bfd->lpContext = NULL;
47    bfd->lerror = 0;
48 }
49
50 HANDLE bget_handle(BFILE *bfd)
51 {
52    if (!bfd->use_win_api) {
53       return get_osfhandle(bfd->fid);
54    }
55    return bfd->fh;
56 }
57
58 int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode)
59 {
60    POOLMEM *win32_fname;
61    if (!bfd->use_win_api) {
62       bfd->fid = open(fname, flags, mode);
63       if (bfd->fid >= 0) {
64          bfd->mode = BF_READ;         /* not important if BF_READ or BF_WRITE */
65       }
66       return bfd->fid;
67    }
68
69    /* Convert to Windows path format */
70    win32_fname = get_pool_memory(PM_FNAME);
71    unix_name_to_win32(&win32_fname, (char *)fname);
72
73    if (flags & O_WRONLY) {            /* creating */
74       bfd->fh = CreateFile(win32_fname,
75                    WRITE_OWNER|WRITE_DAC|ACCESS_SYSTEM_SECURITY,    /* access */
76                    FILE_SHARE_READ | FILE_SHARE_WRITE,     /* shared mode */
77                    NULL,                                   /* SecurityAttributes */
78                    CREATE_ALWAYS,                          /* CreationDisposition */
79                    FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,   /* Flags and attributes */
80                    NULL);                                  /* TemplateFile */
81
82       if (bfd->fh == INVALID_HANDLE_VALUE) {
83          bfd->lerror = GetLastError();
84          bfd->mode = BF_CLOSED;
85       } else {
86          bfd->mode = BF_WRITE;
87       }
88    } else {
89       bfd->fh = CreateFile(win32_fname,
90                    READ_CONTROL|ACCESS_SYSTEM_SECURITY,    /* access */
91                    FILE_SHARE_READ | FILE_SHARE_WRITE,     /* shared mode */
92                    NULL,                                   /* SecurityAttributes */
93                    OPEN_EXISTING,                          /* CreationDisposition */
94                    FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,  /* Flags and attributes */
95                    NULL);                                  /* TemplateFile */
96
97       if (bfd->fh == INVALID_HANDLE_VALUE) {
98          bfd->lerror = GetLastError();
99          bfd->mode = BF_CLOSED;
100       } else {
101          bfd->mode = BF_READ;
102       }
103    }
104    bfd->errmsg = NULL;
105    bfd->lpContext = NULL;
106    return bfd->mode == BF_CLOSED ? -1 : 1;
107 }
108
109 /* 
110  * Returns  0 on success
111  *         -1 on error
112  */
113 int bclose(BFILE *bfd)
114
115    int stat = 0;
116    if (!bfd->use_win_api) {
117       int stat = close(bfd->fid);
118       bfd->fid = -1;
119       bfd->mode = BF_CLOSED;
120       return stat;
121    }
122    if (bfd->errmsg) {
123       free_pool_memory(bfd->errmsg);
124       bfd->errmsg = NULL;
125    }
126    if (bfd->mode == BF_CLOSED) {
127       return 0;
128    }
129    if (bfd->mode == BF_READ) {
130       BYTE buf[10];
131       if (!bfd->lpContext && !BackupRead(bfd->fh,   
132               buf,                    /* buffer */
133               (DWORD)0,               /* bytes to read */
134               &bfd->rw_bytes,         /* bytes read */
135               1,                      /* Abort */
136               1,                      /* ProcessSecurity */
137               &bfd->lpContext)) {     /* Read context */
138          stat = -1;
139       } 
140    } else {
141       BYTE buf[10];
142       if (!bfd->lpContext && !BackupWrite(bfd->fh,   
143               buf,                    /* buffer */
144               (DWORD)0,               /* bytes to read */
145               &bfd->rw_bytes,         /* bytes written */
146               1,                      /* Abort */
147               1,                      /* ProcessSecurity */
148               &bfd->lpContext)) {     /* Write context */
149          stat = -1;
150       } 
151    }
152    if (!CloseHandle(bfd->fh)) {
153       stat = -1;
154    }
155    bfd->mode = BF_CLOSED;
156    bfd->lpContext = NULL;
157    return stat;
158 }
159
160 /*
161  * Generate error message 
162  */
163 char *berror(BFILE *bfd)
164 {
165    LPTSTR msg;
166
167    if (!bfd->use_win_api) {
168       return strerror(errno);
169    }
170    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|
171                  FORMAT_MESSAGE_FROM_SYSTEM,
172                  NULL,
173                  bfd->lerror,
174                  0,
175                  (LPTSTR)&msg,
176                  0,
177                  NULL);
178    strip_trailing_junk(msg);
179    if (!bfd->errmsg) {
180       bfd->errmsg = get_pool_memory(PM_FNAME);
181    }
182    pm_strcpy(&bfd->errmsg, msg);
183    LocalFree(msg);
184    return bfd->errmsg;
185 }
186
187 /* Returns: bytes read on success
188  *           0         on EOF
189  *          -1         on error
190  */
191 ssize_t bread(BFILE *bfd, void *buf, size_t count)
192 {
193    if (!bfd->use_win_api) {
194       return read(bfd->fid, buf, count);
195    }
196
197    bfd->rw_bytes = 0;
198    BackupRead(bfd->fh, 
199          (BYTE *)buf,
200          count,
201          &bfd->rw_bytes,
202          0,                           /* no Abort */
203          1,                           /* Process Security */
204          &bfd->lpContext);            /* Context */
205    if (bfd->rw_bytes > 0) {
206       return (ssize_t)bfd->rw_bytes;
207    }
208    bfd->lerror = GetLastError();
209    return bfd->lerror == 0 ? 0 : -1;
210 }
211
212 ssize_t bwrite(BFILE *bfd, void *buf, size_t count)
213 {
214    DWORD bytes_written = 0;
215    if (!bfd->use_win_api) {
216       return write(bfd->fid, buf, count);
217    }
218    BackupWrite(bfd->fh,
219          (BYTE *)buf,
220          count,
221          &bytes_written,
222          0,                           /* No abort */
223          1,                           /* Process Security */
224          &bfd->lpContext);            /* Context */
225
226    if ((size_t)bfd->rw_bytes == count) {
227       return (ssize_t)bfd->rw_bytes;
228    }
229    bfd->lerror = GetLastError();
230    return bfd->lerror == 0 ? (ssize_t)bfd->rw_bytes : -1;
231 }
232
233 int is_bopen(BFILE *bfd)
234 {
235    return bfd->mode != BF_CLOSED;
236 }
237
238 off_t blseek(BFILE *bfd, off_t offset, int whence)
239 {
240    if (!bfd->use_win_api) {
241       return lseek(bfd->fid, offset, whence);
242    }
243    return -1;
244 }
245
246 #else  /* Unix systems */
247
248 /* ===============================================================
249  * 
250  *            U N I X
251  *
252  * ===============================================================
253  */
254 void binit(BFILE *bfd, int use_win_api)
255 {
256    bfd->fid = -1;
257 }
258
259 int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode)
260 {
261    return bfd->fid = open(fname, flags, mode);
262 }
263
264 int bclose(BFILE *bfd)
265
266    int stat = close(bfd->fid);
267    bfd->fid = -1;
268    return stat;
269 }
270
271 ssize_t bread(BFILE *bfd, void *buf, size_t count)
272 {
273    return read(bfd->fid, buf, count);
274 }
275
276 ssize_t bwrite(BFILE *bfd, void *buf, size_t count)
277 {
278    return write(bfd->fid, buf, count);
279 }
280
281 int is_bopen(BFILE *bfd)
282 {
283    return bfd->fid >= 0;
284 }
285
286 off_t blseek(BFILE *bfd, off_t offset, int whence)
287 {
288    return lseek(bfd->fid, offset, whence);
289 }
290
291 char *berror(BFILE *bfd)
292 {
293     return strerror(errno);
294 }
295
296 #endif