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.
6 * Kern Sibbald, April MMIII
12 Copyright (C) 2000-2003 Kern Sibbald and John Walker
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.
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.
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,
36 void unix_name_to_win32(POOLMEM **win32_name, char *name);
37 extern "C" HANDLE get_osfhandle(int fd);
40 void binit(BFILE *bfd, int use_win_api)
43 bfd->mode = BF_CLOSED;
44 bfd->use_win_api = use_win_api;
46 bfd->lpContext = NULL;
50 HANDLE bget_handle(BFILE *bfd)
52 if (!bfd->use_win_api) {
53 return get_osfhandle(bfd->fid);
58 int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode)
61 if (!bfd->use_win_api) {
62 bfd->fid = open(fname, flags, mode);
64 bfd->mode = BF_READ; /* not important if BF_READ or BF_WRITE */
69 /* Convert to Windows path format */
70 win32_fname = get_pool_memory(PM_FNAME);
71 unix_name_to_win32(&win32_fname, (char *)fname);
73 if (flags & O_WRONLY) { /* creating */
74 bfd->fh = CreateFile(win32_fname,
75 WRITE_OWNER|WRITE_DAC|ACCESS_SYSTEM_SECURITY, /* access */
77 NULL, /* SecurityAttributes */
78 CREATE_ALWAYS, /* CreationDisposition */
79 FILE_FLAG_BACKUP_SEMANTICS, /* Flags and attributes */
80 NULL); /* TemplateFile */
82 if (bfd->fh == INVALID_HANDLE_VALUE) {
83 bfd->lerror = GetLastError();
84 bfd->mode = BF_CLOSED;
89 bfd->fh = CreateFile(win32_fname,
90 READ_CONTROL|ACCESS_SYSTEM_SECURITY, /* access */
92 NULL, /* SecurityAttributes */
93 OPEN_EXISTING, /* CreationDisposition */
94 FILE_FLAG_BACKUP_SEMANTICS, /* Flags and attributes */
95 NULL); /* TemplateFile */
97 if (bfd->fh == INVALID_HANDLE_VALUE) {
98 bfd->lerror = GetLastError();
99 bfd->mode = BF_CLOSED;
105 bfd->lpContext = NULL;
106 return bfd->mode == BF_CLOSED ? -1 : 1;
110 * Returns 0 on success
113 int bclose(BFILE *bfd)
116 if (!bfd->use_win_api) {
117 int stat = close(bfd->fid);
119 bfd->mode = BF_CLOSED;
123 free_pool_memory(bfd->errmsg);
126 if (bfd->mode == BF_CLOSED) {
129 if (bfd->mode == BF_READ) {
131 if (!bfd->lpContext && !BackupRead(bfd->fh,
133 (DWORD)0, /* bytes to read */
134 &bfd->rw_bytes, /* bytes read */
136 1, /* ProcessSecurity */
137 &bfd->lpContext)) { /* Read context */
142 if (!bfd->lpContext && !BackupWrite(bfd->fh,
144 (DWORD)0, /* bytes to read */
145 &bfd->rw_bytes, /* bytes written */
147 1, /* ProcessSecurity */
148 &bfd->lpContext)) { /* Write context */
152 if (!CloseHandle(bfd->fh)) {
155 bfd->mode = BF_CLOSED;
156 bfd->lpContext = NULL;
161 * Generate error message
163 char *berror(BFILE *bfd)
167 if (!bfd->use_win_api) {
168 return strerror(errno);
170 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|
171 FORMAT_MESSAGE_FROM_SYSTEM,
178 strip_trailing_junk(msg);
180 bfd->errmsg = get_pool_memory(PM_FNAME);
182 pm_strcpy(&bfd->errmsg, msg);
187 /* Returns: bytes read on success
191 ssize_t bread(BFILE *bfd, void *buf, size_t count)
193 if (!bfd->use_win_api) {
194 return read(bfd->fid, buf, count);
203 1, /* Process Security */
204 &bfd->lpContext); /* Context */
205 if (bfd->rw_bytes > 0) {
206 return (ssize_t)bfd->rw_bytes;
208 bfd->lerror = GetLastError();
209 return bfd->lerror == 0 ? 0 : -1;
212 ssize_t bwrite(BFILE *bfd, void *buf, size_t count)
214 DWORD bytes_written = 0;
215 if (!bfd->use_win_api) {
216 return write(bfd->fid, buf, count);
223 1, /* Process Security */
224 &bfd->lpContext); /* Context */
226 if ((size_t)bfd->rw_bytes == count) {
227 return (ssize_t)bfd->rw_bytes;
229 bfd->lerror = GetLastError();
230 return bfd->lerror == 0 ? (ssize_t)bfd->rw_bytes : -1;
233 int is_bopen(BFILE *bfd)
235 return bfd->mode != BF_CLOSED;
238 off_t blseek(BFILE *bfd, off_t offset, int whence)
240 if (!bfd->use_win_api) {
241 return lseek(bfd->fid, offset, whence);
246 #else /* Unix systems */
248 /* ===============================================================
252 * ===============================================================
254 void binit(BFILE *bfd, int use_win_api)
259 int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode)
261 return bfd->fid = open(fname, flags, mode);
264 int bclose(BFILE *bfd)
266 int stat = close(bfd->fid);
271 ssize_t bread(BFILE *bfd, void *buf, size_t count)
273 return read(bfd->fid, buf, count);
276 ssize_t bwrite(BFILE *bfd, void *buf, size_t count)
278 return write(bfd->fid, buf, count);
281 int is_bopen(BFILE *bfd)
283 return bfd->fid >= 0;
286 off_t blseek(BFILE *bfd, off_t offset, int whence)
288 return lseek(bfd->fid, offset, whence);
291 char *berror(BFILE *bfd)
293 return strerror(errno);