From owner-freebsd-ports Mon Dec 23 4:31:17 2002 Delivered-To: freebsd-ports@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id A839437B401; Mon, 23 Dec 2002 04:31:12 -0800 (PST) Received: from wwweasel.geeksrus.net (wwweasel.geeksrus.net [64.8.210.226]) by mx1.FreeBSD.org (Postfix) with ESMTP id 0EC7943EDE; Mon, 23 Dec 2002 04:31:12 -0800 (PST) (envelope-from alane@wwweasel.geeksrus.net) Received: from wwweasel.geeksrus.net (localhost [127.0.0.1]) by wwweasel.geeksrus.net (8.12.6/8.12.6) with ESMTP id gBNCUsDr064388; Mon, 23 Dec 2002 07:30:54 -0500 (EST) (envelope-from alane@wwweasel.geeksrus.net) Received: (from alane@localhost) by wwweasel.geeksrus.net (8.12.6/8.12.6/Submit) id gBNCUsSL064381; Mon, 23 Dec 2002 07:30:54 -0500 (EST) (envelope-from alane) Date: Mon, 23 Dec 2002 07:30:54 -0500 (EST) Message-Id: <200212231230.gBNCUsSL064381@wwweasel.geeksrus.net> To: FreeBSD-gnats-submit@freebsd.org Subject: From: Alan Eldridge Reply-To: Alan Eldridge Cc: demon@freebsd.org, ports@freebsd.org X-send-pr-version: 3.113 X-GNATS-Notify: Sender: owner-freebsd-ports@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org >Submitter-Id: current-users >Originator: Alan Eldridge >Organization: Geeksrus.NET >Confidential: no >Synopsis: >Responsible: demon >Severity: serious >Priority: medium >Category: ports >Class: change-request >Release: FreeBSD 4.7-STABLE i386 >Environment: System: FreeBSD wwweasel.geeksrus.net 4.7-STABLE FreeBSD 4.7-STABLE #0: Fri Dec 20 06:38:48 EST 2002 root@wwweasel.geeksrus.net:/usr/obj/usr/src/sys/THRAK i386 >Description: Links, as great as it is, has no way to print. This patch hijacks the generic file open function, so anyplace you can enter a filename to save you can type "| command" and the data will go to the command instead. Printing is as easy as doing the "save formatted" command and giving a filename of "| lpr". This patch is non-invasive for the most part. It creates one new function (create_process(commandline)) in session.c, and adds an if statement to see if the save file begins with a "|": if it does we hijack it to create_process instead. I plan on submitting this to the author as well. However, it's a nice value-add for FreeBSD, and people are welcome to try it out on their own. The patch, which follows, is also available at: http://people.freebsd.org/~alane/patches/patch-links-save_to_pipe.txt >How-To-Repeat: >Fix: ==8<====8<====8<====8<====8<====8<====8<====8<====8<====8<== Index: files/patch-session.c =================================================================== RCS file: files/patch-session.c diff -N files/patch-session.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ files/patch-session.c 23 Dec 2002 12:07:48 -0000 @@ -0,0 +1,119 @@ +--- session.c.orig Sun Jun 9 15:49:24 2002 ++++ session.c Mon Dec 23 07:07:36 2002 +@@ -1,4 +1,4 @@ +-/* session.c ++/* session.c -*-mode: c; c-basic-offset: 8-*- + * (c) 2002 Mikulas Patocka + * This file is a part of the Links program, released under GPL. + */ +@@ -503,6 +503,95 @@ + } + } + ++int create_process(unsigned char *szfn) ++{ ++ int pid, rgfd[ 2 ]; ++ unsigned char *command = szfn; ++ ++ pipe(rgfd); ++ if ((pid = fork()) < 0) { ++ close(rgfd[ 0 ]); ++ close(rgfd[ 1 ]); ++ return -1; ++ } else if (pid > 0) { ++ /* parent: ++ 1. The write "handle" returned to the caller is ++ the canonical write end of the pipe pair. ++ 2. We close the "read" end since we are not using ++ it and we don't want fd leakage. ++ 3. The first thing the child is going to do is ++ fork and exit, so the process we want to run will ++ belong to init, not us. It's gross, but more ++ portable than becoming a session leader. So we wait. ++ */ ++ int status; ++ ++ wait(&status); ++ close(rgfd[ 0 ]); ++ return rgfd[ 1 ]; ++ } else { ++ /* child: ++ at this point, if something goes wrong, ++ there's really nothing we can do about it; ++ the parent will get a SIGPIPE when it ++ tries to write. ++ */ ++ int fdnull = open("/dev/null", O_WRONLY); ++ ++ /* ++ fork again, so we are re-parented to init ++ and avoid the whole SIGCHLD issue. if we ++ aren't the chile, we die. We use _exit so ++ we don't flush any output buffers. ++ */ ++ if ((pid = fork()) != 0) { ++ _exit(0); ++ } ++ ++ /* grandchild: ++ If we got here, we are in the grandchild process, ++ whose parent has died and been reaped. Our parent ++ should be init (the primordial process). ++ ++ Before we exec the command, we need to set up ++ stdin, stdout, and stderr. ++ 1. stdin gets a dup2 of the "read" end of the ++ pipe. ++ 2. stdout and stderr get copies of an fd opened ++ to "/dev/null". ++ */ ++ dup2(rgfd[ 0 ], 0); ++ dup2(fdnull, 1); ++ dup2(fdnull, 2); ++ ++ /* ++ Now we can close everything that is still ++ open, because we've dup'd what we needed. ++ */ ++ close(fdnull); ++ close(rgfd[ 0 ]); ++ close(rgfd[ 1 ]); ++ ++ /* ++ Let the shell handle the command. We use ++ a hard-coded /bin/sh to avoid someone setting ++ SHELL to an odd value and causing damage. ++ ++ Any damage that is done to the user should be ++ self-inflicted, not the result of a maliciously ++ set environment var. ++ */ ++ execlp("/bin/sh", "/bin/sh", "-c", command, 0); ++ ++ /* failure: ++ If we get here, there's not much to do but die. ++ We use _exit so we don't flush any output buffers. ++ */ ++ _exit(1); ++ } ++ /* Trust me, you can't get here. */ ++} ++ + int create_download_file(struct terminal *term, unsigned char *fi, int safe) + { + unsigned char *file = fi; +@@ -514,6 +603,14 @@ + #else + int sf = safe; + #endif ++ if (*fi == '|') { ++ /* ++ This will hook any command that saves ++ a file to disk and hijack it to write ++ to the input of a process. Cool, huh? ++ */ ++ return create_process(fi + 1); ++ } + wd = get_cwd(); + set_cwd(term->cwd); + if (file[0] == '~' && dir_sep(file[1])) { ==8<====8<====8<====8<====8<====8<====8<====8<====8<====8<== To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-ports" in the body of the message