Index: console-client/ChangeLog =================================================================== RCS file: /cvsroot/hurd/hurd/console-client/ChangeLog,v retrieving revision 1.22 diff -u -u -p -r1.22 ChangeLog --- console-client/ChangeLog 17 Jan 2005 02:00:00 -0000 1.22 +++ console-client/ChangeLog 5 Mar 2005 15:52:59 -0000 @@ -1,3 +1,25 @@ +2005-03-05 Samuel Thibault + + * Makefile (modules): Add `vcs_repeat' and its rule. + * console.c (console_current_id): New function. + * input.h (console_current_id): New prototype. + * trans.c (struct netnode): New member `symlink_path'. + (console_demuxer): Handle case when node it anonymous. + (netfs_S_io_select): Likewise. + (netfs_S_io_read): Likewise. + (netfs_S_io_write): Likewise. + (netfs_report_access): Likewise. + (netfs_attempt_mksymlink): Implement symlinks. + (netfs_attempt_lookup): Likewise. + (netfs_attempt_unlink): Likewise. + (netfs_attempt_link): Likewise. + (netfs_attempt_mkfile): Likewise. + (netfs_attempt_readlink): Likewise. + (netfs_get_dirents): Likewise. + (netfs_create_consnode): Likewise. + * trans.h (struct consnode): New members `readlink' and `mksymlink'. + * vcs-repeat.c: New file. + 2005-01-10 Alfred M. Szmidt * console.c (consnode_path): Renamed to ... Index: console-client/Makefile =================================================================== RCS file: /cvsroot/hurd/hurd/console-client/Makefile,v retrieving revision 1.3 diff -u -u -p -r1.3 Makefile --- console-client/Makefile 6 Jan 2005 21:43:53 -0000 1.3 +++ console-client/Makefile 5 Mar 2005 15:52:59 -0000 @@ -41,7 +41,7 @@ driver-CPPFLAGS = -D'CONSOLE_DEFPATH="$( console: ../libcons/libcons.a ../libports/libports.a \ ../libthreads/libthreads.a ../libshouldbeinlibc/libshouldbeinlibc.a -modules = vga pc_kbd generic_speaker pc_mouse +modules = vga pc_kbd generic_speaker pc_mouse vcs_repeat vga-CPPFLAGS = -DDEFAULT_VGA_FONT_DIR=\"${datadir}/hurd/\" vga.so.$(hurd-version): $(patsubst %.c,%_pic.o,bdf.c vga-dynafont.c \ @@ -49,6 +49,7 @@ vga.so.$(hurd-version): $(patsubst %.c,% pc_kbd.so.$(hurd-version): $(patsubst %.c,%_pic.o,pc-kbd.c kdioctlServer.o kbd-repeat.c) pc_mouse.so.$(hurd-version): $(patsubst %.c,%_pic.o,pc-mouse.c) generic_speaker.so.$(hurd-version): $(patsubst %.c,%_pic.o,generic-speaker.c) +vcs_repeat.so.$(hurd-version): $(patsubst %.c,%_pic.o,vcs-repeat.c) ifneq ($(LIBNCURSESW),) modules += ncursesw Index: console-client/console.c =================================================================== RCS file: /cvsroot/hurd/hurd/console-client/console.c,v retrieving revision 1.6 diff -u -u -p -r1.6 console.c --- console-client/console.c 17 Jan 2005 02:00:00 -0000 1.6 +++ console-client/console.c 5 Mar 2005 15:52:59 -0000 @@ -64,6 +64,24 @@ static char *console_node; /* Callbacks for input source drivers. */ +/* Returns current console ID. */ +error_t +console_current_id (int *cur) +{ + vcons_t vcons; + + mutex_lock (&global_lock); + vcons = active_vcons; + if (!vcons) + { + mutex_unlock (&global_lock); + return ENODEV; + } + *cur = vcons->id; + mutex_unlock (&global_lock); + return 0; +} + /* Switch the active console to console ID or DELTA (relative to the active console). */ error_t Index: console-client/input.h =================================================================== RCS file: /cvsroot/hurd/hurd/console-client/input.h,v retrieving revision 1.2 diff -u -u -p -r1.2 input.h --- console-client/input.h 6 Jan 2005 21:43:53 -0000 1.2 +++ console-client/input.h 5 Mar 2005 15:52:59 -0000 @@ -55,6 +55,9 @@ error_t console_input (char *buf, size_t cons_vcons_scrollback. */ int console_scrollback (cons_scroll_t type, float value); +/* Returns current console ID. */ +error_t console_current_id (int *cur); + /* Switch the active console to console ID or DELTA (relative to the active console). */ error_t console_switch (int id, int delta); Index: console-client/trans.c =================================================================== RCS file: /cvsroot/hurd/hurd/console-client/trans.c,v retrieving revision 1.1 diff -u -u -p -r1.1 trans.c --- console-client/trans.c 6 Jan 2005 21:43:53 -0000 1.1 +++ console-client/trans.c 5 Mar 2005 15:52:59 -0000 @@ -41,6 +41,7 @@ static consnode_t node_list = 0; struct netnode { consnode_t node; + char *symlink_path; }; typedef mach_msg_header_t request_t; @@ -69,7 +70,7 @@ console_demuxer (mach_msg_header_t *inp, return 0; } - if (!ret && user->po->np->nn->node->demuxer) + if (!ret && user->po->np->nn->node && user->po->np->nn->node->demuxer) ret = user->po->np->nn->node->demuxer (inp, outp); ports_port_deref (user); @@ -125,6 +126,15 @@ error_t netfs_attempt_mksymlink (struct iouser *cred, struct node *np, char *name) { + if (!np->nn->node) + { + if (np->nn->symlink_path) + free (np->nn->symlink_path); + np->nn->symlink_path = strdup (name); + return 0; + } + else if (np->nn->node->mksymlink) + return np->nn->node->mksymlink (cred, np, name); return EOPNOTSUPP; } @@ -272,8 +282,18 @@ netfs_attempt_lookup (struct iouser *use nn->node = cn; (*node)->nn_stat = netfs_root_node->nn_stat; - (*node)->nn_stat.st_mode = S_IFCHR | (netfs_root_node->nn_stat.st_mode & ~S_IFMT & ~S_ITRANS); + (*node)->nn_stat.st_mode = (netfs_root_node->nn_stat.st_mode & ~S_IFMT & ~S_ITRANS); (*node)->nn_stat.st_ino = 5; + if (cn->readlink) + { + (*node)->nn_stat.st_mode |= S_IFLNK; + (*node)->nn_stat.st_size = cn->readlink (user, NULL, NULL); + } + else + { + (*node)->nn_stat.st_mode |= S_IFCHR; + (*node)->nn_stat.st_size = 0; + } cn->node = *node; goto out; } @@ -325,7 +345,7 @@ netfs_S_io_select (struct protid *user, np = user->po->np; - if (np->nn->node->select) + if (np->nn->node && np->nn->node->select) return np->nn->node->select (user, reply, replytype, type); return EOPNOTSUPP; } @@ -336,6 +356,21 @@ error_t netfs_attempt_unlink (struct iouser *user, struct node *dir, char *name) { + error_t err; + consnode_t cn; + + err = fshelp_access (&dir->nn_stat, S_IWRITE, user); + if (err) + return err; + + for (cn = node_list; cn; cn = cn->next) + if (!strcmp (name, cn->name)) + { + if (cn->mksymlink) + return 0; + else + break; + } return EOPNOTSUPP; } @@ -378,6 +413,30 @@ error_t netfs_attempt_link (struct iouser *user, struct node *dir, struct node *file, char *name, int excl) { + error_t err; + consnode_t cn; + + err = fshelp_access (&dir->nn_stat, S_IWRITE, user); + if (err) + return err; + + if (!file->nn->node && file->nn->symlink_path) + { + for (cn = node_list; cn; cn = cn->next) + if (!strcmp (name, cn->name)) + { + if (cn->mksymlink) + { + file->nn->node = cn; + cn->mksymlink (user, file, file->nn->symlink_path); + free (file->nn->symlink_path); + file->nn->symlink_path = NULL; + return 0; + } + else + break; + } + } return EOPNOTSUPP; } @@ -389,7 +448,27 @@ error_t netfs_attempt_mkfile (struct iouser *user, struct node *dir, mode_t mode, struct node **np) { - return EOPNOTSUPP; + error_t err; + struct netnode *nn; + + mutex_unlock (&dir->lock); + + err = fshelp_access (&dir->nn_stat, S_IWRITE, user); + if (err) + { + *np = 0; + return err; + } + + nn = calloc (1, sizeof (*nn)); + if (!nn) + return ENOMEM; + + *np = netfs_make_node (nn); + mutex_lock (&(*np)->lock); + spin_unlock (&netfs_node_refcnt_lock); + + return 0; } @@ -413,6 +492,8 @@ error_t netfs_attempt_readlink (struct iouser *user, struct node *np, char *buf) { + if (np->nn->node && np->nn->node->readlink) + return np->nn->node->readlink (user, np, buf); return EOPNOTSUPP; } @@ -471,7 +552,7 @@ netfs_S_io_read (struct protid *user, return EOPNOTSUPP; np = user->po->np; - if (np->nn->node->read) + if (np->nn->node && np->nn->node->read) return np->nn->node->read (user, data, datalen, offset, amount); return EOPNOTSUPP; } @@ -490,7 +571,7 @@ netfs_S_io_write (struct protid *user, return EOPNOTSUPP; np = user->po->np; - if (np->nn->node->read) + if (np->nn->node && np->nn->node->write) return np->nn->node->write (user, data, datalen, offset, amount); return EOPNOTSUPP; } @@ -517,9 +598,15 @@ netfs_report_access (struct iouser *cred void netfs_node_norefs (struct node *np) { - if (np->nn->node->close) - np->nn->node->close (); - np->nn->node->node = 0; + if (np->nn->node) + { + if (np->nn->node->close) + np->nn->node->close (); + np->nn->node->node = 0; + } + + if (np->nn->symlink_path) + free (np->nn->symlink_path); spin_unlock (&netfs_node_refcnt_lock); free (np->nn); @@ -645,7 +732,7 @@ netfs_get_dirents (struct iouser *cred, /* Fill in the real directory entries. */ for (cn = first_node; cn; cn = cn->next) - if (!add_dir_entry (cn->name, cn->id, DT_CHR)) + if (!add_dir_entry (cn->name, cn->id, cn->readlink ? DT_LNK : DT_CHR)) break; } @@ -689,6 +776,9 @@ console_create_consnode (const char *nam return ENOMEM; } + (*cn)->readlink = NULL; + (*cn)->mksymlink = NULL; + return 0; } Index: console-client/trans.h =================================================================== RCS file: /cvsroot/hurd/hurd/console-client/trans.h,v retrieving revision 1.1 diff -u -u -p -r1.1 trans.h --- console-client/trans.h 6 Jan 2005 21:43:53 -0000 1.1 +++ console-client/trans.h 5 Mar 2005 15:53:00 -0000 @@ -54,6 +54,12 @@ struct consnode /* The demuxer used for this node. */ int (*demuxer) (mach_msg_header_t *inp, mach_msg_header_t *outp); + /* Called when the symlink is read */ + error_t (*readlink) (struct iouser *user, struct node *np, char *buf); + + /* Called when the symlink is written */ + error_t (*mksymlink) (struct iouser *cred, struct node *np, char *name); + struct consnode *next; }; Index: console-client/vcs-repeat.c =================================================================== RCS file: console-client/vcs-repeat.c diff -N console-client/vcs-repeat.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ console-client/vcs-repeat.c 5 Mar 2005 15:53:00 -0000 @@ -0,0 +1,223 @@ +/* vcs-repeat.c -- Add a repeater for "current vcs" as a symlink in the + console translator node. + Copyright (C) 2005 Free Software Foundation, Inc. + Written by Samuel Thibault. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#include +#include +#include +#include +#include +#include + +#include "trans.h" + + +/* The default name of the node of the repeater. */ +#define DEFAULT_REPEATER_NODE "vcs" + +/* The name of the repeater node. */ +static char *repeater_node; + +/* The repeater node. */ +static consnode_t vcs_node; + + +/* Callbacks for vcs console node. */ + +/* Reading the link to get current vcs, returns length of path (trailing \0 + excluded). */ +static error_t +vcs_readlink (struct iouser *user, struct node *np, char *buf) +{ + int cur; + error_t ret = 0; + + ret = console_current_id (&cur); + if (!ret) + { + if (!buf) + ret = snprintf (NULL, 0, "%s/%d", cons_file, cur); + else + ret = sprintf (buf, "%s/%d", cons_file, cur); + + if (ret < 0) + ret = errno; + } + return ret; +} + +static error_t +vcs_read (struct protid *user, char **data, + mach_msg_type_number_t * datalen, off_t offset, + mach_msg_type_number_t amount) +{ + int err; + int size; + + if (amount > 0) + { + size = vcs_readlink (user->user, NULL, NULL); + if (size < 0) + return size; + + { + char buf[size]; + + err = vcs_readlink (user->user, NULL, buf); + + if (err < 0) + return err; + + if (offset + amount > size) + amount = size - offset; + if (amount < 0) + amount = 0; + + if (*datalen < amount) + { + *data = mmap (0, amount, PROT_READ | PROT_WRITE, MAP_ANON, 0, 0); + if (*data == MAP_FAILED) + return ENOMEM; + } + + memcpy (*data, buf + offset, amount); + *datalen = amount; + } + } + return 0; +} + +/* Making a link to set current vcs. + Relative values perform relative switches. */ +static error_t +vcs_mksymlink (struct iouser *user, struct node *np, char *name) +{ + char *c, *d; + int vt, delta = 0; + + c = strrchr (name, '/'); + if (!c) + c = name; + else + c++; + if (!*c) + return EINVAL; + + if (*c == '-' || *c == '+') + delta = 1; + + vt = strtol (c, &d, 10); + if (*d) + /* Bad number. */ + return EINVAL; + + if (!vt) + return 0; + return console_switch (delta ? 0 : vt, delta ? vt : 0); +} + + +static const char doc[] = "VCS Repeater Driver"; + +static const struct argp_option options[] = + { + { "repeater", 'r', "NODE", OPTION_ARG_OPTIONAL, + "Set a repeater translator on NODE (default: " DEFAULT_REPEATER_NODE ")"}, + { 0 } + }; + +static error_t +parse_opt (int key, char *arg, struct argp_state *state) +{ + int *pos = (int *) state->input; + + switch (key) + { + case 'r': + repeater_node = arg ? arg: DEFAULT_REPEATER_NODE; + break; + + case ARGP_KEY_END: + break; + + default: + return ARGP_ERR_UNKNOWN; + } + + *pos = state->next; + return 0; +} + +static struct argp argp = {options, parse_opt, 0, doc}; + +/* Initialize the VCS Repeater driver. */ +static error_t +vcs_repeat_init (void **handle, int no_exit, int argc, char *argv[], int *next) +{ + error_t err; + int pos = 1; + + /* Parse the arguments. */ + err = argp_parse (&argp, argc, argv, ARGP_IN_ORDER | ARGP_NO_EXIT + | ARGP_SILENT, 0, &pos); + *next += pos - 1; + + if (err && err != EINVAL) + return err; + + return 0; +} + +static error_t +vcs_repeat_start (void *handle) +{ + error_t err; + + err = console_create_consnode (repeater_node, &vcs_node); + if (err) + return err; + + vcs_node->read = vcs_read; + vcs_node->write = NULL; + vcs_node->select = NULL; + vcs_node->open = NULL; + vcs_node->close = NULL; + vcs_node->demuxer = NULL; + vcs_node->readlink = vcs_readlink; + vcs_node->mksymlink = vcs_mksymlink; + console_register_consnode (vcs_node); + + return 0; +} + +static error_t +vcs_repeat_fini (void *handle, int force) +{ + console_unregister_consnode (vcs_node); + console_destroy_consnode (vcs_node); + return 0; +} + + +struct driver_ops driver_vcs_repeat_ops = + { + vcs_repeat_init, + vcs_repeat_start, + vcs_repeat_fini + }; + Index: libcons/ChangeLog =================================================================== RCS file: /cvsroot/hurd/hurd/libcons/ChangeLog,v retrieving revision 1.17 diff -u -u -p -r1.17 ChangeLog --- libcons/ChangeLog 6 Jan 2005 21:53:26 -0000 1.17 +++ libcons/ChangeLog 5 Mar 2005 15:53:00 -0000 @@ -1,3 +1,11 @@ +2005-03-05 Samuel Thibault + + * priv.h (_cons_file): Prototype moved and renamed to... + * cons.h (cons_file): ... this. + * init-init.c (cons_init): Updated `_cons_file' reference. + * opts-std-startup.c (_cons_file): Renamed into `cons_file'. Updated + reference. + 2005-01-06 Marco Gerards * Makefile (SRCS): Add `vcons-move-mouse.c' and `vcons-event.c'. Index: libcons/cons.h =================================================================== RCS file: /cvsroot/hurd/hurd/libcons/cons.h,v retrieving revision 1.9 diff -u -u -p -r1.9 cons.h --- libcons/cons.h 6 Jan 2005 21:53:26 -0000 1.9 +++ libcons/cons.h 5 Mar 2005 15:53:00 -0000 @@ -298,6 +298,9 @@ extern const struct argp cons_startup_ar extern struct port_bucket *cons_port_bucket; extern struct port_class *cons_port_class; +/* The filename of the console server. */ +extern char *cons_file; + error_t cons_init (void); void cons_server_loop (void); int cons_demuxer (mach_msg_header_t *inp, mach_msg_header_t *outp); Index: libcons/init-init.c =================================================================== RCS file: /cvsroot/hurd/hurd/libcons/init-init.c,v retrieving revision 1.2 diff -u -u -p -r1.2 init-init.c --- libcons/init-init.c 8 Sep 2002 21:55:59 -0000 1.2 +++ libcons/init-init.c 5 Mar 2005 15:53:00 -0000 @@ -56,7 +56,7 @@ cons_init (void) mutex_init (&cons->lock); cons->vcons_list = NULL; cons->vcons_last = NULL; - cons->dir = opendir (_cons_file); + cons->dir = opendir (cons_file); cons->slack = _cons_slack; if (!cons->dir) { Index: libcons/opts-std-startup.c =================================================================== RCS file: /cvsroot/hurd/hurd/libcons/opts-std-startup.c,v retrieving revision 1.7 diff -u -u -p -r1.7 opts-std-startup.c --- libcons/opts-std-startup.c 6 Jan 2005 21:53:26 -0000 1.7 +++ libcons/opts-std-startup.c 5 Mar 2005 15:53:00 -0000 @@ -58,7 +58,7 @@ int _cons_jump_down_on_input = 1; int _cons_jump_down_on_output; /* The filename of the console server. */ -char *_cons_file; +char *cons_file; /* The type of bell used for the visual bell. */ bell_type_t _cons_visual_bell = BELL_VISUAL; @@ -206,7 +206,7 @@ parse_startup_opt (int opt, char *arg, s if (state->arg_num > 0) /* Too many arguments. */ argp_error (state, "Too many non option arguments"); - _cons_file = arg; + cons_file = arg; break; case ARGP_KEY_NO_ARGS: Index: libcons/priv.h =================================================================== RCS file: /cvsroot/hurd/hurd/libcons/priv.h,v retrieving revision 1.5 diff -u -u -p -r1.5 priv.h --- libcons/priv.h 6 Jan 2005 21:53:26 -0000 1.5 +++ libcons/priv.h 5 Mar 2005 15:53:00 -0000 @@ -45,9 +45,6 @@ extern int _cons_jump_down_on_input; /* If we jump down at output. */ extern int _cons_jump_down_on_output; -/* The filename of the console server. */ -extern char *_cons_file; - /* The type of bell used for the visual bell. */ extern bell_type_t _cons_visual_bell;