static int iconv_chmod(const char *path, mode_t mode) { struct iconv *ic = iconv_get(); char *newpath; int err = iconv_convpath(ic, path, &newpath, 0); if (!err) { err = fuse_fs_chmod(ic->next, newpath, mode); free(newpath); } return err; }
static int iconv_getattr(const char *path, struct stat *stbuf) { struct iconv *ic = iconv_get(); char *newpath; int err = iconv_convpath(ic, path, &newpath, 0); if (!err) { err = fuse_fs_getattr(ic->next, newpath, stbuf); free(newpath); } return err; }
static int iconv_setcrtime(const char *path, const struct timespec *crtime) { struct iconv *ic = iconv_get(); char *newpath; int err = iconv_convpath(ic, path, &newpath, 0); if (!err) { err = fuse_fs_setcrtime(ic->next, newpath, crtime); free(newpath); } return err; }
static int iconv_listxattr(const char *path, char *list, size_t size) { struct iconv *ic = iconv_get(); char *newpath; int err = iconv_convpath(ic, path, &newpath, 0); if (!err) { err = fuse_fs_listxattr(ic->next, newpath, list, size); free(newpath); } return err; }
static int iconv_chown(const char *path, uid_t uid, gid_t gid) { struct iconv *ic = iconv_get(); char *newpath; int err = iconv_convpath(ic, path, &newpath, 0); if (!err) { err = fuse_fs_chown(ic->next, newpath, uid, gid); free(newpath); } return err; }
static int iconv_truncate(const char *path, off_t size) { struct iconv *ic = iconv_get(); char *newpath; int err = iconv_convpath(ic, path, &newpath, 0); if (!err) { err = fuse_fs_truncate(ic->next, newpath, size); free(newpath); } return err; }
static int iconv_release(const char *path, struct fuse_file_info *fi) { struct iconv *ic = iconv_get(); char *newpath; int err = iconv_convpath(ic, path, &newpath, 0); if (!err) { err = fuse_fs_release(ic->next, newpath, fi); free(newpath); } return err; }
static int iconv_utimens(const char *path, const struct timespec ts[2]) { struct iconv *ic = iconv_get(); char *newpath; int err = iconv_convpath(ic, path, &newpath, 0); if (!err) { err = fuse_fs_utimens(ic->next, newpath, ts); free(newpath); } return err; }
static int iconv_setvolname(const char *volname) { struct iconv *ic = iconv_get(); char *newvolname; int err = iconv_convpath(ic, volname, &newvolname, 0); if (!err) { err = fuse_fs_setvolname(ic->next, newvolname); free(newvolname); } return err; }
static int iconv_chflags(const char *path, uint32_t flags) { struct iconv *ic = iconv_get(); char *newpath; int err = iconv_convpath(ic, path, &newpath, 0); if (!err) { err = fuse_fs_chflags(ic->next, newpath, flags); free(newpath); } return err; }
static int iconv_access(const char *path, int mask) { struct iconv *ic = iconv_get(); char *newpath; int err = iconv_convpath(ic, path, &newpath, 0); if (!err) { err = fuse_fs_access(ic->next, newpath, mask); free(newpath); } return err; }
static int iconv_removexattr(const char *path, const char *name) { struct iconv *ic = iconv_get(); char *newpath; int err = iconv_convpath(ic, path, &newpath, 0); if (!err) { err = fuse_fs_removexattr(ic->next, newpath, name); free(newpath); } return err; }
static int iconv_bmap(const char *path, size_t blocksize, uint64_t *idx) { struct iconv *ic = iconv_get(); char *newpath; int err = iconv_convpath(ic, path, &newpath, 0); if (!err) { err = fuse_fs_bmap(ic->next, newpath, blocksize, idx); free(newpath); } return err; }
static int iconv_fsyncdir(const char *path, int isdatasync, struct fuse_file_info *fi) { struct iconv *ic = iconv_get(); char *newpath; int err = iconv_convpath(ic, path, &newpath, 0); if (!err) { err = fuse_fs_fsyncdir(ic->next, newpath, isdatasync, fi); free(newpath); } return err; }
static int iconv_write(const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { struct iconv *ic = iconv_get(); char *newpath; int err = iconv_convpath(ic, path, &newpath, 0); if (!err) { err = fuse_fs_write(ic->next, newpath, buf, size, offset, fi); free(newpath); } return err; }
static int iconv_lock(const char *path, struct fuse_file_info *fi, int cmd, struct flock *lock) { struct iconv *ic = iconv_get(); char *newpath; int err = iconv_convpath(ic, path, &newpath, 0); if (!err) { err = fuse_fs_lock(ic->next, newpath, fi, cmd, lock); free(newpath); } return err; }
static int iconv_setxattr(const char *path, const char *name, const char *value, size_t size, int flags) { struct iconv *ic = iconv_get(); char *newpath; int err = iconv_convpath(ic, path, &newpath, 0); if (!err) { err = fuse_fs_setxattr(ic->next, newpath, name, value, size, flags); free(newpath); } return err; }
static int iconv_link(const char *from, const char *to) { struct iconv *ic = iconv_get(); char *newfrom; char *newto; int err = iconv_convpath(ic, from, &newfrom, 0); if (!err) { err = iconv_convpath(ic, to, &newto, 0); if (!err) { err = fuse_fs_link(ic->next, newfrom, newto); free(newto); } free(newfrom); } return err; }
static int iconv_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi) { struct iconv *ic = iconv_get(); char *newpath; int err = iconv_convpath(ic, path, &newpath, 0); if (!err) { struct iconv_dh dh; dh.ic = ic; dh.prev_buf = buf; dh.prev_filler = filler; err = fuse_fs_readdir(ic->next, newpath, &dh, iconv_dir_fill, offset, fi); free(newpath); } return err; }
static int iconv_getxattr(const char *path, const char *name, char *value, size_t size) #endif /* __APPLE__ */ { struct iconv *ic = iconv_get(); char *newpath; int err = iconv_convpath(ic, path, &newpath, 0); if (!err) { #ifdef __APPLE__ err = fuse_fs_getxattr(ic->next, newpath, name, value, size, position); #else err = fuse_fs_getxattr(ic->next, newpath, name, value, size); #endif /* __APPLE__ */ free(newpath); } return err; }
static int iconv_exchange(const char *path1, const char *path2, unsigned long options) { struct iconv *ic = iconv_get(); char *new1; char *new2; int err = iconv_convpath(ic, path1, &new1, 0); if (!err) { err = iconv_convpath(ic, path2, &new2, 0); if (!err) { err = fuse_fs_exchange(ic->next, new1, new2, options); free(new1); } free(new2); } return err; }
static int iconv_readlink(const char *path, char *buf, size_t size) { struct iconv *ic = iconv_get(); char *newpath; int err = iconv_convpath(ic, path, &newpath, 0); if (!err) { err = fuse_fs_readlink(ic->next, newpath, buf, size); if (!err) { char *newlink; err = iconv_convpath(ic, buf, &newlink, 1); if (!err) { strncpy(buf, newlink, size - 1); buf[size - 1] = '\0'; free(newlink); } } free(newpath); } return err; }
static void convertWithIConv(struct OMRPortLibrary *portLibrary, char *error, char *errBuf, uintptr_t bufLen) { iconv_t converter; size_t inbytesleft, outbytesleft; char *inbuf, *outbuf; converter = iconv_get(portLibrary, J9SL_ICONV_DESCRIPTOR, "UTF-8", nl_langinfo(CODESET)); if (J9VM_INVALID_ICONV_DESCRIPTOR == converter) { /* no converter available for this code set. Just dump the platform chars */ strncpy(errBuf, error, bufLen); errBuf[bufLen - 1] = '\0'; return; } inbuf = (char *)error; /* for some reason this argument isn't const */ outbuf = errBuf; inbytesleft = strlen(error); outbytesleft = bufLen - 1; while ((outbytesleft > 0) && (inbytesleft > 0)) { if ((size_t)-1 == iconv(converter, &inbuf, &inbytesleft, &outbuf, &outbytesleft)) { if (E2BIG == errno) { break; } /* if we couldn't translate this character, copy one byte verbatim */ *outbuf = *inbuf; outbuf++; inbuf++; inbytesleft--; outbytesleft--; } } *outbuf = '\0'; iconv_free(portLibrary, J9SL_ICONV_DESCRIPTOR, converter); }
static void *iconv_init(struct fuse_conn_info *conn) { struct iconv *ic = iconv_get(); fuse_fs_init(ic->next, conn); return ic; }
static intptr_t file_write_using_iconv(struct OMRPortLibrary *portLibrary, intptr_t fd, const char *buf, intptr_t nbytes) { intptr_t result = 0; char stackBuf[512]; char *bufStart = NULL; uintptr_t outBufLen = sizeof(stackBuf); iconv_t converter = J9VM_INVALID_ICONV_DESCRIPTOR; size_t inbytesleft = 0; size_t outbytesleft = 0; char *inbuf = NULL; char *outbuf = NULL; intptr_t bytesToWrite = 0; #ifdef J9ZOS390 /* LIR 1280 (z/OS only) - every failed call to iconv_open() is recorded on the operator console, so don't retry */ if (FALSE == PPG_file_text_iconv_open_failed) { /* iconv_get is not an a2e function, so we need to pass it honest-to-goodness EBCDIC strings */ #pragma convlit(suspend) #endif #ifndef OMRZTPF converter = iconv_get(portLibrary, J9FILETEXT_ICONV_DESCRIPTOR, nl_langinfo(CODESET), "UTF-8"); #else converter = iconv_get(portLibrary, J9FILETEXT_ICONV_DESCRIPTOR, "IBM1047", "ISO8859-1" ); #endif #ifdef J9ZOS390 #pragma convlit(resume) if (J9VM_INVALID_ICONV_DESCRIPTOR == converter) { PPG_file_text_iconv_open_failed = TRUE; } } #endif if (J9VM_INVALID_ICONV_DESCRIPTOR == converter) { /* no converter available for this code set. Just dump the UTF-8 chars */ result = portLibrary->file_write(portLibrary, fd, (void *)buf, nbytes); return (result == nbytes) ? 0 : result; } inbuf = (char *)buf; /* for some reason this argument isn't const */ outbuf = bufStart = stackBuf; inbytesleft = nbytes; outbytesleft = sizeof(stackBuf); while ((size_t)-1 == iconv(converter, &inbuf, &inbytesleft, &outbuf, &outbytesleft)) { int tmp_errno = errno; if (inbytesleft == 0) { break; } if ((outbytesleft == 0) || (tmp_errno == E2BIG)) { /* input conversion stopped due to lack of space in the output buffer */ if (growBuffer(portLibrary, stackBuf, &bufStart, &outbuf, &outbytesleft, &outBufLen) < 0) { /* failed to grow buffer, just output what we've got so far */ break; } } else if (tmp_errno == EILSEQ) { /* input conversion stopped due to an input byte that does not belong to the input code set */ const char *unicodeFormat = "\\u%04x"; #define J9FILETEXT_ESCAPE_STR_SIZE 6 /* max size of unicode format */ char escapedStr[J9FILETEXT_ESCAPE_STR_SIZE]; char *escapedStrStart = escapedStr; uint16_t unicodeC = 0; size_t escapedLength = 0; size_t utf8Length = decodeUTF8CharN((const uint8_t *)inbuf, &unicodeC, inbytesleft); if (utf8Length == 0) { /* invalid encoding, including 4-byte UTF-8 */ utf8Length = 1; escapedLength = 1; escapedStr[0] = '?'; } else { escapedLength = portLibrary->str_printf(portLibrary, escapedStr, J9FILETEXT_ESCAPE_STR_SIZE, unicodeFormat, (uintptr_t)unicodeC); } inbytesleft -= utf8Length; inbuf += utf8Length; if ((size_t)-1 == iconv(converter, &escapedStrStart, &escapedLength, &outbuf, &outbytesleft)) { /* not handling EILSEQ here because: * 1. we can't do much if iconv() fails to convert ascii. * 2. inbuf and inbytesleft have been explicitly updated so the while loop will get terminated after converting the rest of the characters. */ tmp_errno = errno; /* if the remaining outbuf is too small, then grow it before storing Unicode string representation */ if (tmp_errno == E2BIG) { if (growBuffer(portLibrary, stackBuf, &bufStart, &outbuf, &outbytesleft, &outBufLen) < 0) { /* failed to grow buffer, just output what we've got so far */ break; } } } } else { /* input conversion stopped due to an incomplete character or shift sequence at the end of the input buffer */ break; } } iconv_free(portLibrary, J9FILETEXT_ICONV_DESCRIPTOR, converter); /* CMVC 152575 - the converted string is not necessarily the same length in bytes as the original string */ bytesToWrite = outbuf - bufStart; result = portLibrary->file_write(portLibrary, fd, (void *)bufStart, bytesToWrite); if (bufStart != stackBuf) { portLibrary->mem_free_memory(portLibrary, bufStart); } return (result == bytesToWrite) ? 0 : result; }