]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/findlib/bfile.c
Win32 BackupRead/Write, begin adding Base, Jmsg knows about console, autochanger...
[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
62    if (!bfd->use_win_api) {
63       bfd->fid = open(fname, flags, mode);
64       if (bfd->fid >= 0) {
65          bfd->mode = BF_READ;         /* not important if BF_READ or BF_WRITE */
66       }
67       return bfd->fid;
68    }
69
70    /* Convert to Windows path format */
71    win32_fname = get_pool_memory(PM_FNAME);
72    unix_name_to_win32(&win32_fname, (char *)fname);
73
74    if (flags & O_WRONLY) {            /* creating */
75       bfd->fh = CreateFile(win32_fname,
76                    FILE_ALL_ACCESS|WRITE_DAC|ACCESS_SYSTEM_SECURITY,    /* access */
77                    0,
78                    NULL,                                   /* SecurityAttributes */
79                    CREATE_ALWAYS,                          /* CreationDisposition */
80                    FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,   /* Flags and attributes */
81                    NULL);                                  /* TemplateFile */
82
83       if (bfd->fh == INVALID_HANDLE_VALUE) {
84          bfd->lerror = GetLastError();
85          bfd->mode = BF_CLOSED;
86       } else {
87          bfd->mode = BF_WRITE;
88       }
89    } else {
90       bfd->fh = CreateFile(win32_fname,
91                    GENERIC_READ|ACCESS_SYSTEM_SECURITY,       /* access */
92                    FILE_SHARE_READ,                         /* shared mode */
93                    NULL,                                   /* SecurityAttributes */
94                    OPEN_EXISTING,                          /* CreationDisposition */
95                    FILE_FLAG_BACKUP_SEMANTICS,  /* Flags and attributes */
96                    NULL);                                  /* TemplateFile */
97
98       if (bfd->fh == INVALID_HANDLE_VALUE) {
99          bfd->lerror = GetLastError();
100          bfd->mode = BF_CLOSED;
101       } else {
102          bfd->mode = BF_READ;
103       }
104    }
105    bfd->errmsg = NULL;
106    bfd->lpContext = NULL;
107    return bfd->mode == BF_CLOSED ? -1 : 1;
108 }
109
110 /* 
111  * Returns  0 on success
112  *         -1 on error
113  */
114 int bclose(BFILE *bfd)
115
116    int stat = 0;
117    if (!bfd->use_win_api) {
118       int stat = close(bfd->fid);
119       bfd->fid = -1;
120       bfd->mode = BF_CLOSED;
121       return stat;
122    }
123    if (bfd->errmsg) {
124       free_pool_memory(bfd->errmsg);
125       bfd->errmsg = NULL;
126    }
127    if (bfd->mode == BF_CLOSED) {
128       return 0;
129    }
130    if (bfd->mode == BF_READ) {
131       BYTE buf[10];
132       if (!bfd->lpContext && !BackupRead(bfd->fh,   
133               buf,                    /* buffer */
134               (DWORD)0,               /* bytes to read */
135               &bfd->rw_bytes,         /* bytes read */
136               1,                      /* Abort */
137               1,                      /* ProcessSecurity */
138               &bfd->lpContext)) {     /* Read context */
139          stat = -1;
140       } 
141    } else {
142       BYTE buf[10];
143       if (!bfd->lpContext && !BackupWrite(bfd->fh,   
144               buf,                    /* buffer */
145               (DWORD)0,               /* bytes to read */
146               &bfd->rw_bytes,         /* bytes written */
147               1,                      /* Abort */
148               1,                      /* ProcessSecurity */
149               &bfd->lpContext)) {     /* Write context */
150          stat = -1;
151       } 
152    }
153    if (!CloseHandle(bfd->fh)) {
154       stat = -1;
155    }
156    bfd->mode = BF_CLOSED;
157    bfd->lpContext = NULL;
158    return stat;
159 }
160
161 /*
162  * Generate error message 
163  */
164 char *berror(BFILE *bfd)
165 {
166    LPTSTR msg;
167
168    if (!bfd->use_win_api) {
169       return strerror(errno);
170    }
171    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|
172                  FORMAT_MESSAGE_FROM_SYSTEM,
173                  NULL,
174                  bfd->lerror,
175                  0,
176                  (LPTSTR)&msg,
177                  0,
178                  NULL);
179    strip_trailing_junk(msg);
180    if (!bfd->errmsg) {
181       bfd->errmsg = get_pool_memory(PM_FNAME);
182    }
183    pm_strcpy(&bfd->errmsg, msg);
184    LocalFree(msg);
185    return bfd->errmsg;
186 }
187
188 /* Returns: bytes read on success
189  *           0         on EOF
190  *          -1         on error
191  */
192 ssize_t bread(BFILE *bfd, void *buf, size_t count)
193 {
194    if (!bfd->use_win_api) {
195       return read(bfd->fid, buf, count);
196    }
197
198    bfd->rw_bytes = 0;
199    if (!BackupRead(bfd->fh, 
200         (BYTE *)buf,
201         count,
202         &bfd->rw_bytes,
203         0,                           /* no Abort */
204         1,                           /* Process Security */
205         &bfd->lpContext)) {          /* Context */
206       bfd->lerror = GetLastError();
207       return -1;
208    }
209    return (ssize_t)bfd->rw_bytes;
210 }
211
212 ssize_t bwrite(BFILE *bfd, void *buf, size_t count)
213 {
214    if (!bfd->use_win_api) {
215       return write(bfd->fid, buf, count);
216    }
217
218    bfd->rw_bytes = 0;
219    if (!BackupWrite(bfd->fh,
220         (BYTE *)buf,
221         count,
222         &bfd->rw_bytes,
223         0,                           /* No abort */
224         1,                           /* Process Security */
225         &bfd->lpContext)) {          /* Context */
226       bfd->lerror = GetLastError();
227       return -1;
228    }
229    return (ssize_t)bfd->rw_bytes;
230 }
231
232 int is_bopen(BFILE *bfd)
233 {
234    return bfd->mode != BF_CLOSED;
235 }
236
237 off_t blseek(BFILE *bfd, off_t offset, int whence)
238 {
239    if (!bfd->use_win_api) {
240       return lseek(bfd->fid, offset, whence);
241    }
242    return -1;
243 }
244
245 #else  /* Unix systems */
246
247 /* ===============================================================
248  * 
249  *            U N I X
250  *
251  * ===============================================================
252  */
253 void binit(BFILE *bfd, int use_win_api)
254 {
255    bfd->fid = -1;
256 }
257
258 int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode)
259 {
260    return bfd->fid = open(fname, flags, mode);
261 }
262
263 int bclose(BFILE *bfd)
264
265    int stat = close(bfd->fid);
266    bfd->fid = -1;
267    return stat;
268 }
269
270 ssize_t bread(BFILE *bfd, void *buf, size_t count)
271 {
272    return read(bfd->fid, buf, count);
273 }
274
275 ssize_t bwrite(BFILE *bfd, void *buf, size_t count)
276 {
277    return write(bfd->fid, buf, count);
278 }
279
280 int is_bopen(BFILE *bfd)
281 {
282    return bfd->fid >= 0;
283 }
284
285 off_t blseek(BFILE *bfd, off_t offset, int whence)
286 {
287    return lseek(bfd->fid, offset, whence);
288 }
289
290 char *berror(BFILE *bfd)
291 {
292     return strerror(errno);
293 }
294
295 #endif