static int set_timefilter_date_w(struct archive_match *a, int timetype, const wchar_t *datestr) { struct archive_string as; time_t t; if (datestr == NULL || *datestr == L'\0') { archive_set_error(&(a->archive), EINVAL, "date is empty"); return (ARCHIVE_FAILED); } archive_string_init(&as); if (archive_string_append_from_wcs(&as, datestr, wcslen(datestr)) < 0) { archive_string_free(&as); if (errno == ENOMEM) return (error_nomem(a)); archive_set_error(&(a->archive), -1, "Failed to convert WCS to MBS"); return (ARCHIVE_FAILED); } t = get_date(a->now, as.s); archive_string_free(&as); if (t == (time_t)-1) { archive_set_error(&(a->archive), EINVAL, "invalid date string"); return (ARCHIVE_FAILED); } return set_timefilter(a, timetype, t, 0, t, 0); }
static int set_timefilter_pathname_wcs(struct archive_match *a, int timetype, const wchar_t *path) { struct archive_string as; int r; if (path == NULL || *path == L'\0') { archive_set_error(&(a->archive), EINVAL, "pathname is empty"); return (ARCHIVE_FAILED); } /* Convert WCS filename to MBS filename. */ archive_string_init(&as); if (archive_string_append_from_wcs(&as, path, wcslen(path)) < 0) { archive_string_free(&as); if (errno == ENOMEM) return (error_nomem(a)); archive_set_error(&(a->archive), -1, "Failed to convert WCS to MBS"); return (ARCHIVE_FAILED); } r = set_timefilter_pathname_mbs(a, timetype, as.s); archive_string_free(&as); return (r); }
int archive_read_open_filename_w(struct archive *a, const wchar_t *wfilename, size_t block_size) { struct read_file_data *mine = (struct read_file_data *)calloc(1, sizeof(*mine) + wcslen(wfilename) * sizeof(wchar_t)); if (!mine) { archive_set_error(a, ENOMEM, "No memory"); return (ARCHIVE_FATAL); } mine->fd = -1; mine->block_size = block_size; if (wfilename == NULL || wfilename[0] == L'\0') { mine->filename_type = FNT_STDIN; } else { #if defined(_WIN32) && !defined(__CYGWIN__) mine->filename_type = FNT_WCS; wcscpy(mine->filename.w, wfilename); #else /* * POSIX system does not support a wchar_t interface for * open() system call, so we have to translate a whcar_t * filename to multi-byte one and use it. */ struct archive_string fn; archive_string_init(&fn); if (archive_string_append_from_wcs(&fn, wfilename, wcslen(wfilename)) != 0) { if (errno == ENOMEM) archive_set_error(a, errno, "Can't allocate memory"); else archive_set_error(a, EINVAL, "Failed to convert a wide-character" " filename to a multi-byte filename"); archive_string_free(&fn); free(mine); return (ARCHIVE_FATAL); } mine->filename_type = FNT_MBS; strcpy(mine->filename.m, fn.s); archive_string_free(&fn); #endif } if (archive_read_append_callback_data(a, mine) != (ARCHIVE_OK)) return (ARCHIVE_FATAL); archive_read_set_open_callback(a, file_open); archive_read_set_read_callback(a, file_read); archive_read_set_skip_callback(a, file_skip); archive_read_set_close_callback(a, file_close); archive_read_set_switch_callback(a, file_switch); archive_read_set_seek_callback(a, file_seek); return (archive_read_open1(a)); }
int archive_read_open_filename_w(struct archive *a, const wchar_t *wfilename, size_t block_size) { enum fnt_e filename_type; if (wfilename == NULL || wfilename[0] == L'\0') { filename_type = FNT_STDIN; } else { #if defined(_WIN32) && !defined(__CYGWIN__) filename_type = FNT_WCS; #else /* * POSIX system does not support a wchar_t interface for * open() system call, so we have to translate a whcar_t * filename to multi-byte one and use it. */ struct archive_string fn; int r; archive_string_init(&fn); if (archive_string_append_from_wcs(&fn, wfilename, wcslen(wfilename)) != 0) { if (errno == ENOMEM) archive_set_error(a, errno, "Can't allocate memory"); else archive_set_error(a, EINVAL, "Failed to convert a wide-character" " filename to a multi-byte filename"); archive_string_free(&fn); return (ARCHIVE_FATAL); } r = file_open_filename(a, FNT_MBS, fn.s, block_size); archive_string_free(&fn); return (r); #endif } return (file_open_filename(a, filename_type, wfilename, block_size)); }
/* * Like 'vsprintf', but ensures the target is big enough, resizing if * necessary. */ void archive_string_vsprintf(struct archive_string *as, const char *fmt, va_list ap) { char long_flag; intmax_t s; /* Signed integer temp. */ uintmax_t u; /* Unsigned integer temp. */ const char *p, *p2; const wchar_t *pw; if (archive_string_ensure(as, 64) == NULL) __archive_errx(1, "Out of memory"); if (fmt == NULL) { as->s[0] = 0; return; } for (p = fmt; *p != '\0'; p++) { const char *saved_p = p; if (*p != '%') { archive_strappend_char(as, *p); continue; } p++; long_flag = '\0'; switch(*p) { case 'j': case 'l': case 'z': long_flag = *p; p++; break; } switch (*p) { case '%': archive_strappend_char(as, '%'); break; case 'c': s = va_arg(ap, int); archive_strappend_char(as, (char)s); break; case 'd': switch(long_flag) { case 'j': s = va_arg(ap, intmax_t); break; case 'l': s = va_arg(ap, long); break; case 'z': s = va_arg(ap, ssize_t); break; default: s = va_arg(ap, int); break; } append_int(as, s, 10); break; case 's': switch(long_flag) { case 'l': pw = va_arg(ap, wchar_t *); if (pw == NULL) pw = L"(null)"; if (archive_string_append_from_wcs(as, pw, wcslen(pw)) != 0 && errno == ENOMEM) __archive_errx(1, "Out of memory"); break; default: p2 = va_arg(ap, char *); if (p2 == NULL) p2 = "(null)"; archive_strcat(as, p2); break; } break; case 'S': pw = va_arg(ap, wchar_t *); if (pw == NULL) pw = L"(null)"; if (archive_string_append_from_wcs(as, pw, wcslen(pw)) != 0 && errno == ENOMEM) __archive_errx(1, "Out of memory"); break; case 'o': case 'u': case 'x': case 'X': /* Common handling for unsigned integer formats. */ switch(long_flag) { case 'j': u = va_arg(ap, uintmax_t); break; case 'l': u = va_arg(ap, unsigned long); break; case 'z': u = va_arg(ap, size_t); break; default: u = va_arg(ap, unsigned int); break; } /* Format it in the correct base. */ switch (*p) { case 'o': append_uint(as, u, 8); break; case 'u': append_uint(as, u, 10); break; default: append_uint(as, u, 16); break; } break; default: /* Rewind and print the initial '%' literally. */ p = saved_p; archive_strappend_char(as, *p); } } }