Exemplo n.º 1
0
int
main(int argc, char **argv) {
	sigset_t block_mask, unblock_mask;
	struct sigaction sa;
	int ch;
	FILE *timingfd = stderr;

	enum { FORCE_OPTION = CHAR_MAX + 1 };

	static const struct option longopts[] = {
		{ "append",	no_argument,	   NULL, 'a' },
		{ "command",	required_argument, NULL, 'c' },
		{ "return",	no_argument,	   NULL, 'e' },
		{ "flush",	no_argument,	   NULL, 'f' },
		{ "force",	no_argument,	   NULL, FORCE_OPTION, },
		{ "quiet",	no_argument,	   NULL, 'q' },
		{ "timing",	optional_argument, NULL, 't' },
		{ "version",	no_argument,	   NULL, 'V' },
		{ "help",	no_argument,	   NULL, 'h' },
		{ NULL,		0, NULL, 0 }
	};

	setlocale(LC_ALL, "");
	setlocale(LC_NUMERIC, "C");	/* see comment above */
	bindtextdomain(PACKAGE, LOCALEDIR);
	textdomain(PACKAGE);
	atexit(close_stdout);

	while ((ch = getopt_long(argc, argv, "ac:efqt::Vh", longopts, NULL)) != -1)
		switch(ch) {
		case 'a':
			aflg = 1;
			break;
		case 'c':
			cflg = optarg;
			break;
		case 'e':
			eflg = 1;
			break;
		case 'f':
			fflg = 1;
			break;
		case FORCE_OPTION:
			forceflg = 1;
			break;
		case 'q':
			qflg = 1;
			break;
		case 't':
			if (optarg)
				if ((timingfd = fopen(optarg, "w")) == NULL)
					err(EXIT_FAILURE, _("cannot open timing file %s"), optarg);
			tflg = 1;
			break;
		case 'V':
			printf(_("%s from %s\n"), program_invocation_short_name,
						  PACKAGE_STRING);
			exit(EXIT_SUCCESS);
			break;
		case 'h':
			usage(stdout);
			break;
		case '?':
		default:
			usage(stderr);
		}
	argc -= optind;
	argv += optind;

	if (argc > 0)
		fname = argv[0];
	else {
		fname = DEFAULT_OUTPUT;
		die_if_link(fname);
	}
	if ((fscript = fopen(fname, aflg ? "a" : "w")) == NULL) {
		warn(_("open failed: %s"), fname);
		fail();
	}

	shell = getenv("SHELL");
	if (shell == NULL)
		shell = _PATH_BSHELL;

	getmaster();
	if (!qflg)
		printf(_("Script started, file is %s\n"), fname);
	fixtty();

#ifdef HAVE_LIBUTEMPTER
	utempter_add_record(master, NULL);
#endif
	/* setup SIGCHLD handler */
	sigemptyset(&sa.sa_mask);
	sa.sa_flags = 0;
	sa.sa_handler = finish;
	sigaction(SIGCHLD, &sa, NULL);

	/* init mask for SIGCHLD */
	sigprocmask(SIG_SETMASK, NULL, &block_mask);
	sigaddset(&block_mask, SIGCHLD);

	sigprocmask(SIG_SETMASK, &block_mask, &unblock_mask);
	child = fork();
	sigprocmask(SIG_SETMASK, &unblock_mask, NULL);

	if (child < 0) {
		warn(_("fork failed"));
		fail();
	}
	if (child == 0) {

		sigprocmask(SIG_SETMASK, &block_mask, NULL);
		subchild = child = fork();
		sigprocmask(SIG_SETMASK, &unblock_mask, NULL);

		if (child < 0) {
			warn(_("fork failed"));
			fail();
		}
		if (child)
			dooutput(timingfd);
		else
			doshell();
	} else {
		sa.sa_handler = resize;
		sigaction(SIGWINCH, &sa, NULL);
	}
	doinput();

	if (close_stream(timingfd) != 0)
		errx(EXIT_FAILURE, _("write error"));
	return EXIT_SUCCESS;
}
Exemplo n.º 2
0
/* EXTPROTO */
void
rxvt_makeutent(rxvt_t *r, const char *pty, const char *hostname)
{
#ifdef UTEMPTER_SUPPORT
    utempter_add_record (PVTS(r)->cmd_fd, hostname);
#else	/* UTEMPTER_SUPPORT */

#ifdef HAVE_STRUCT_UTMP
    struct utmp    *ut = &(PVTS(r)->ut);
#endif
#if defined(HAVE_STRUCT_UTMPX) && !defined(HAVE_STRUCT_UTMP)
    struct utmpx   *utx = &(PVTS(r)->utx);
#endif
#ifdef HAVE_UTMP_PID
    int             i;
#endif
    char            ut_id[5];
    struct passwd  *pwent = getpwuid(getuid());

    if (!STRNCMP(pty, "/dev/", 5))
	pty += 5;	/* skip /dev/ prefix */

    if (!STRNCMP(pty, "pty", 3) || !STRNCMP(pty, "tty", 3)) {
	STRNCPY(ut_id, (pty + 3), sizeof(ut_id));
    }
#ifdef HAVE_UTMP_PID
    else if (sscanf(pty, "pts/%d", &i) == 1)
	sprintf(ut_id, "vt%02x", (i & 0xff));	/* sysv naming */
#endif
    else if (STRNCMP(pty, "pty", 3) && STRNCMP(pty, "tty", 3)) {
	rxvt_msg (DBG_ERROR, DBG_LOGGING, "can't parse tty name \"%s\"", pty);
	return;
    }

#ifdef HAVE_STRUCT_UTMP
    MEMSET(ut, 0, sizeof(struct utmp));
# ifdef HAVE_UTMP_PID
    setutent();
    STRNCPY(ut->ut_id, ut_id, sizeof(ut->ut_id));
    ut->ut_type = DEAD_PROCESS;
    getutid(ut);	/* position to entry in utmp file */
    STRNCPY(PVTS(r)->ut_id, ut_id, sizeof(PVTS(r)->ut_id));
# endif
#endif

#if defined(HAVE_STRUCT_UTMPX) && !defined(HAVE_STRUCT_UTMP)
    MEMSET(utx, 0, sizeof(struct utmpx));
    setutxent();
    STRNCPY(utx->ut_id, ut_id, sizeof(utx->ut_id));
    utx->ut_type = DEAD_PROCESS;
    getutxid(utx);	/* position to entry in utmp file */
    STRNCPY(PVTS(r)->ut_id, ut_id, sizeof(PVTS(r)->ut_id));
#endif

#ifdef HAVE_STRUCT_UTMP
    STRNCPY(ut->ut_line, pty, sizeof(ut->ut_line));
    ut->ut_time = time(NULL);
# ifdef HAVE_UTMP_PID
    STRNCPY(ut->ut_user, (pwent && pwent->pw_name) ? pwent->pw_name : "?",
        sizeof(ut->ut_user));
    STRNCPY(ut->ut_id, ut_id, sizeof(ut->ut_id));
    ut->ut_time = time(NULL);
    ut->ut_pid = PVTS(r)->cmd_pid;
#  ifdef HAVE_UTMP_HOST
    STRNCPY(ut->ut_host, hostname, sizeof(ut->ut_host));
#  endif
    ut->ut_type = USER_PROCESS;
    pututline(ut);
    endutent();		/* close the file */
    PVTS(r)->utmp_pos = 0;
# else
    STRNCPY(ut->ut_name, (pwent && pwent->pw_name) ? pwent->pw_name : "?",
        sizeof(ut->ut_name));
#  ifdef HAVE_UTMP_HOST
    STRNCPY(ut->ut_host, hostname, sizeof(ut->ut_host));
#  endif
# endif
#endif

#if defined(HAVE_STRUCT_UTMPX) && !defined(HAVE_STRUCT_UTMP)
    STRNCPY(utx->ut_line, pty, sizeof(utx->ut_line));
    STRNCPY(utx->ut_user, (pwent && pwent->pw_name) ? pwent->pw_name : "?",
        sizeof(utx->ut_user));
    STRNCPY(utx->ut_id, ut_id, sizeof(utx->ut_id));
# ifdef HAVE_UTMPX_SESSION
    utx->ut_session = getsid(0);
# endif
    utx->ut_tv.tv_sec = time(NULL);
    utx->ut_tv.tv_usec = 0;
    utx->ut_pid = PVTS(r)->cmd_pid;
# ifdef HAVE_UTMPX_HOST
    STRNCPY(utx->ut_host, hostname, sizeof(utx->ut_host));
# endif
    utx->ut_type = USER_PROCESS;
    pututxline(utx);
    endutxent();	/* close the file */
    PVTS(r)->utmp_pos = 0;
#endif

#if defined(HAVE_STRUCT_UTMP) && !defined(HAVE_UTMP_PID)
    {
	int             i;
# ifdef HAVE_TTYSLOT
	i = ttyslot();
	if (rxvt_write_bsd_utmp(i, ut))
	    PVTS(r)->utmp_pos = i;
# else
	FILE           *fd0;

	if (NOT_NULL(fd0 = fopen(TTYTAB_FILENAME, "r"))) {
	    char            buf[256], name[256];

	    buf[sizeof(buf) - 1] = '\0';
	    for (i = 1; NOT_NULL(fgets(buf, sizeof(buf) - 1, fd0)); ) {
		if (*buf == '#' || sscanf(buf, "%s", name) != 1)
		    continue;
		if (!STRCMP(ut->ut_line, name)) {
		    if (!rxvt_write_bsd_utmp(i, ut))
			i = 0;
		    PVTS(r)->utmp_pos = i;
		    fclose(fd0);
		    break;
		}
		i++;
	    }
	    fclose(fd0);
	}
# endif
    }
#endif

#ifdef WTMP_SUPPORT
# ifdef WTMP_ONLY_ON_LOGIN
    if (ISSET_OPTION(r, Opt_loginShell))
# endif
    {
# ifdef HAVE_STRUCT_UTMP
#  ifdef HAVE_UPDWTMP
	updwtmp(RXVT_WTMP_FILE, ut);
#  else
	rxvt_update_wtmp(RXVT_WTMP_FILE, ut);
#  endif
# endif
# if defined(HAVE_STRUCT_UTMPX) && !defined(HAVE_STRUCT_UTMP)
#  ifdef HAVE_UPDWTMPX
	updwtmpx(RXVT_WTMPX_FILE, utx);
#  else
	pututxline (utx);
#  endif
# endif
    }
#endif

#endif	/* UTEMPTER_SUPPORT */

#if defined(LASTLOG_SUPPORT) && defined(RXVT_LASTLOG_FILE)
    if (ISSET_OPTION(r, Opt_loginShell))
	rxvt_update_lastlog(RXVT_LASTLOG_FILE, pty, hostname);
#endif

}
Exemplo n.º 3
0
int
main(int argc, char **argv) {
    sigset_t block_mask, unblock_mask;
    struct sigaction sa;
    extern int optind;
    char *p;
    int ch;

    progname = argv[0];
    if ((p = strrchr(progname, '/')) != NULL)
        progname = p+1;


    setlocale(LC_ALL, "");
    setlocale(LC_NUMERIC, "C");	/* see comment above */
    bindtextdomain(PACKAGE, LOCALEDIR);
    textdomain(PACKAGE);

    if (argc == 2) {
        if (!strcmp(argv[1], "-V") || !strcmp(argv[1], "--version")) {
            printf(_("%s (%s)\n"),
                   progname, PACKAGE_STRING);
            return 0;
        }
    }

    while ((ch = getopt(argc, argv, "ac:efqt")) != -1)
        switch((char)ch) {
        case 'a':
            aflg++;
            break;
        case 'c':
            cflg = optarg;
            break;
        case 'e':
            eflg++;
            break;
        case 'f':
            fflg++;
            break;
        case 'q':
            qflg++;
            break;
        case 't':
            tflg++;
            break;
        case '?':
        default:
            fprintf(stderr,
                    _("usage: script [-a] [-e] [-f] [-q] [-t] [file]\n"));
            exit(1);
        }
    argc -= optind;
    argv += optind;

    if (argc > 0)
        fname = argv[0];
    else {
        fname = "typescript";
        die_if_link(fname);
    }
    if ((fscript = fopen(fname, aflg ? "a" : "w")) == NULL) {
        perror(fname);
        fail();
    }

    shell = getenv("SHELL");
    if (shell == NULL)
        shell = _PATH_BSHELL;

    getmaster();
    if (!qflg)
        printf(_("Script started, file is %s\n"), fname);
    fixtty();

#ifdef HAVE_LIBUTEMPTER
    utempter_add_record(master, NULL);
#endif
    /* setup SIGCHLD handler */
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;
    sa.sa_handler = finish;
    sigaction(SIGCHLD, &sa, NULL);

    /* init mask for SIGCHLD */
    sigprocmask(SIG_SETMASK, NULL, &block_mask);
    sigaddset(&block_mask, SIGCHLD);

    sigprocmask(SIG_SETMASK, &block_mask, &unblock_mask);
    child = fork();
    sigprocmask(SIG_SETMASK, &unblock_mask, NULL);

    if (child < 0) {
        perror("fork");
        fail();
    }
    if (child == 0) {

        sigprocmask(SIG_SETMASK, &block_mask, NULL);
        subchild = child = fork();
        sigprocmask(SIG_SETMASK, &unblock_mask, NULL);

        if (child < 0) {
            perror("fork");
            fail();
        }
        if (child)
            dooutput();
        else
            doshell();
    } else {
        sa.sa_handler = resize;
        sigaction(SIGWINCH, &sa, NULL);
    }
    doinput();

    return 0;
}