static int fish_linear_start (struct vfs_class *me, struct vfs_s_fh *fh, off_t offset) { char *name; char *quoted_name; if (offset) ERRNOR (E_NOTSUPP, 0); name = vfs_s_fullpath (me, fh->ino); if (!name) return 0; quoted_name = name_quote (name, 0); g_free (name); name = quoted_name; fh->u.fish.append = 0; offset = fish_command (me, FH_SUPER, WANT_STRING, "#RETR /%s\n" "if dd if=/%s of=/dev/null bs=1 count=1 2>/dev/null; then\n" "ls -ln /%s 2>/dev/null | (\n" "read p l u g s r\n" "echo \"$s\"\n" ")\n" "echo '### 100'\n" "cat /%s\n" "echo '### 200'\n" "else\n" "echo '### 500'\n" "fi\n", name, name, name, name ); g_free (name); if (offset != PRELIM) ERRNOR (E_REMOTE, 0); fh->linear = LS_LINEAR_OPEN; fh->u.fish.got = 0; #if SIZEOF_OFF_T > SIZEOF_INT if (sscanf( reply_str, "%llu", &fh->u.fish.total )!=1) #else if (sscanf( reply_str, "%u", &fh->u.fish.total )!=1) #endif ERRNOR (E_REMOTE, 0); return 1; }
/* If the entry is a symlink, find the entry for its target */ static struct vfs_s_entry * vfs_s_resolve_symlink (struct vfs_class *me, struct vfs_s_entry *entry, int follow) { char *linkname; char *fullname = NULL; struct vfs_s_entry *target; if (follow == LINK_NO_FOLLOW) return entry; if (follow == 0) ERRNOR (ELOOP, NULL); if (!entry) ERRNOR (ENOENT, NULL); if (!S_ISLNK (entry->ino->st.st_mode)) return entry; linkname = entry->ino->linkname; if (linkname == NULL) ERRNOR (EFAULT, NULL); /* make full path from relative */ if (*linkname != PATH_SEP) { char *fullpath = vfs_s_fullpath (me, entry->dir); if (fullpath) { fullname = g_strconcat (fullpath, "/", linkname, NULL); linkname = fullname; g_free (fullpath); } } target = (MEDATA->find_entry) (me, entry->dir->super->root, linkname, follow - 1, 0); g_free (fullname); return target; }
gboolean sftpfs_open_file (vfs_file_handler_t * file_handler, int flags, mode_t mode, GError ** error) { unsigned long sftp_open_flags = 0; int sftp_open_mode = 0; gboolean do_append = FALSE; sftpfs_file_handler_data_t *file_handler_data; sftpfs_super_data_t *super_data; char *name; (void) mode; name = vfs_s_fullpath (&sftpfs_class, file_handler->ino); if (name == NULL) return FALSE; super_data = (sftpfs_super_data_t *) file_handler->ino->super->data; file_handler_data = g_new0 (sftpfs_file_handler_data_t, 1); if ((flags & O_CREAT) != 0 || (flags & O_WRONLY) != 0) { sftp_open_flags = (flags & O_WRONLY) != 0 ? LIBSSH2_FXF_WRITE : 0; sftp_open_flags |= (flags & O_CREAT) != 0 ? LIBSSH2_FXF_CREAT : 0; if ((flags & O_APPEND) != 0) { sftp_open_flags |= LIBSSH2_FXF_APPEND; do_append = TRUE; } sftp_open_flags |= (flags & O_TRUNC) != 0 ? LIBSSH2_FXF_TRUNC : 0; sftp_open_mode = LIBSSH2_SFTP_S_IRUSR | LIBSSH2_SFTP_S_IWUSR | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IROTH; } else sftp_open_flags = LIBSSH2_FXF_READ; while (TRUE) { int libssh_errno; file_handler_data->handle = libssh2_sftp_open (super_data->sftp_session, sftpfs_fix_filename (name), sftp_open_flags, sftp_open_mode); if (file_handler_data->handle != NULL) break; libssh_errno = libssh2_session_last_errno (super_data->session); if (libssh_errno != LIBSSH2_ERROR_EAGAIN) { sftpfs_ssherror_to_gliberror (super_data, libssh_errno, error); g_free (name); g_free (file_handler_data); return FALSE; } } g_free (name); file_handler_data->flags = flags; file_handler_data->mode = mode; file_handler->data = file_handler_data; if (do_append) { struct stat file_info; if (sftpfs_fstat (file_handler, &file_info, error) == 0) libssh2_sftp_seek64 (file_handler_data->handle, file_info.st_size); } return TRUE; }