#define MODE_RW 0666
#endif
-#ifdef DEBUG_MUTEX
+#if defined(HAVE_WIN32)
+typedef int64_t boffset_t;
+#else
+typedef off_t boffset_t;
+#endif
+
+#if defined(DEBUG_MUTEX)
extern void _p(char *file, int line, pthread_mutex_t *m);
extern void _v(char *file, int line, pthread_mutex_t *m);
#define REPLACE_NEVER 'n'
#define REPLACE_IFOLDER 'o'
-/* This probably should be done on a machine by machine basic, but it works */
+/* This probably should be done on a machine by machine basis, but it works */
/* This is critical for the smartalloc routines to properly align memory */
#define ALIGN_SIZE (sizeof(double))
#define BALIGN(x) (((x) + ALIGN_SIZE - 1) & ~(ALIGN_SIZE -1))
#endif
+#if defined(HAVE_WIN32)
+#define DEFAULT_CONFIGDIR "C:\\Documents and Settings\\All Users\\Application Data\\Bacula"
+
+inline bool IsPathSeparator(int ch) { return ch == '/' || ch == '\\'; }
+inline char *first_path_separator(char *path) { return strpbrk(path, ":/\\"); }
+inline const char *first_path_separator(const char *path) { return strpbrk(path, ":/\\"); }
+
+#else
/* Define Winsock functions if we aren't on Windows */
-#if !defined HAVE_WIN32
+
#define WSA_Init() 0 /* 0 = success */
#define WSACleanup() 0 /* 0 = success */
-#endif
-#ifdef HAVE_AIX_OS
+inline bool IsPathSeparator(int ch) { return ch == '/'; }
+inline char *first_path_separator(char *path) { return strchr(path, '/'); }
+inline const char *first_path_separator(const char *path) { return strchr(path, '/'); }
#endif
+
/* HP-UX 11 specific workarounds */
#ifdef HAVE_HPUX_OS
#endif
-/* Added by KES to deal with Win32 systems */
-#ifndef S_ISWIN32
-#define S_ISWIN32 020000
-#endif
-
-
/* Disabled because it breaks internationalisation...
#undef HAVE_SETLOCALE
#ifdef HAVE_SETLOCALE
POOLMEM *dbf;
dbf = get_pool_memory(PM_FNAME);
- if (working_directory[strlen(working_directory)-1] == '/') {
+ if (IsPathSeparator(working_directory[strlen(working_directory)-1])) {
sep = 0;
} else {
sep = '/';
* must be a path name (e.g. c:).
*/
for (p=f=fname; *p; p++) {
- if (*p == '/') {
+ if (IsPathSeparator(*p)) {
f = p; /* set pos of last slash */
}
}
- if (*f == '/') { /* did we find a slash? */
+ if (IsPathSeparator(*f)) { /* did we find a slash? */
f++; /* yes, point to filename */
} else { /* no, whole thing must be path name */
f = p;
res_incexe.current_opts->wilddir.append(bstrdup(lc->str));
newsize = res_incexe.current_opts->wilddir.size();
} else if (item->code == 2) {
- if (strchr(lc->str, '/') != NULL) {
+ if (strpbrk(lc->str, "/\\") != NULL) {
type = "wildfile";
res_incexe.current_opts->wildfile.append(bstrdup(lc->str));
newsize = res_incexe.current_opts->wildfile.size();
break;
}
/* Add trailing slash to end of directory names */
- if (ua->cmd[0] != '<' && ua->cmd[len-1] != '/') {
+ if (ua->cmd[0] != '<' && !IsPathSeparator(ua->cmd[len-1])) {
strcat(ua->cmd, "/");
}
insert_one_file_or_dir(ua, rx, date, true);
* must be a path name (e.g. c:).
*/
for (p=f=name; *p; p++) {
- if (*p == '/') {
+ if (IsPathSeparator(*p)) {
f = p; /* set pos of last slash */
}
}
- if (*f == '/') { /* did we find a slash? */
+ if (IsPathSeparator(*f)) { /* did we find a slash? */
f++; /* yes, point to filename */
} else { /* no, whole thing must be path name */
f = p;
free(jcr->where);
jcr->where = NULL;
}
- if (ua->cmd[0] == '/' && ua->cmd[1] == 0) {
+ if (IsPathSeparator(ua->cmd[0]) && ua->cmd[1] == '\0') {
ua->cmd[0] = 0;
}
jcr->where = bstrdup(ua->cmd);
// Dmsg4(000, "Path=%s%s FI=%s JobId=%s\n", row[0], row[1],
// row[2], row[3]);
- if (*row[1] == 0) { /* no filename => directory */
- if (*row[0] != '/') { /* Must be Win32 directory */
+ if (*row[1] == 0) { /* no filename => directory */
+ if (!IsPathSeparator(*row[0])) { /* Must be Win32 directory */
type = TN_DIR_NLS;
} else {
type = TN_DIR;
return EXIT_FAILURE;
}
- prgname = strrchr(argv[0], '/');
+ prgname = last_path_separator(argv[0]);
if (prgname == NULL || *++prgname == '\0') {
prgname = argv[0];
}
#ifdef HAVE_LIBZ
/* Do compression if turned on */
if (!sparseBlock && (ff_pkt->flags & FO_GZIP) && jcr->pZLIB_compress_workset) {
- Dmsg4(400, "cbuf=0x%x len=%u rbuf=0x%x len=%u\n", cbuf, compress_len,
- rbuf, sd->msglen);
+ Dmsg3(400, "cbuf=0x%x rbuf=0x%x len=%u\n", cbuf, rbuf, sd->msglen);
((z_stream*)jcr->pZLIB_compress_workset)->next_in = (Bytef *)rbuf;
((z_stream*)jcr->pZLIB_compress_workset)->avail_in = sd->msglen;
if (!sparseBlock && (ff_pkt->flags & FO_ENCRYPT)) {
uint32_t initial_len = 0;
+ ser_declare;
if (ff_pkt->flags & FO_SPARSE) {
cipher_input_len += SPARSE_FADDR_SIZE;
}
/* Encrypt the length of the input block */
- uint32_t packet_len = htonl(cipher_input_len);
+ uint8_t packet_len[sizeof(uint32_t)];
+
+ ser_begin(packet_len, sizeof(uint32_t));
+ ser_uint32(cipher_input_len); /* store fileAddr in begin of buffer */
- if (!crypto_cipher_update(cipher_ctx, (const u_int8_t *)&packet_len,
- sizeof(packet_len), (u_int8_t *)jcr->crypto_buf, &initial_len)) {
+ if (!crypto_cipher_update(cipher_ctx, packet_len, sizeof(packet_len),
+ (u_int8_t *)jcr->crypto_buf, &initial_len)) {
/* Encryption failed. Shouldn't happen. */
Jmsg(jcr, M_FATAL, 0, _("Encryption error\n"));
goto err;
*where = 0;
}
/* Turn / into nothing */
- if (where[0] == '/' && where[1] == 0) {
- where[0] = 0;
+ if (IsPathSeparator(where[0]) && where[1] == '\0') {
+ where[0] = '\0';
}
Dmsg2(150, "Got replace %c, where=%s\n", replace, where);
* Close a bfd check that we are at the expected file offset.
* Makes some code in set_attributes().
*/
-int bclose_chksize(JCR *jcr, BFILE *bfd, off_t osize)
+int bclose_chksize(JCR *jcr, BFILE *bfd, boffset_t osize)
{
char ec1[50], ec2[50];
- off_t fsize;
+ boffset_t fsize;
fsize = blseek(bfd, 0, SEEK_CUR);
bclose(bfd); /* first close file */
if (flags & FO_ENCRYPT) {
ASSERT(cipher);
+ unser_declare;
while (jcr->crypto_size > 0 && jcr->crypto_count > 0 && wsize > 0) {
uint32_t chunk_size = 16;
jcr->crypto_count += decrypted_len;
if (jcr->crypto_size == 0 && jcr->crypto_count >= 4) {
- jcr->crypto_size = ntohl(*(uint32_t *)&jcr->crypto_buf[0]) + 4;
+ unser_begin(&jcr->crypto_buf[0], sizeof(uint32_t));
+ unser_uint32(jcr->crypto_size);
+ jcr->crypto_size += 4;
}
if (jcr->crypto_size == 0 || jcr->crypto_count < jcr->crypto_size) {
}
if (flags & FO_SPARSE) {
- ser_declare;
+ unser_declare;
uint64_t faddr;
char ec1[50];
- ser_begin(wbuf, SPARSE_FADDR_SIZE);
+ unser_begin(wbuf, SPARSE_FADDR_SIZE);
unser_uint64(faddr);
if (*addr != faddr) {
*addr = faddr;
- if (blseek(bfd, (off_t)*addr, SEEK_SET) < 0) {
+ if (blseek(bfd, (boffset_t)*addr, SEEK_SET) < 0) {
berrno be;
Jmsg3(jcr, M_ERROR, 0, _("Seek to %s error on %s: ERR=%s\n"),
edit_uint64(*addr, ec1), jcr->last_fname,
edit_uint64_with_commas(sm_buffers, b3),
edit_uint64_with_commas(sm_max_buffers, b4));
sendit(msg, len, arg);
- len = Mmsg(msg, _(" Sizeof: off_t=%d size_t=%d debug=%d trace=%d\n"),
- sizeof(off_t), sizeof(size_t), debug_level, get_trace());
+ len = Mmsg(msg, _(" Sizeof: boffset_t=%d size_t=%d debug=%d trace=%d\n"),
+ sizeof(boffset_t), sizeof(size_t), debug_level, get_trace());
sendit(msg, len, arg);
/*
struct utimbuf ut;
mode_t old_mask;
bool ok = true;
- off_t fsize;
+ boffset_t fsize;
#if defined(HAVE_WIN32)
if (attr->stream == STREAM_UNIX_ATTRIBUTES_EX &&
char ec1[50], ec2[50];
fsize = blseek(ofd, 0, SEEK_END);
bclose(ofd); /* first close file */
- if (attr->type == FT_REG && fsize > 0 && fsize != (off_t)attr->statp.st_size) {
+ if (attr->type == FT_REG && fsize > 0 && fsize != (boffset_t)attr->statp.st_size) {
Jmsg3(jcr, M_ERROR, 0, _("File size of restored file %s not correct. Original %s, restored %s.\n"),
attr->ofname, edit_uint64(attr->statp.st_size, ec1),
edit_uint64(fsize, ec2));
bool processWin32BackupAPIBlock (BFILE *bfd, void *pBuffer, ssize_t dwSize)
-{
+{
/* pByte contains the buffer
dwSize the len to be processed. function assumes to be
called in successive incremental order over the complete
*/
int32_t dwSizeHeader = 20;
- do {
- if (pContext->liNextHeader >= dwSize) {
+ do {
+ if (pContext->liNextHeader >= dwSize) {
dwDataLen = dwSize-dwDataOffset;
bContinue = false; /* 1 iteration is enough */
- }
- else {
+ } else {
dwDataLen = pContext->liNextHeader-dwDataOffset;
bContinue = true; /* multiple iterations may be necessary */
}
/* copy block of real DATA */
if (pContext->bIsInData) {
if (bwrite(bfd, ((char *)pBuffer)+dwDataOffset, dwDataLen) != (ssize_t)dwDataLen)
- return false;
+ return false;
}
if (pContext->liNextHeader < dwSize) {/* is a header in this block ? */
int32_t dwOffsetTarget;
int32_t dwOffsetSource;
-
+
if (pContext->liNextHeader < 0) {
/* start of header was before this block, so we
* continue with the part in the current block
*/
- dwOffsetTarget = -pContext->liNextHeader;
- dwOffsetSource = 0;
+ dwOffsetTarget = -pContext->liNextHeader;
+ dwOffsetSource = 0;
} else {
/* start of header is inside of this block */
dwOffsetTarget = 0;
- dwOffsetSource = pContext->liNextHeader;
+ dwOffsetSource = pContext->liNextHeader;
}
int32_t dwHeaderPartLen = dwSizeHeader-dwOffsetTarget;
bool bHeaderIsComplete;
- if (dwHeaderPartLen <= dwSize-dwOffsetSource)
+ if (dwHeaderPartLen <= dwSize-dwOffsetSource) {
/* header (or rest of header) is completely available
in current block
*/
bHeaderIsComplete = true;
- else {
+ } else {
/* header will continue in next block */
bHeaderIsComplete = false;
dwHeaderPartLen = dwSize-dwOffsetSource;
int32_t dwNameSize;
int32_LE2BE (&dwNameSize, pContext->header_stream.dwStreamNameSize);
dwDataOffset = dwNameSize+pContext->liNextHeader+dwSizeHeader;
-
+
/* convert stream size (64 bit little endian) to machine type */
int64_LE2BE (&(pContext->liNextHeader), pContext->header_stream.Size);
pContext->liNextHeader += dwDataOffset;
pContext->bIsInData = pContext->header_stream.dwStreamId == WIN32_BACKUP_DATA;
if (dwDataOffset == dwSize)
- bContinue = false;
- }
- else {
+ bContinue = false;
+ } else {
/* stop and continue with next block */
bContinue = false;
pContext->bIsInData = false;
}
- }
- } while (bContinue);
+ }
+ } while (bContinue);
/* set "NextHeader" relative to the beginning of the next block */
pContext->liNextHeader-= dwSize;
extern "C" HANDLE get_osfhandle(int fd);
-
void binit(BFILE *bfd)
{
memset(bfd, 0, sizeof(BFILE));
}
-
/*
* Return true if we support the stream
* false if we do not support the stream
if (!(p_CreateFileA || p_CreateFileW))
return 0;
- if (p_CreateFileW && p_MultiByteToWideChar)
+ if (p_CreateFileW && p_MultiByteToWideChar)
make_win32_path_UTF8_2_wchar(&win32_fname_wchar, fname);
if (flags & O_CREAT) { /* Create */
return bfd->mode != BF_CLOSED;
}
-off_t blseek(BFILE *bfd, off_t offset, int whence)
+boffset_t blseek(BFILE *bfd, boffset_t offset, int whence)
{
- /* ****FIXME**** this must be implemented if we want to read Win32 Archives */
- return -1;
+ LONG offset_low = (LONG)offset;
+ LONG offset_high = (LONG)(offset >> 32);
+ DWORD dwResult;
+
+ dwResult = SetFilePointer(bfd->fh, offset_low, &offset_high, whence);
+
+ if (dwResult == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR) {
+ return (boffset_t)-1;
+ }
+
+ return ((boffset_t)offset_high << 32) | dwResult;
}
#else /* Unix systems */
return bfd->fid >= 0;
}
-off_t blseek(BFILE *bfd, off_t offset, int whence)
+boffset_t blseek(BFILE *bfd, boffset_t offset, int whence)
{
- off_t pos;
- pos = lseek(bfd->fid, offset, whence);
+ boffset_t pos;
+ pos = (boffset_t)lseek(bfd->fid, (off_t)offset, whence);
bfd->berrno = errno;
return pos;
}
int bclose(BFILE *bfd);
ssize_t bread(BFILE *bfd, void *buf, size_t count);
ssize_t bwrite(BFILE *bfd, void *buf, size_t count);
-off_t blseek(BFILE *bfd, off_t offset, int whence);
+boffset_t blseek(BFILE *bfd, boffset_t offset, int whence);
const char *stream_to_ascii(int stream);
bool processWin32BackupAPIBlock (BFILE *bfd, void *pBuffer, ssize_t dwSize);
be.set_errno(bfd->berrno);
#ifdef HAVE_WIN32
/* Check for trying to create a drive, if so, skip */
- if (attr->ofname[1] == ':' && attr->ofname[2] == '/' && attr->ofname[3] == 0) {
+ if (attr->ofname[1] == ':' &&
+ IsPathSeparator(attr->ofname[2]) &&
+ attr->ofname[3] == '\0') {
return CF_SKIP;
}
#endif
/* Separate pathname and filename */
for (q=p=f=ofile; *p; p++) {
#ifdef HAVE_WIN32
- if (*p == '\\' || *p == '/') {
+ if (IsPathSeparator(*p)) {
f = q;
- if (p[1] == '\\' || p[1] == '/') {
+ if (IsPathSeparator(p[1])) {
p++;
}
}
*q++ = *p; /* copy data */
#else
- if (*p == '/') {
+ if (IsPathSeparator(*p)) {
f = q; /* possible filename */
}
q++;
#endif
}
- if (*f == '/') {
+ if (IsPathSeparator(*f)) {
f++;
}
*q = 0; /* terminate string */
if (ff->flags & FO_ENHANCEDWILD) {
match_func = enh_fnmatch;
- if ((basename = strrchr(ff->fname, '/')) != NULL)
+ if ((basename = last_path_separator(ff->fname)) != NULL)
basename++;
else
basename = ff->fname;
basename = ff->fname;
}
- for (j=0; j<incexe->opts_list.size(); j++) {
+ for (j = 0; j < incexe->opts_list.size(); j++) {
findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j);
ff->flags = fo->flags;
ff->GZIP_level = fo->GZIP_level;
/* This is not a link to a previously dumped file, so dump it. */
if (S_ISREG(ff_pkt->statp.st_mode)) {
- off_t sizeleft;
+ boffset_t sizeleft;
sizeleft = ff_pkt->statp.st_size;
link = (char *)bmalloc(link_len + 2);
bstrncpy(link, fname, link_len);
/* Strip all trailing slashes */
- while (len >= 1 && link[len - 1] == '/')
+ while (len >= 1 && IsPathSeparator(link[len - 1]))
len--;
link[len++] = '/'; /* add back one */
link[len] = 0;
isAbsolute(const char *path)
{
#if defined(HAVE_WIN32)
- return path[1] == ':' || *path == '/' || *path == '\\'; /* drivespec:/blah is absolute */
+ return path[1] == ':' || IsPathSeparator(*path); /* drivespec:/blah is absolute */
#else
- return *path == '/';
+ return IsPathSeparator(*path);
#endif
}
}
/* Skip over leading slashes. */
-#if defined(HAVE_WIN32)
- while (*slash == '/' || *slash == '\\')
- slash++;
-#else
- while (*slash == '/')
+ while (IsPathSeparator(*slash))
slash++;
-#endif
- while (1) {
+
+ for ( ; ; ) {
int newly_created_dir;
int fail;
/* slash points to the leftmost unprocessed component of dirpath. */
basename_dir = slash;
-
-#if defined(HAVE_WIN32)
- slash = strpbrk(slash, ":/\\");
- if (slash == NULL) {
- break;
- }
-#else
- slash = strchr (slash, '/');
+ slash = first_path_separator(slash);
if (slash == NULL) {
break;
}
-#endif
/* If we're *not* doing chdir before each mkdir, then we have to refer
to the target using the full (multi-component) directory name. */
/* Avoid unnecessary calls to `stat' when given
pathnames containing multiple adjacent slashes. */
-#if defined(HAVE_WIN32)
- while (*slash == '/' || *slash == '\\')
- slash++;
-#else
- while (*slash == '/')
+ while (IsPathSeparator(*slash))
slash++;
-#endif
} /* end while (1) */
if (!cwd.do_chdir) {
len = strlen(p);
/* Zap trailing slashes. */
p += len - 1;
- while (p > inc->fname && *p == '/') {
+ while (p > inc->fname && IsPathSeparator(*p)) {
*p-- = 0;
len--;
}
Dmsg1(20, "Add name to exclude: %s\n", fname);
-#if defined(HAVE_WIN32)
- if (strchr(fname, '/') || strchr(fname, '\\')) {
-#else
- if (strchr(fname, '/')) {
-#endif
+ if (first_path_separator(fname) != NULL) {
list = &ff->excluded_paths_list;
} else {
list = &ff->excluded_files_list;
if (inc->len == len && strcmp(inc->fname, file) == 0) {
return 1;
}
- if (inc->len < len && file[inc->len] == '/' &&
+ if (inc->len < len && IsPathSeparator(file[inc->len]) &&
strncmp(inc->fname, file, inc->len) == 0) {
return 1;
}
- if (inc->len == 1 && inc->fname[0] == '/') {
+ if (inc->len == 1 && IsPathSeparator(inc->fname[0])) {
return 1;
}
}
/* Try each component */
for (p = file; *p; p++) {
/* Match from the beginning of a component only */
- if ((p == file || (*p != '/' && *(p-1) == '/'))
+ if ((p == file || (!IsPathSeparator(*p) && IsPathSeparator(p[-1])))
&& file_in_excluded_list(ff->excluded_files_list, p)) {
return 1;
}
{
char *p = fname;
while (p && *p) {
- p = strchr(p, '/');
- if (p && p[1] == '/') {
- strcpy(p, p+1);
- }
- if (p) {
+ p = strpbrk(p, "/\\");
+ if (p != NULL) {
+ if (IsPathSeparator(p[1])) {
+ strcpy(p, p+1);
+ }
p++;
}
}
#endif
fn = attr->fname; /* take whole name */
/* Ensure where is terminated with a slash */
- if (jcr->where[wherelen-1] != '/' && fn[0] != '/') {
+ if (!IsPathSeparator(jcr->where[wherelen-1]) && !IsPathSeparator(fn[0])) {
pm_strcat(attr->ofname, "/");
}
pm_strcat(attr->ofname, fn); /* copy rest of name */
/* Always add prefix to hard links (FT_LNKSAVED) and
* on user request to soft links
*/
- if (attr->lname[0] == '/' &&
+ if (IsPathSeparator(attr->lname[0]) &&
(attr->type == FT_LNKSAVED || jcr->prefix_links)) {
pm_strcpy(attr->olname, jcr->where);
add_link = true;
#endif
fn = attr->lname; /* take whole name */
/* Ensure where is terminated with a slash */
- if (add_link && jcr->where[wherelen-1] != '/' && fn[0] != '/') {
+ if (add_link &&
+ !IsPathSeparator(jcr->where[wherelen-1]) &&
+ !IsPathSeparator(fn[0])) {
pm_strcat(attr->olname, "/");
}
pm_strcat(attr->olname, fn); /* copy rest of link */
}
}
#if defined(HAVE_WIN32)
- strip_double_slashes(attr->ofname);
- strip_double_slashes(attr->olname);
+ strip_double_slashes(attr->ofname);
+ strip_double_slashes(attr->olname);
#endif
}
case '?':
if (*n == '\0')
return 0;
- else if ((flags & FNM_FILE_NAME) && *n == '/')
+ else if ((flags & FNM_FILE_NAME) && IsPathSeparator(*n))
return 0;
else if ((flags & FNM_PERIOD) && *n == '.' &&
- (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
+ (n == string || ((flags & FNM_FILE_NAME) && IsPathSeparator(n[-1]))))
return 0;
break;
case '*':
if ((flags & FNM_PERIOD) && *n == '.' &&
- (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
+ (n == string || ((flags & FNM_FILE_NAME) && IsPathSeparator(n[-1]))))
return FNM_NOMATCH;
if ((p - pattern) >= patternlen)
for (c = *p++; ((p - pattern) <= patternlen) && (c == '?' || c == '*'); c = *p++)
{
- if ((flags & FNM_FILE_NAME) && *n == '/')
+ if ((flags & FNM_FILE_NAME) && IsPathSeparator(*n))
/* A slash does not match a wildcard under FNM_FILE_NAME. */
return 0;
else if (c == '?')
}
else
{
- if ((flags & FNM_FILE_NAME) && *n == '/')
+ if ((flags & FNM_FILE_NAME) && IsPathSeparator(*n))
return 0; /* A slash does not match a wildcard under FNM_FILE_NAME. */
}
return 0;
if ((flags & FNM_PERIOD) && *n == '.' &&
- (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
+ (n == string || ((flags & FNM_FILE_NAME) && IsPathSeparator(n[-1]))))
return 0;
nnot = (*p == '!' || *p == '^');
c = *p++;
c = FOLD (c);
- if ((flags & FNM_FILE_NAME) && c == '/')
+ if ((flags & FNM_FILE_NAME) && IsPathSeparator(c))
/* [/] can never match. */
return 0;
if (string[matchlen] == '\0')
return 0;
- if ((flags & FNM_LEADING_DIR) && string[matchlen] == '/')
+ if ((flags & FNM_LEADING_DIR) && IsPathSeparator(string[matchlen]))
/* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */
return 0;
case '?':
if (*n == '\0')
return FNM_NOMATCH;
- else if ((flags & FNM_FILE_NAME) && *n == '/')
+ else if ((flags & FNM_FILE_NAME) && IsPathSeparator(*n))
return FNM_NOMATCH;
else if ((flags & FNM_PERIOD) && *n == '.' &&
- (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
+ (n == string || ((flags & FNM_FILE_NAME) && IsPathSeparator(n[-1]))))
return FNM_NOMATCH;
break;
case '*':
if ((flags & FNM_PERIOD) && *n == '.' &&
- (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
+ (n == string || ((flags & FNM_FILE_NAME) && IsPathSeparator(n[-1]))))
return FNM_NOMATCH;
for (c = *p++; c == '?' || c == '*'; c = *p++)
{
- if ((flags & FNM_FILE_NAME) && *n == '/')
+ if ((flags & FNM_FILE_NAME) && IsPathSeparator(*n))
/* A slash does not match a wildcard under FNM_FILE_NAME. */
return FNM_NOMATCH;
else if (c == '?')
return FNM_NOMATCH;
if ((flags & FNM_PERIOD) && *n == '.' &&
- (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
+ (n == string || ((flags & FNM_FILE_NAME) && IsPathSeparator(n[-1]))))
return FNM_NOMATCH;
nnot = (*p == '!' || *p == '^');
c = *p++;
c = FOLD (c);
- if ((flags & FNM_FILE_NAME) && c == '/')
+ if ((flags & FNM_FILE_NAME) && IsPathSeparator(c))
/* [/] can never match. */
return FNM_NOMATCH;
if (*n == '\0')
return 0;
- if ((flags & FNM_LEADING_DIR) && *n == '/')
+ if ((flags & FNM_LEADING_DIR) && IsPathSeparator(*n))
/* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */
return 0;
char *getuser(uid_t uid, char *name, int len)
{
- register struct userid *tail;
- struct passwd *pwent;
- char usernum_string[20];
-
- P(mutex);
- for (tail = user_alist; tail; tail = tail->next) {
- if (tail->id.u == uid) {
- goto uid_done;
- }
- }
+ register struct userid *tail;
+ char usernum_string[20];
+
+ P(mutex);
+ for (tail = user_alist; tail; tail = tail->next) {
+ if (tail->id.u == uid) {
+ goto uid_done;
+ }
+ }
+
+ tail = (struct userid *)malloc(sizeof (struct userid));
+ tail->id.u = uid;
+ tail->name = NULL;
+
+#if !defined(HAVE_WIN32)
+ {
+ struct passwd *pwent = getpwuid(uid);
+
+ if (pwent != NULL && strcmp(pwent->pw_name, "????????") != 0) {
+ tail->name = bstrdup(pwent->pw_name);
+ }
+ }
+#endif
- pwent = getpwuid(uid);
- tail = (struct userid *)malloc(sizeof (struct userid));
- tail->id.u = uid;
-#ifndef HAVE_WIN32
- if (pwent == NULL || strcmp(pwent->pw_name, "????????") == 0) {
+ if (tail->name == NULL) {
sprintf(usernum_string, "%u", (uint32_t)uid);
tail->name = bstrdup(usernum_string);
- } else {
- tail->name = bstrdup(pwent->pw_name);
- }
-#else
- sprintf(usernum_string, "%u", (uint32_t)uid);
- tail->name = bstrdup(usernum_string);
-#endif
+ }
- /* Add to the head of the list, so most recently used is first. */
- tail->next = user_alist;
- user_alist = tail;
+ /* Add to the head of the list, so most recently used is first. */
+ tail->next = user_alist;
+ user_alist = tail;
uid_done:
- bstrncpy(name, tail->name, len);
- V(mutex);
- return name;
+ bstrncpy(name, tail->name, len);
+ V(mutex);
+ return name;
}
void free_getuser_cache()
/* Translate GID to a group name or a stringified number,
- with cache. */
+ with cache. */
char *getgroup(gid_t gid, char *name, int len)
{
- register struct userid *tail;
- struct group *grent;
- char groupnum_string[20];
-
- P(mutex);
- for (tail = group_alist; tail; tail = tail->next) {
- if (tail->id.g == gid) {
- goto gid_done;
- }
- }
+ register struct userid *tail;
+ char groupnum_string[20];
+
+ P(mutex);
+ for (tail = group_alist; tail; tail = tail->next) {
+ if (tail->id.g == gid) {
+ goto gid_done;
+ }
+ }
+
+ tail = (struct userid *)malloc(sizeof (struct userid));
+ tail->id.g = gid;
+ tail->name = NULL;
+
+#if !defined(HAVE_WIN32)
+ {
+ struct group *grent = getgrgid(gid);
+
+ if (grent != NULL && strcmp(grent->gr_name, "????????") != 0) {
+ tail->name = bstrdup(grent->gr_name);
+ }
+ }
+#endif
- grent = getgrgid(gid);
- tail = (struct userid *)malloc(sizeof (struct userid));
- tail->id.g = gid;
-#ifndef HAVE_WIN32
- if (grent == NULL || strcmp(grent->gr_name, "????????") == 0) {
+ if (tail->name == NULL) {
sprintf (groupnum_string, "%u", (uint32_t)gid);
tail->name = bstrdup(groupnum_string);
- } else {
- tail->name = bstrdup(grent->gr_name);
- }
-#else
- sprintf (groupnum_string, "%u", (uint32_t)gid);
- tail->name = bstrdup(groupnum_string);
-#endif
- /* Add to the head of the list, so most recently used is first. */
- tail->next = group_alist;
- group_alist = tail;
+ }
+
+ /* Add to the head of the list, so most recently used is first. */
+ tail->next = group_alist;
+ group_alist = tail;
gid_done:
- bstrncpy(name, tail->name, len);
- V(mutex);
- return name;
+ bstrncpy(name, tail->name, len);
+ V(mutex);
+ return name;
}
void free_getgroup_cache()
if (argc>0 && argv && argv[0]) {
/* strip trailing filename and save exepath */
for (l=p=argv[0]; *p; p++) {
- if (*p == '/') {
+ if (IsPathSeparator(*p)) {
l = p; /* set pos of last slash */
}
}
- if (*l == '/') {
+ if (IsPathSeparator(*l)) {
l++;
} else {
l = argv[0];
*q++ = *p++;
}
*q = 0;
- if (strchr(exepath, '.') || exepath[0] != '/') {
+ if (strchr(exepath, '.') || !IsPathSeparator(exepath[0])) {
if (getcwd(cpath, sizeof(cpath))) {
free(exepath);
exepath = (char *)malloc(strlen(cpath) + 1 + len);
const char *get_default_configdir()
{
#if defined(HAVE_WIN32)
-#define DEFAULT_CONFIGDIR "C:\\Documents and Settings\\All Users\\Application Data\\Bacula"
-
HRESULT hr;
static char szConfigDir[MAX_PATH + 1] = { 0 };
bool
find_config_file(const char *config_file, char *full_path)
{
-#if defined(HAVE_WIN32)
- if (strpbrk(config_file, ":/\\") != NULL) {
- return false;
- }
-#else
- if (strchr(config_file, '/') != NULL) {
+ if (first_path_separator(config_file) != NULL) {
return false;
}
-#endif
struct stat st;
memcpy(full_path, config_dir, dir_length + 1);
- if (full_path[dir_length - 1] != '/' &&
- full_path[dir_length - 1] != '\\') {
+ if (!IsPathSeparator(full_path[dir_length - 1])) {
full_path[dir_length++] = '/';
}
const char * job_status_to_str (int stat);
const char * job_level_to_str (int level);
void make_session_key (char *key, char *seed, int mode);
-POOLMEM *edit_job_codes(JCR *jcr, char *omsg, char *imsg, const char *to);
-void set_working_directory(char *wd);
+POOLMEM * edit_job_codes (JCR *jcr, char *omsg, char *imsg, const char *to);
+void set_working_directory (char *wd);
+const char * last_path_separator (const char *str);
/* watchdog.c */
p = dir + strlen(dir) - 1;
/* strip trailing slashes */
- while ((p >= dir) && (*p == '/'))
+ while (p >= dir && IsPathSeparator(*p))
*p-- = 0;
}
*/
f = fname + len - 1;
/* "strip" any trailing slashes */
- while (slen > 1 && *f == '/') {
+ while (slen > 1 && IsPathSeparator(*f)) {
slen--;
f--;
}
/* Walk back to last slash -- begin of filename */
- while (slen > 0 && *f != '/') {
+ while (slen > 0 && !IsPathSeparator(*f)) {
slen--;
f--;
}
- if (*f == '/') { /* did we find a slash? */
+ if (IsPathSeparator(*f)) { /* did we find a slash? */
f++; /* yes, point to filename */
} else { /* no, whole thing must be path name */
f = fname;
bstrncpy(btpath, "btraceback", sizeof(btpath));
} else {
bstrncpy(btpath, exepath, sizeof(btpath));
- if (btpath[exelen-1] == '/') {
+ if (IsPathSeparator(btpath[exelen-1])) {
btpath[exelen-1] = 0;
}
bstrncat(btpath, "/btraceback", sizeof(btpath));
}
- if (exepath[exelen-1] != '/') {
+ if (!IsPathSeparator(exepath[exelen - 1])) {
strcat(exepath, "/");
}
strcat(exepath, exename);
*/
if (path_len > 0) {
q = path + path_len - 1;
- if (*q == '/') {
+ if (IsPathSeparator(*q)) {
*q = 0; /* strip trailing slash */
} else {
q = NULL; /* no trailing slash */
}
/* If no filename, strip last component of path as "filename" */
if (*fname == 0) {
- p = strrchr(path, '/'); /* separate path and filename */
+ p = (char *)last_path_separator(path); /* separate path and filename */
if (p) {
fname = p + 1; /* set new filename */
- *p = 0; /* terminate new path */
+ *p = '\0'; /* terminate new path */
}
} else {
p = NULL;
Dmsg0(100, "make_tree_path: parent=*root*\n");
return (TREE_NODE *)root;
}
- p = strrchr(path, '/'); /* get last dir component of path */
+ p = (char *)last_path_separator(path); /* get last dir component of path */
if (p) {
fname = p + 1;
*p = 0; /* terminate path */
* there is only a / in the buffer, remove it since
* win32 names don't generally start with /
*/
- if (node->type == TN_DIR_NLS && buf[0] == '/' && buf[1] == 0) {
- buf[0] = 0;
+ if (node->type == TN_DIR_NLS && IsPathSeparator(buf[0]) && buf[1] == '\0') {
+ buf[0] = '\0';
}
bstrncat(buf, node->fname, buf_size);
/* Add a slash for all directories unless we are at the root,
* also add a slash to a soft linked file if it has children
* i.e. it is linked to a directory.
*/
- if ((node->type != TN_FILE && !(buf[0] == '/' && buf[1] == 0)) ||
+ if ((node->type != TN_FILE && !(IsPathSeparator(buf[0]) && buf[1] == '\0')) ||
(node->soft_link && tree_node_has_child(node))) {
bstrncat(buf, "/", buf_size);
}
return tree_cwd(path+3, root, parent);
}
}
- if (path[0] == '/') {
+ if (IsPathSeparator(path[0])) {
Dmsg0(100, "Doing absolute lookup.\n");
return tree_relcwd(path+1, root, (TREE_NODE *)root);
}
return node;
}
/* Check the current segment only */
- p = strchr(path, '/');
- if (p) {
+ if ((p = first_path_separator(path)) != NULL) {
len = p - path;
} else {
len = strlen(path);
}
working_directory = wd; /* set global */
}
+
+const char *last_path_separator(const char *str)
+{
+ if (*str != '\0') {
+ for (const char *p = &str[strlen(str) - 1]; p >= str; p--) {
+ if (IsPathSeparator(*p)) {
+ return p;
+ }
+ }
+ }
+ return NULL;
+}
+
unser_uint64(faddr);
if (fileAddr != faddr) {
fileAddr = faddr;
- if (blseek(&bfd, (off_t)fileAddr, SEEK_SET) < 0) {
+ if (blseek(&bfd, (boffset_t)fileAddr, SEEK_SET) < 0) {
berrno be;
Emsg2(M_ERROR_TERM, 0, _("Seek error on %s: %s\n"),
attr->ofname, be.strerror());
unser_uint64(faddr);
if (fileAddr != faddr) {
fileAddr = faddr;
- if (blseek(&bfd, (off_t)fileAddr, SEEK_SET) < 0) {
+ if (blseek(&bfd, (boffset_t)fileAddr, SEEK_SET) < 0) {
berrno be;
Emsg3(M_ERROR, 0, _("Seek to %s error on %s: ERR=%s\n"),
edit_uint64(fileAddr, ec1), attr->ofname, be.strerror());
}
} else {
Dmsg0(200, "Seek to beginning of block for reread.\n");
- off_t pos = dev->lseek(dcr, (off_t)0, SEEK_CUR); /* get curr pos */
+ boffset_t pos = dev->lseek(dcr, (boffset_t)0, SEEK_CUR); /* get curr pos */
pos -= block->read_len;
dev->lseek(dcr, pos, SEEK_SET);
dev->file_addr = pos;
Dmsg0(200, "At end of read block\n");
if (block->read_len > block->block_len && !dev->is_tape()) {
char ed1[50];
- off_t pos = dev->lseek(dcr, (off_t)0, SEEK_CUR); /* get curr pos */
+ boffset_t pos = dev->lseek(dcr, (boffset_t)0, SEEK_CUR); /* get curr pos */
Dmsg1(200, "Current lseek pos=%s\n", edit_int64(pos, ed1));
pos -= (block->read_len - block->block_len);
dev->lseek(dcr, pos, SEEK_SET);
if (TAPE_BSIZE != (1 << (ffs(TAPE_BSIZE)-1))) {
Emsg1(M_ABORT, 0, _("Tape block size (%d) is not a power of 2\n"), TAPE_BSIZE);
}
- if (sizeof(off_t) < 8) {
- Pmsg1(-1, _("\n\n!!!! Warning large disk addressing disabled. off_t=%d should be 8 or more !!!!!\n\n\n"),
- sizeof(off_t));
+ if (sizeof(boffset_t) < 8) {
+ Pmsg1(-1, _("\n\n!!!! Warning large disk addressing disabled. boffset_t=%d should be 8 or more !!!!!\n\n\n"),
+ sizeof(boffset_t));
}
x32 = 123456789;
bsnprintf(buf, sizeof(buf), "%u", x32);
static void do_unfill()
{
DEV_BLOCK *block = dcr->block;
- bool autochanger;
+ int autochanger;
dumped = 0;
VolBytes = 0;
dev->offline();
}
autochanger = autoload_device(dcr, 1, NULL);
- if (!autochanger) {
+ if (autochanger != 1) {
dev->close();
get_cmd(_("Mount first tape. Press enter when ready: "));
}
set_volume_name("TestVolume2", 2);
autochanger = autoload_device(dcr, 1, NULL);
- if (!autochanger) {
+ if (autochanger != 1) {
dev->close();
get_cmd(_("Mount second tape. Press enter when ready: "));
}
bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr)
{
- bool autochanger;
+ int autochanger;
DEVICE *dev = dcr->dev;
Dmsg0(20, "Enter dir_ask_sysop_to_create_appendable_volume\n");
if (stop == 0) {
dev->offline();
}
autochanger = autoload_device(dcr, 1, NULL);
- if (!autochanger) {
+ if (autochanger != 1) {
fprintf(stderr, _("Mount blank Volume on device %s and press return when ready: "),
dev->print_name());
dev->close();
/* Try stripping file part */
p = dev_name + strlen(dev_name);
- while (p >= dev_name && *p != '/')
+ while (p >= dev_name && !IsPathSeparator(*p))
p--;
- if (*p == '/') {
+ if (IsPathSeparator(*p)) {
bstrncpy(VolName, p+1, sizeof(VolName));
*p = 0;
}
return;
}
- if (archive_name.c_str()[strlen(archive_name.c_str())-1] != '/') {
+ if (!IsPathSeparator(archive_name.c_str()[strlen(archive_name.c_str())-1])) {
pm_strcat(archive_name, "/");
}
pm_strcat(archive_name, VolCatInfo.VolCatName);
break;
}
} else if (is_file() || is_dvd()) {
- if (lseek(dcr, (off_t)0, SEEK_SET) < 0) {
+ if (lseek(dcr, (boffset_t)0, SEEK_SET) < 0) {
berrno be;
dev_errno = errno;
Mmsg2(errmsg, _("lseek error on %s. ERR=%s.\n"),
struct mtop mt_com;
struct mtget mt_stat;
bool ok = true;
- off_t pos;
+ boffset_t pos;
if (fd < 0) {
dev_errno = EBADF;
return true;
}
if (!is_tape()) {
- pos = lseek(dcr, (off_t)0, SEEK_END);
+ pos = lseek(dcr, (boffset_t)0, SEEK_END);
// Dmsg1(100, "====== Seek to %lld\n", pos);
if (pos >= 0) {
update_pos(dcr);
*/
bool DEVICE::update_pos(DCR *dcr)
{
- off_t pos;
+ boffset_t pos;
bool ok = true;
if (!is_open()) {
if (is_file() || is_dvd()) {
file = 0;
file_addr = 0;
- pos = lseek(dcr, (off_t)0, SEEK_CUR);
+ pos = lseek(dcr, (boffset_t)0, SEEK_CUR);
if (pos < 0) {
berrno be;
dev_errno = errno;
}
if (!is_tape()) {
- off_t pos = (((off_t)rfile)<<32) + (off_t)rblock;
+ boffset_t pos = (((boffset_t)rfile)<<32) | rblock;
Dmsg1(100, "===== lseek to %d\n", (int)pos);
- if (lseek(dcr, pos, SEEK_SET) == (off_t)-1) {
+ if (lseek(dcr, pos, SEEK_SET) == (boffset_t)-1) {
berrno be;
dev_errno = errno;
Mmsg2(errmsg, _("lseek error on %s. ERR=%s.\n"),
dcr->VolCatInfo = saveVolCatInfo; /* structure assignment */
}
-off_t DEVICE::lseek(DCR *dcr, off_t offset, int whence)
+boffset_t DEVICE::lseek(DCR *dcr, boffset_t offset, int whence)
{
switch (dev_type) {
case B_DVD_DEV:
return lseek_dvd(dcr, offset, whence);
case B_FILE_DEV:
- return ::lseek(fd, offset, whence);
- }
+#if defined(HAVE_WIN32)
+ return ::_lseeki64(fd, (__int64)offset, whence);
+#else
+ return ::lseek(fd, (off_t)offset, whence);
+#endif
+ }
return -1;
}
bool scan_dir_for_volume(DCR *dcr); /* in scan.c */
bool reposition(DCR *dcr, uint32_t rfile, uint32_t rblock); /* in dev.c */
void clrerror(int func); /* in dev.c */
- off_t lseek(DCR *dcr, off_t offset, int whence); /* in dev.c */
+ boffset_t lseek(DCR *dcr, boffset_t offset, int whence); /* in dev.c */
bool update_pos(DCR *dcr); /* in dev.c */
bool update_freespace(); /* in dvd.c */
{
char partnumber[20];
- if (archive_name.c_str()[strlen(archive_name.c_str())-1] != '/') {
+ if (!IsPathSeparator(archive_name.c_str()[strlen(archive_name.c_str())-1])) {
pm_strcat(archive_name, "/");
}
/*
* Do an lseek on a DVD handling all the different parts
*/
-off_t lseek_dvd(DCR *dcr, off_t offset, int whence)
+boffset_t lseek_dvd(DCR *dcr, boffset_t offset, int whence)
{
DEVICE *dev = dcr->dev;
- off_t pos;
+ boffset_t pos;
char ed1[50], ed2[50];
Dmsg5(400, "Enter lseek_dvd fd=%d off=%s w=%d part=%d nparts=%d\n", dev->fd,
if ((uint64_t)offset == dev->part_start ||
(uint64_t)offset < dev->part_start+dev->part_size) {
/* We are staying in the current part, just seek */
- if ((pos = lseek(dev->fd, offset-dev->part_start, SEEK_SET)) < 0) {
+#if defined(HAVE_WIN32)
+ pos = _lseeki64(dev->fd, offset-dev->part_start, SEEK_SET);
+#else
+ pos = lseek(dev->fd, offset-dev->part_start, SEEK_SET);
+#endif
+ if (pos < 0) {
return pos;
} else {
return pos + dev->part_start;
/* Found a file, checking it is empty */
POOL_MEM filename(PM_FNAME);
pm_strcpy(filename, dev->device->mount_point);
- if (filename.c_str()[strlen(filename.c_str())-1] != '/') {
+ if (!IsPathSeparator(filename.c_str()[strlen(filename.c_str())-1])) {
pm_strcat(filename, "/");
}
pm_strcat(filename, result->d_name);
bool truncate_dvd(DCR *dcr);
bool check_can_write_on_non_blank_dvd(DCR *dcr);
int find_num_dvd_parts(DCR *dcr);
-off_t lseek_dvd(DCR *dcr, off_t offset, int whence);
+boffset_t lseek_dvd(DCR *dcr, boffset_t offset, int whence);
void dvd_remove_empty_part(DCR *dcr);
/* From device.c */
len = strlen(mount_point);
if (len > 0) {
- need_slash = mount_point[len - 1] != '/';
+ need_slash = !IsPathSeparator(mount_point[len - 1]);
}
entry = (struct dirent *)malloc(sizeof(struct dirent) + name_max + 1000);
for ( ;; ) {
if (stat != (ssize_t)sizeof(hdr)) {
/* If we wrote something, truncate it, then despool */
if (stat != -1) {
- if (ftruncate(dcr->spool_fd, lseek(dcr->spool_fd, (off_t)0, SEEK_CUR) - stat) != 0) {
+#if defined(HAVE_WIN32)
+ boffset_t pos = _lseeki64(dcr->spool_fd, (__int64)0, SEEK_CUR);
+#else
+ boffset_t pos = lseek(dcr->spool_fd, (off_t)0, SEEK_CUR);
+#endif
+ if (ftruncate(dcr->spool_fd, pos - stat) != 0) {
berrno be;
Jmsg(dcr->jcr, M_FATAL, 0, _("Ftruncate spool file failed: ERR=%s\n"),
be.strerror());
* If we wrote something, truncate it and the header, then despool
*/
if (stat != -1) {
- if (ftruncate(dcr->spool_fd, lseek(dcr->spool_fd, (off_t)0, SEEK_CUR)
- - stat - sizeof(spool_hdr)) != 0) {
+#if defined(HAVE_WIN32)
+ boffset_t pos = _lseeki64(dcr->spool_fd, (__int64)0, SEEK_CUR);
+#else
+ boffset_t pos = lseek(dcr->spool_fd, (off_t)0, SEEK_CUR);
+#endif
+ if (ftruncate(dcr->spool_fd, pos - stat - sizeof(spool_hdr)) != 0) {
berrno be;
Jmsg(dcr->jcr, M_FATAL, 0, _("Ftruncate spool file failed: ERR=%s\n"),
be.strerror());
pm_strcpy(cleanup, "/bin/rm -f ");
#endif
pm_strcat(cleanup, me->working_directory);
- if (len > 0 && me->working_directory[len-1] != '/'
-#if defined(HAVE_WIN32)
- && me->working_directory[len-1] != '\\'
-#endif
- ) {
+ if (len > 0 && !IsPathSeparator(me->working_directory[len-1])) {
pm_strcat(cleanup, "/");
}
pm_strcat(cleanup, my_name);
printf("%s\n", db_strerror(db));
}
/* Strip trailing slash(es) */
- for (len=strlen(name); len > 0 && name[len-1]=='/'; len--)
+ for (len=strlen(name); len > 0 && IsPathSeparator(name[len-1]); len--)
{ }
if (len == 0) {
len = 1;
* must be a path name (e.g. c:).
*/
for (p=l=ar->fname; *p; p++) {
- if (*p == '/') {
+ if (IsPathSeparator(*p)) {
l = p; /* set pos of last slash */
}
}
- if (*l == '/') { /* did we find a slash? */
+ if (IsPathSeparator(*l)) { /* did we find a slash? */
l++; /* yes, point to filename */
} else { /* no, whole thing must be path name */
l = p;