void vfs_s_invalidate (struct vfs_class *me, struct vfs_s_super *super) { if (!super->want_stale){ vfs_s_free_inode (me, super->root); super->root = vfs_s_new_inode (me, super, vfs_s_default_stat (me, S_IFDIR | 0755)); } }
struct vfs_s_entry * vfs_s_generate_entry (struct vfs_class *me, const char *name, struct vfs_s_inode *parent, mode_t mode) { struct vfs_s_inode *inode; struct stat *st; st = vfs_s_default_stat (me, mode); inode = vfs_s_new_inode (me, parent->super, st); return vfs_s_new_entry (me, name, inode); }
/* Returns fd of the open tar file */ static int tar_open_archive (vfs *me, char *name, vfs_s_super *archive) { int result, type; long size; mode_t mode; struct vfs_s_inode *root; result = mc_open (name, O_RDONLY); if (result == -1) { message_2s (1, MSG_ERROR, _("Couldn't open tar archive\n%s"), name); ERRNOR (ENOENT, -1); } archive->name = strdup (name); mc_stat (name, &(archive->u.tar.tarstat)); archive->u.tar.fd = -1; /* Find out the method to handle this tar file */ size = is_gunzipable (result, &type); mc_lseek (result, 0, SEEK_SET); if (size > 0) { char *s; mc_close( result ); s = copy_strings( archive->name, decompress_extension (type), NULL ); result = mc_open (s, O_RDONLY); if (result == -1) message_2s (1, MSG_ERROR, _("Couldn't open tar archive\n%s"), s); free(s); if (result == -1) ERRNOR (ENOENT, -1); } archive->u.tar.fd = result; mode = archive->u.tar.tarstat.st_mode & 07777; if (mode & 0400) mode |= 0100; if (mode & 0040) mode |= 0010; if (mode & 0004) mode |= 0001; mode |= S_IFDIR; root = vfs_s_new_inode (me, archive, &archive->u.tar.tarstat); root->st.st_mode = mode; root->u.tar.data_offset = -1; root->st.st_nlink++; root->st.st_dev = MEDATA->rdev++; vfs_s_add_dots (me, root, NULL); archive->root = root; return result; }
/* @Before */ static void setup (void) { static struct stat initstat; str_init_strings (NULL); vfs_init (); init_localfs (); vfs_setup_work_dir (); test_subclass1.flags = VFS_S_REMOTE; vfs_s_init_class (&vfs_test_ops1, &test_subclass1); vfs_test_ops1.name = "testfs1"; vfs_test_ops1.flags = VFSF_NOLINKS; vfs_test_ops1.prefix = "test1:"; vfs_register_class (&vfs_test_ops1); vfs_test_super = g_new0 (struct vfs_s_super, 1); vfs_test_super->me = &vfs_test_ops1; vfs_root_inode = vfs_s_new_inode (&vfs_test_ops1, vfs_test_super, &initstat); vfs_root_entry = vfs_s_new_entry (&vfs_test_ops1, "/", vfs_root_inode); }
static struct vfs_s_entry * vfs_s_find_entry_linear (struct vfs_class *me, struct vfs_s_inode *root, const char *a_path, int follow, int flags) { struct vfs_s_entry *ent = NULL; char * const path = g_strdup (a_path); struct vfs_s_entry *retval = NULL; if (root->super->root != root) vfs_die ("We have to use _real_ root. Always. Sorry."); canonicalize_pathname (path); if (!(flags & FL_DIR)) { char *dirname, *name, *save; struct vfs_s_inode *ino; split_dir_name (me, path, &dirname, &name, &save); ino = vfs_s_find_inode (me, root->super, dirname, follow, flags | FL_DIR); if (save) *save = PATH_SEP; retval = vfs_s_find_entry_tree (me, ino, name, follow, flags); g_free (path); return retval; } for (ent = root->subdir; ent != NULL; ent = ent->next) if (!strcmp (ent->name, path)) break; if (ent && (!(MEDATA->dir_uptodate) (me, ent->ino))) { #if 1 print_vfs_message (_("Directory cache expired for %s"), path); #endif vfs_s_free_entry (me, ent); ent = NULL; } if (!ent) { struct vfs_s_inode *ino; ino = vfs_s_new_inode (me, root->super, vfs_s_default_stat (me, S_IFDIR | 0755)); ent = vfs_s_new_entry (me, path, ino); if ((MEDATA->dir_load) (me, ino, path) == -1) { vfs_s_free_entry (me, ent); g_free (path); return NULL; } vfs_s_insert_entry (me, root, ent); for (ent = root->subdir; ent != NULL; ent = ent->next) if (!strcmp (ent->name, path)) break; } if (!ent) vfs_die ("find_linear: success but directory is not there\n"); #if 0 if (!vfs_s_resolve_symlink (me, ent, follow)) { g_free (path); return NULL; } #endif g_free (path); return ent; }
static int fish_open_archive_int (struct vfs_class *me, struct vfs_s_super *super) { { const char *argv[10]; const int port_num = SUP.flags & 0xFFFF; const int sh_flags = SUP.flags & ~0xFFFF; const char *xsh = (sh_flags == FISH_FLAG_RSH ? "rsh" : "ssh"); char buf[8]; int i = 0; argv[i++] = xsh; if (sh_flags == FISH_FLAG_COMPRESSED) argv[i++] = "-C"; if (port_num) { sprintf(buf, "%d", port_num); argv[i++] = "-p"; argv[i++] = buf; } argv[i++] = "-l"; argv[i++] = SUP.user; argv[i++] = SUP.host; argv[i++] = "echo FISH:; /bin/sh"; argv[i++] = NULL; fish_pipeopen (super, xsh, argv); } { char answer[2048]; print_vfs_message (_("fish: Waiting for initial line...")); if (!vfs_s_get_line (me, SUP.sockr, answer, sizeof (answer), ':')) ERRNOR (E_PROTO, -1); print_vfs_message ("%s", answer); if (strstr (answer, "assword")) { /* Currently, this does not work. ssh reads passwords from /dev/tty, not from stdin :-(. */ message (1, MSG_ERROR, _ ("Sorry, we cannot do password authenticated connections for now.")); ERRNOR (EPERM, -1); if (!SUP.password) { char *p, *op; p = g_strconcat (_(" fish: Password required for "), SUP.user, " ", (char *) NULL); op = vfs_get_password (p); g_free (p); if (op == NULL) ERRNOR (EPERM, -1); SUP.password = op; } print_vfs_message (_("fish: Sending password...")); write (SUP.sockw, SUP.password, strlen (SUP.password)); write (SUP.sockw, "\n", 1); } } print_vfs_message (_("fish: Sending initial line...")); /* * Run `start_fish_server'. If it doesn't exist - no problem, * we'll talk directly to the shell. */ if (fish_command (me, super, WAIT_REPLY, "#FISH\necho; start_fish_server 2>&1; echo '### 200'\n") != COMPLETE) ERRNOR (E_PROTO, -1); print_vfs_message (_("fish: Handshaking version...")); if (fish_command (me, super, WAIT_REPLY, "#VER 0.0.0\necho '### 000'\n") != COMPLETE) ERRNOR (E_PROTO, -1); /* Set up remote locale to C, otherwise dates cannot be recognized */ if (fish_command (me, super, WAIT_REPLY, "LANG=C; LC_ALL=C; LC_TIME=C\n" "export LANG; export LC_ALL; export LC_TIME\n" "echo '### 200'\n") != COMPLETE) ERRNOR (E_PROTO, -1); print_vfs_message (_("fish: Setting up current directory...")); SUP.cwdir = fish_getcwd (me, super); print_vfs_message (_("fish: Connected, home %s."), SUP.cwdir); #if 0 super->name = g_strconcat ("/#sh:", SUP.user, "@", SUP.host, "/", (char *) NULL); #endif super->name = g_strdup (PATH_SEP_STR); super->root = vfs_s_new_inode (me, super, vfs_s_default_stat (me, S_IFDIR | 0755)); return 0; }
/* * Return 1 for success, 0 if the checksum is bad, EOF on eof, * 2 for a record full of zeros (EOF marker). * */ static int read_header (vfs *me, vfs_s_super *archive, int tard) { register int i; register long sum, signed_sum, recsum; register char *p; register union record *header; char **longp; char *bp, *data; int size, written; static char *next_long_name = NULL, *next_long_link = NULL; char *current_file_name, *current_link_name; recurse: header = get_next_record (archive, tard); if (NULL == header) return EOF; recsum = from_oct (8, header->header.chksum); sum = 0; signed_sum = 0; p = header->charptr; for (i = sizeof (*header); --i >= 0;) { /* * We can't use unsigned char here because of old compilers, * e.g. V7. */ signed_sum += *p; sum += 0xFF & *p++; } /* Adjust checksum to count the "chksum" field as blanks. */ for (i = sizeof (header->header.chksum); --i >= 0;) { sum -= 0xFF & header->header.chksum[i]; signed_sum -= (char) header->header.chksum[i]; } sum += ' ' * sizeof header->header.chksum; signed_sum += ' ' * sizeof header->header.chksum; if (sum == 8 * ' ') { /* * This is a zeroed record...whole record is 0's except * for the 8 blanks we faked for the checksum field. */ return 2; } if (sum != recsum && signed_sum != recsum) return 0; /* * linkflag on BSDI tar (pax) always '\000' */ if(header->header.linkflag == '\000' && strlen(header->header.arch_name) && header->header.arch_name[strlen(header->header.arch_name) - 1] == '/') header->header.linkflag = LF_DIR; /* * Good record. Decode file size and return. */ if (header->header.linkflag == LF_LINK || header->header.linkflag == LF_DIR) hstat.st_size = 0; /* Links 0 size on tape */ else hstat.st_size = from_oct (1 + 12, header->header.size); header->header.arch_name[NAMSIZ - 1] = '\0'; if (header->header.linkflag == LF_LONGNAME || header->header.linkflag == LF_LONGLINK) { longp = ((header->header.linkflag == LF_LONGNAME) ? &next_long_name : &next_long_link); if (*longp) free (*longp); bp = *longp = (char *) xmalloc (hstat.st_size, "Tar: Long name"); for (size = hstat.st_size; size > 0; size -= written) { data = get_next_record (archive, tard)->charptr; if (data == NULL) { message_1s (1, MSG_ERROR, _("Unexpected EOF on archive file")); return 0; } written = RECORDSIZE; if (written > size) written = size; bcopy (data, bp, written); bp += written; } #if 0 if (hstat.st_size > 1) bp [hstat.st_size - 1] = 0; /* just to make sure */ #endif goto recurse; } else { struct stat st; struct vfs_s_entry *entry; struct vfs_s_inode *inode, *parent; long data_position; char *p, *q; int len; int isdir = 0; current_file_name = (next_long_name ? next_long_name : strdup (header->header.arch_name)); len = strlen (current_file_name); if (current_file_name[len - 1] == '/') { current_file_name[len - 1] = 0; isdir = 1; } current_link_name = (next_long_link ? next_long_link : strdup (header->header.arch_linkname)); len = strlen (current_link_name); if (len && current_link_name [len - 1] == '/') current_link_name[len - 1] = 0; next_long_link = next_long_name = NULL; data_position = current_tar_position; p = strrchr (current_file_name, '/'); if (p == NULL) { p = current_file_name; q = current_file_name + strlen (current_file_name); /* "" */ } else { *(p++) = 0; q = current_file_name; } parent = vfs_s_find_inode (me, archive->root, q, LINK_NO_FOLLOW, FL_MKDIR); if (parent == NULL) { message_1s (1, MSG_ERROR, _("Inconsistent tar archive")); return 0; } if (header->header.linkflag == LF_LINK) { parent = vfs_s_find_inode (me, archive->root, current_link_name, LINK_NO_FOLLOW, 0); if (parent == NULL) { message_1s (1, MSG_ERROR, _("Inconsistent tar archive")); } else { inode = parent; entry = vfs_s_new_entry(me, p, inode); vfs_s_insert_entry(me, parent, entry); free (current_link_name); goto done; } } fill_stat_from_header (me, &st, header); inode = vfs_s_new_inode (me, archive, &st); inode->u.tar.data_offset = data_position; if (*current_link_name) inode->linkname = current_link_name; entry = vfs_s_new_entry (me, p, inode); vfs_s_insert_entry (me, parent, entry); free (current_file_name); done: if (header->header.isextended) { while (get_next_record (archive, tard)->ext_hdr.isextended); inode->u.tar.data_offset = current_tar_position; } return 1; } }