]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/findlib/bfile.c
Use rentrant mysql lib, eliminate race in sql_list, Win32 streams, misc see kes-1.31
[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)
41 {
42    bfd->fid = -1;
43    bfd->mode = BF_CLOSED;
44    bfd->use_win_api = 1;
45    bfd->use_backup_api = p_BackupRead && p_BackupWrite;
46    bfd->errmsg = NULL;
47    bfd->lpContext = NULL;
48    bfd->lerror = 0;
49 }
50
51 /*
52  * Enables/disables using the Backup API (win32_data).
53  *   Returns 1 if function worked
54  *   Returns 0 if failed (i.e. do not have Backup API on this machine)
55  */
56 int set_win32_data(BFILE *bfd, int enable)
57 {
58    if (!enable) {
59       bfd->use_backup_api = 0;
60       return 1;
61    }
62    /* We enable if possible here */
63    bfd->use_backup_api = p_BackupRead && p_BackupWrite;
64    return bfd->use_backup_api;
65 }
66
67 int is_win32_data(BFILE *bfd)
68 {
69    return bfd->use_backup_api;
70 }
71
72 HANDLE bget_handle(BFILE *bfd)
73 {
74    if (!bfd->use_win_api) {
75       return get_osfhandle(bfd->fid);
76    }
77    return bfd->fh;
78 }
79
80 int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode)
81 {
82    POOLMEM *win32_fname;
83
84    if (!bfd->use_win_api) {
85       bfd->fid = open(fname, flags, mode);
86       if (bfd->fid >= 0) {
87          bfd->mode = BF_READ;         /* not important if BF_READ or BF_WRITE */
88       }
89       return bfd->fid;
90    }
91
92    /* Convert to Windows path format */
93    win32_fname = get_pool_memory(PM_FNAME);
94    unix_name_to_win32(&win32_fname, (char *)fname);
95
96    if (flags & O_WRONLY) {            /* creating */
97       bfd->fh = CreateFile(win32_fname,
98                    FILE_ALL_ACCESS|WRITE_DAC|ACCESS_SYSTEM_SECURITY,    /* access */
99                    0,
100                    NULL,                                   /* SecurityAttributes */
101                    CREATE_ALWAYS,                          /* CreationDisposition */
102                    FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,   /* Flags and attributes */
103                    NULL);                                  /* TemplateFile */
104
105       if (bfd->fh == INVALID_HANDLE_VALUE) {
106          bfd->lerror = GetLastError();
107          bfd->mode = BF_CLOSED;
108       } else {
109          bfd->mode = BF_WRITE;
110       }
111    } else {
112       bfd->fh = CreateFile(win32_fname,
113                    GENERIC_READ|ACCESS_SYSTEM_SECURITY,       /* access */
114                    FILE_SHARE_READ,                         /* shared mode */
115                    NULL,                                   /* SecurityAttributes */
116                    OPEN_EXISTING,                          /* CreationDisposition */
117                    FILE_FLAG_BACKUP_SEMANTICS,  /* Flags and attributes */
118                    NULL);                                  /* TemplateFile */
119
120       if (bfd->fh == INVALID_HANDLE_VALUE) {
121          bfd->lerror = GetLastError();
122          bfd->mode = BF_CLOSED;
123       } else {
124          bfd->mode = BF_READ;
125       }
126    }
127    bfd->errmsg = NULL;
128    bfd->lpContext = NULL;
129    return bfd->mode == BF_CLOSED ? -1 : 1;
130 }
131
132 /* 
133  * Returns  0 on success
134  *         -1 on error
135  */
136 int bclose(BFILE *bfd)
137
138    int stat = 0;
139    if (!bfd->use_win_api) {
140       int stat = close(bfd->fid);
141       bfd->fid = -1;
142       bfd->mode = BF_CLOSED;
143       return stat;
144    }
145    if (bfd->errmsg) {
146       free_pool_memory(bfd->errmsg);
147       bfd->errmsg = NULL;
148    }
149    if (bfd->mode == BF_CLOSED) {
150       return 0;
151    }
152    if (bfd->use_backup_api && bfd->mode == BF_READ) {
153       BYTE buf[10];
154       if (!bfd->lpContext && !p_BackupRead(bfd->fh,   
155               buf,                    /* buffer */
156               (DWORD)0,               /* bytes to read */
157               &bfd->rw_bytes,         /* bytes read */
158               1,                      /* Abort */
159               1,                      /* ProcessSecurity */
160               &bfd->lpContext)) {     /* Read context */
161          stat = -1;
162       } 
163    } else if (bfd->use_backup_api && bfd->mode == BF_WRITE) {
164       BYTE buf[10];
165       if (!bfd->lpContext && !p_BackupWrite(bfd->fh,   
166               buf,                    /* buffer */
167               (DWORD)0,               /* bytes to read */
168               &bfd->rw_bytes,         /* bytes written */
169               1,                      /* Abort */
170               1,                      /* ProcessSecurity */
171               &bfd->lpContext)) {     /* Write context */
172          stat = -1;
173       } 
174    }
175    if (!CloseHandle(bfd->fh)) {
176       stat = -1;
177    }
178    bfd->mode = BF_CLOSED;
179    bfd->lpContext = NULL;
180    return stat;
181 }
182
183 /*
184  * Generate error message 
185  */
186 char *berror(BFILE *bfd)
187 {
188    LPTSTR msg;
189
190    if (!bfd->use_win_api) {
191       return strerror(errno);
192    }
193    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|
194                  FORMAT_MESSAGE_FROM_SYSTEM,
195                  NULL,
196                  bfd->lerror,
197                  0,
198                  (LPTSTR)&msg,
199                  0,
200                  NULL);
201    strip_trailing_junk(msg);
202    if (!bfd->errmsg) {
203       bfd->errmsg = get_pool_memory(PM_FNAME);
204    }
205    pm_strcpy(&bfd->errmsg, msg);
206    LocalFree(msg);
207    return bfd->errmsg;
208 }
209
210 /* Returns: bytes read on success
211  *           0         on EOF
212  *          -1         on error
213  */
214 ssize_t bread(BFILE *bfd, void *buf, size_t count)
215 {
216    if (!bfd->use_win_api) {
217       return read(bfd->fid, buf, count);
218    }
219    bfd->rw_bytes = 0;
220
221    if (bfd->use_backup_api) {
222       if (!p_BackupRead(bfd->fh,
223            (BYTE *)buf,
224            count,
225            &bfd->rw_bytes,
226            0,                           /* no Abort */
227            1,                           /* Process Security */
228            &bfd->lpContext)) {          /* Context */
229          bfd->lerror = GetLastError();
230          return -1;
231       }
232    } else {
233       if (!ReadFile(bfd->fh,
234            buf,
235            count,
236            &bfd->rw_bytes,
237            NULL)) {
238          bfd->lerror = GetLastError();
239          return -1;
240       }
241    }
242
243    return (ssize_t)bfd->rw_bytes;
244 }
245
246 ssize_t bwrite(BFILE *bfd, void *buf, size_t count)
247 {
248    if (!bfd->use_win_api) {
249       return write(bfd->fid, buf, count);
250    }
251    bfd->rw_bytes = 0;
252
253    if (bfd->use_backup_api) {
254       if (!p_BackupWrite(bfd->fh,
255            (BYTE *)buf,
256            count,
257            &bfd->rw_bytes,
258            0,                           /* No abort */
259            1,                           /* Process Security */
260            &bfd->lpContext)) {          /* Context */
261          bfd->lerror = GetLastError();
262          return -1;
263       }
264    } else {
265       if (!WriteFile(bfd->fh,
266            buf,
267            count,
268            &bfd->rw_bytes,
269            NULL)) {
270          bfd->lerror = GetLastError();
271          return -1;
272       }
273    }
274    return (ssize_t)bfd->rw_bytes;
275 }
276
277 int is_bopen(BFILE *bfd)
278 {
279    return bfd->mode != BF_CLOSED;
280 }
281
282 off_t blseek(BFILE *bfd, off_t offset, int whence)
283 {
284    if (!bfd->use_win_api) {
285       return lseek(bfd->fid, offset, whence);
286    }
287    return -1;
288 }
289
290 #else  /* Unix systems */
291
292 /* ===============================================================
293  * 
294  *            U N I X
295  *
296  * ===============================================================
297  */
298 void binit(BFILE *bfd)
299 {
300    bfd->fid = -1;
301 }
302
303 int is_win32_data(BFILE *bfd)
304 {
305    return 0;
306 }
307
308
309 int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode)
310 {
311    bfd->fid = open(fname, flags, mode);
312    bfd->berrno = errno;
313    return bfd->fid;
314 }
315
316 int bclose(BFILE *bfd)
317
318    int stat = close(bfd->fid);
319    bfd->berrno = errno;
320    bfd->fid = -1;
321    return stat;
322 }
323
324 ssize_t bread(BFILE *bfd, void *buf, size_t count)
325 {
326    ssize_t stat;
327    stat = read(bfd->fid, buf, count);
328    bfd->berrno = errno;
329    return stat;
330 }
331
332 ssize_t bwrite(BFILE *bfd, void *buf, size_t count)
333 {
334    ssize_t stat;
335    stat = write(bfd->fid, buf, count);
336    bfd->berrno = errno;
337    return stat;
338 }
339
340 int is_bopen(BFILE *bfd)
341 {
342    return bfd->fid >= 0;
343 }
344
345 off_t blseek(BFILE *bfd, off_t offset, int whence)
346 {
347     off_t pos;
348     pos = lseek(bfd->fid, offset, whence);
349     bfd->berrno = errno;
350     return pos;
351 }
352
353 char *berror(BFILE *bfd)
354 {
355     return strerror(bfd->berrno);
356 }
357
358 #endif