示例#1
0
void
init_misc(void)
{
    if (cmd) {
	if (SHIN >= 10)
	    fclose(bshin);
	SHIN = movefd(open("/dev/null", O_RDONLY));
	bshin = fdopen(SHIN, "r");
	execstring(cmd, 0, 1);
	stopmsg = 1;
	zexit(lastval, 0);
    }

    if (interact && isset(RCS))
	readhistfile(getsparam("HISTFILE"), 0);
    adjustwinsize();   /* check window size and adjust if necessary */
}
示例#2
0
int
quotactl(int cmd, char *mountp, uid_t uid, caddr_t addr)
{
	int		fd;
	int		status;
	struct quotctl	quota;
	char		qfile[MAXPATHLEN];

	FILE		*fstab;
	struct mnttab	mnt;


	if ((mountp == NULL) && (cmd == Q_ALLSYNC)) {
	/*
	 * Find the mount point of any mounted file system. This is
	 * because the ioctl that implements the quotactl call has
	 * to go to a real file, and not to the block device.
	 */
		if ((fstab = fopen(MNTTAB, "r")) == NULL) {
			fprintf(stderr, "%s: ", MNTTAB);
			perror("open");
			zexit(32);
		}
		fd = -1;
		while ((status = getmntent(fstab, &mnt)) == NULL) {
			if (strcmp(mnt.mnt_fstype, MNTTYPE_UFS) != 0 ||
			    hasopt(MNTOPT_RO, mnt.mnt_mntopts))
				continue;
			if ((strlcpy(qfile, mnt.mnt_mountp,
			    sizeof (qfile)) >= sizeof (qfile)) ||
			    (strlcat(qfile, "/" QFNAME, sizeof (qfile)) >=
			    sizeof (qfile))) {
				continue;
			}
			(void) __priv_bracket(PRIV_ON);
			fd = open64(qfile, O_RDONLY);
			(void) __priv_bracket(PRIV_OFF);
			if (fd != -1)
				break;
		}
		fclose(fstab);
		if (fd == -1) {
			errno = ENOENT;
			return (-1);
		}
	} else {
		if (mountp == NULL || mountp[0] == '\0') {
			errno = ENOENT;
			return (-1);
		}
		if ((strlcpy(qfile, mountp, sizeof (qfile)) >= sizeof
		    (qfile)) ||
		    (strlcat(qfile, "/" QFNAME, sizeof (qfile)) >= sizeof
		    (qfile))) {
			errno = ENOENT;
			return (-1);
		}
		(void) __priv_bracket(PRIV_ON);
		fd = open64(qfile, O_RDONLY);
		(void) __priv_bracket(PRIV_OFF);
		if (fd < 0)
			return (-1);
	}	/* else */
	quota.op = cmd;
	quota.uid = uid;
	quota.addr = addr;
	status = ioctl(fd, Q_QUOTACTL, &quota);
	if (fd != 0)
		close(fd);
	return (status);
}
示例#3
0
static void
showquotas(uid_t uid, char *name)
{
	struct mnttab mnt;
	FILE *mtab;
	struct dqblk dqblk;
	uid_t myuid;
	struct failed_srv {
		char *serv_name;
		struct failed_srv *next;
	};
	struct failed_srv *failed_srv_list = NULL;
	int	rc;
	char	my_zonename[ZONENAME_MAX];
	zoneid_t my_zoneid = getzoneid();

	myuid = getuid();
	if (uid != myuid && myuid != 0) {
		printf("quota: %s (uid %d): permission denied\n", name, uid);
		zexit(32);
	}

	memset(my_zonename, '\0', ZONENAME_MAX);
	getzonenamebyid(my_zoneid, my_zonename, ZONENAME_MAX);

	if (vflag)
		heading(uid, name);
	mtab = fopen(MNTTAB, "r");
	while (getmntent(mtab, &mnt) == NULL) {
		if (strcmp(mnt.mnt_fstype, MNTTYPE_ZFS) == 0) {
			bzero(&dqblk, sizeof (dqblk));
			if (getzfsquota(name, mnt.mnt_special, &dqblk))
				continue;
		} else if (strcmp(mnt.mnt_fstype, MNTTYPE_UFS) == 0) {
			if (nolocalquota ||
			    (quotactl(Q_GETQUOTA,
			    mnt.mnt_mountp, uid, &dqblk) != 0 &&
			    !(vflag && getdiskquota(&mnt, uid, &dqblk))))
				continue;
		} else if (strcmp(mnt.mnt_fstype, MNTTYPE_NFS) == 0) {

			struct replica *rl;
			int count;
			char *mntopt = NULL;

			/*
			 * Skip checking quotas for file systems mounted
			 * in other zones. Zone names will be passed in
			 * following format from hasmntopt():
			 * "zone=<zone-name>,<mnt options...>"
			 */
			if ((mntopt = hasmntopt(&mnt, MNTOPT_ZONE)) &&
			    (my_zonename[0] != '\0')) {
				mntopt += strcspn(mntopt, "=") + 1;
				if (strncmp(mntopt, my_zonename,
				    strcspn(mntopt, ",")) != 0)
					continue;
			}

			if (hasopt(MNTOPT_NOQUOTA, mnt.mnt_mntopts))
				continue;

			/*
			 * Skip quota processing if mounted with public
			 * option. We are not likely to be able to pierce
			 * a fire wall to contact the quota server.
			 */
			if (hasopt(MNTOPT_PUBLIC, mnt.mnt_mntopts))
				continue;

			rl = parse_replica(mnt.mnt_special, &count);

			if (rl == NULL) {

				if (count < 0)
					fprintf(stderr, "cannot find hostname "
					    "and/or pathname for %s\n",
					    mnt.mnt_mountp);
				else
					fprintf(stderr, "no memory to parse "
					    "mnttab entry for %s\n",
					    mnt.mnt_mountp);
				continue;
			}

			/*
			 * We skip quota reporting on mounts with replicas
			 * for the following reasons:
			 *
			 * (1) Very little point in reporting quotas on
			 * a set of read-only replicas ... how will the
			 * user correct the problem?
			 *
			 * (2) Which replica would we report the quota
			 * for? If we pick the current replica, what
			 * happens when a fail over event occurs? The
			 * next time quota is run, the quota will look
			 * all different, or there won't even be one.
			 * This has the potential to break scripts.
			 *
			 * If we prnt quouta for all replicas, how do
			 * we present the output without breaking scripts?
			 */

			if (count > 1) {
				free_replica(rl, count);
				continue;
			}

			/*
			 * Skip file systems mounted using public fh.
			 * We are not likely to be able to pierce
			 * a fire wall to contact the quota server.
			 */
			if (strcmp(rl[0].host, "nfs") == 0 &&
			    strncmp(rl[0].path, "//", 2) == 0) {
				free_replica(rl, count);
				continue;
			}

			/*
			 * Skip getting quotas from failing servers
			 */
			if (failed_srv_list != NULL) {
				struct failed_srv *tmp_list;
				int found_failed = 0;
				size_t len = strlen(rl[0].host);

				tmp_list = failed_srv_list;
				do {
					if (strncasecmp(rl[0].host,
					    tmp_list->serv_name, len) == 0) {
						found_failed = 1;
						break;
					}
				} while ((tmp_list = tmp_list->next) != NULL);
				if (found_failed) {
					free_replica(rl, count);
					continue;
				}
			}

			rc = getnfsquota(rl[0].host, rl[0].path, uid, &dqblk);
			if (rc != RPC_SUCCESS) {
				size_t len;
				struct failed_srv *tmp_srv;

				/*
				 * Failed to get quota from this server. Add
				 * this server to failed_srv_list and skip
				 * getting quotas for other mounted filesystems
				 * from this server.
				 */
				if (rc == RPC_TIMEDOUT || rc == RPC_CANTSEND) {
					len = strlen(rl[0].host);
					tmp_srv = (struct failed_srv *)malloc(
					    sizeof (struct failed_srv));
					tmp_srv->serv_name = (char *)malloc(
					    len * sizeof (char) + 1);
					strncpy(tmp_srv->serv_name, rl[0].host,
					    len);
					tmp_srv->serv_name[len] = '\0';

					tmp_srv->next = failed_srv_list;
					failed_srv_list = tmp_srv;
				}

				free_replica(rl, count);
				continue;
			}

			free_replica(rl, count);
		} else {
			continue;
		}
		if (dqblk.dqb_bsoftlimit == 0 && dqblk.dqb_bhardlimit == 0 &&
		    dqblk.dqb_fsoftlimit == 0 && dqblk.dqb_fhardlimit == 0)
			continue;
		if (vflag)
			prquota(&mnt, &dqblk);
		else
			warn(&mnt, &dqblk);
	}

	/*
	 * Free list of failed servers
	 */
	while (failed_srv_list != NULL) {
		struct failed_srv *tmp_srv = failed_srv_list;

		failed_srv_list = failed_srv_list->next;
		free(tmp_srv->serv_name);
		free(tmp_srv);
	}

	fclose(mtab);
}
示例#4
0
int
main(int argc, char *argv[])
{
	int	opt;
	int	i;
	int	status = 0;

	(void) setlocale(LC_ALL, "");
	(void) textdomain(TEXT_DOMAIN);

	/*
	 * PRIV_FILE_DAC_READ is needed to read the QFNAME file
	 * Clear all other privleges from the limit set, and add
	 * the required privilege to the bracketed set.
	 */

	if (__init_suid_priv(PU_CLEARLIMITSET, PRIV_FILE_DAC_READ,
	    NULL) == -1) {
		(void) fprintf(stderr,
		    gettext("Insufficient privileges, "
		    "quota must be set-uid root or have "
		    "file_dac_read privileges\n"));

		exit(1);
	}

	load_libzfs();

	while ((opt = getopt(argc, argv, "vV")) != EOF) {
		switch (opt) {

		case 'v':
			vflag++;
			break;

		case 'V':		/* Print command line */
			{
			char	*opt_text;
			int	opt_count;

			(void) fprintf(stdout, "quota -F UFS ");
			for (opt_count = 1; opt_count < argc; opt_count++) {
				opt_text = argv[opt_count];
				if (opt_text)
					(void) fprintf(stdout, " %s ",
					    opt_text);
			}
			(void) fprintf(stdout, "\n");
			}
			break;

		case '?':
			fprintf(stderr, "usage: quota [-v] [username]\n");
			zexit(32);
		}
	}
	if (quotactl(Q_ALLSYNC, NULL, (uid_t)0, NULL) < 0 && errno == EINVAL) {
		if (vflag)
			fprintf(stderr, "There are no quotas on this system\n");
		nolocalquota++;
	}
	if (argc == optind) {
		showuid(getuid());
		zexit(0);
	}
	for (i = optind; i < argc; i++) {
		if (alldigits(argv[i])) {
			showuid((uid_t)atoi(argv[i]));
		} else
			status |= showname(argv[i]);
	}
	__priv_relinquish();
	return (status);
}
示例#5
0
/*ARGSUSED*/
int
main(int argc, char *argv[])
{
	register SVCXPRT *transp;

	load_libzfs();

	/*
	 * If stdin looks like a TLI endpoint, we assume
	 * that we were started by a port monitor. If
	 * t_getstate fails with TBADF, this is not a
	 * TLI endpoint.
	 */
	if (t_getstate(0) != -1 || t_errno != TBADF) {
		char *netid;
		struct netconfig *nconf = NULL;

		openlog("rquotad", LOG_PID, LOG_DAEMON);

		if ((netid = getenv("NLSPROVIDER")) == NULL) {
			struct t_info tinfo;

			if (t_sync(0) == -1) {
				syslog(LOG_ERR, "could not do t_sync");
				zexit(1);
			}
			if (t_getinfo(0, &tinfo) == -1) {
				syslog(LOG_ERR, "t_getinfo failed");
				zexit(1);
			}
			if (tinfo.servtype == T_CLTS) {
				if (tinfo.addr == INET_ADDRSTRLEN)
					netid = "udp";
				else
					netid = "udp6";
			} else {
				syslog(LOG_ERR, "wrong transport");
				zexit(1);
			}
		}
		if ((nconf = getnetconfigent(netid)) == NULL) {
			syslog(LOG_ERR, "cannot get transport info");
		}

		if ((transp = svc_tli_create(0, nconf, NULL, 0, 0)) == NULL) {
			syslog(LOG_ERR, "cannot create server handle");
			zexit(1);
		}
		if (nconf)
			freenetconfigent(nconf);

		if (!svc_reg(transp, RQUOTAPROG, RQUOTAVERS, dispatch, 0)) {
			syslog(LOG_ERR,
			    "unable to register (RQUOTAPROG, RQUOTAVERS).");
			zexit(1);
		}

		(void) sigset(SIGALRM, (void(*)(int)) closedown);
		(void) alarm(RPCSVC_CLOSEDOWN);

		svc_run();
		zexit(1);
		/* NOTREACHED */
	}

	/*
	 * Started from a shell - fork the daemon.
	 */

	switch (fork()) {
	case 0:		/* child */
		break;
	case -1:
		perror("rquotad: can't fork");
		zexit(1);
	default:	/* parent */
		zexit(0);
	}

	/*
	 * Close existing file descriptors, open "/dev/null" as
	 * standard input, output, and error, and detach from
	 * controlling terminal.
	 */
	closefrom(0);
	(void) open("/dev/null", O_RDONLY);
	(void) open("/dev/null", O_WRONLY);
	(void) dup(1);
	(void) setsid();

	openlog("rquotad", LOG_PID, LOG_DAEMON);

	/*
	 * Create datagram service
	 */
	if (svc_create(dispatch, RQUOTAPROG, RQUOTAVERS, "datagram_v") == 0) {
		syslog(LOG_ERR, "couldn't register datagram_v service");
		zexit(1);
	}

	/*
	 * Start serving
	 */
	svc_run();
	syslog(LOG_ERR, "Error: svc_run shouldn't have returned");
	return (1);
}
示例#6
0
mod_export int
getbyte(long do_keytmout, int *timeout)
{
    char cc;
    unsigned int ret;
    int die = 0, r, icnt = 0;
    int old_errno = errno, obreaks = breaks;

    if (timeout)
	*timeout = 0;

#ifdef MULTIBYTE_SUPPORT
    /*
     * Reading a single byte always invalidates the status
     * of lastchar_wide.  We may fix this up in getrestchar
     * if this is the last byte of a wide character.
     */
    lastchar_wide_valid = 0;
#endif

    if (kungetct)
	ret = STOUC(kungetbuf[--kungetct]);
    else {
	for (;;) {
	    int q = queue_signal_level();
	    dont_queue_signals();
	    r = raw_getbyte(do_keytmout, &cc);
	    restore_queue_signals(q);
	    if (r == -2) {
		/* timeout */
		if (timeout)
		    *timeout = 1;
		return lastchar = EOF;
	    }
	    if (r == 1)
		break;
	    if (r == 0) {
		/* The test for IGNOREEOF was added to make zsh ignore ^Ds
		   that were typed while commands are running.  Unfortuantely
		   this caused trouble under at least one system (SunOS 4.1).
		   Here shells that lost their xterm (e.g. if it was killed
		   with -9) didn't fail to read from the terminal but instead
		   happily continued to read EOFs, so that the above read
		   returned with 0, and, with IGNOREEOF set, this caused
		   an infinite loop.  The simple way around this was to add
		   the counter (icnt) so that this happens 20 times and than
		   the shell gives up (yes, this is a bit dirty...). */
		if ((zlereadflags & ZLRF_IGNOREEOF) && icnt++ < 20)
		    continue;
		stopmsg = 1;
		zexit(1, 0);
	    }
	    icnt = 0;
	    if (errno == EINTR) {
		die = 0;
		if (!errflag && !retflag && !breaks && !exit_pending)
		    continue;
		errflag &= ~ERRFLAG_ERROR;
		breaks = obreaks;
		errno = old_errno;
		return lastchar = EOF;
	    } else if (errno == EWOULDBLOCK) {
		fcntl(0, F_SETFL, 0);
	    } else if (errno == EIO && !die) {
		ret = opts[MONITOR];
		opts[MONITOR] = 1;
		attachtty(mypgrp);
		zrefresh();	/* kludge! */
		opts[MONITOR] = ret;
		die = 1;
	    } else if (errno != 0) {
		zerr("error on TTY read: %e", errno);
		stopmsg = 1;
		zexit(1, 0);
	    }
	}
	if (cc == '\r')		/* undo the exchange of \n and \r determined by */
	    cc = '\n';		/* zsetterm() */
	else if (cc == '\n')
	    cc = '\r';

	ret = STOUC(cc);
    }
    /*
     * vichgbuf is raw bytes, not wide characters, so is dealt
     * with here.
     */
    if (vichgflag) {
	if (vichgbufptr == vichgbufsz)
	    vichgbuf = realloc(vichgbuf, vichgbufsz *= 2);
	vichgbuf[vichgbufptr++] = ret;
    }
    errno = old_errno;
    return lastchar = ret;
}
示例#7
0
int
main(int argc, char **argv)
{
    char **t;
    int t0;
#ifdef USE_LOCALE
    setlocale(LC_ALL, "");
#endif

#ifdef WINNT

/* Do not use __try if compiling with MinGW */
#ifndef MINGW
	__try {
#endif /* MINGW */

/* Start NT if we are compiling with MinGW, don't otherwise */
#ifdef MINGW
	nt_init();
#else
	//nt_init();
#endif /* MINGW */

	fork_init();

/* Do not use __except if compiling with MinGW */
#ifndef MINGW
	}__except(1) {
		dprintf("damn 0x%08x\n",GetExceptionCode());
		return 1;
	};
#endif /* MINGW */
#endif /* WINNT */

    global_permalloc();

    /*
     * Provisionally set up the type table to allow metafication.
     * This will be done properly when we have decided if we are
     * interactive
     */
    typtab['\0'] |= IMETA;
    typtab[STOUC(Meta)  ] |= IMETA;
    typtab[STOUC(Marker)] |= IMETA;
    for (t0 = (int)STOUC(Pound); t0 <= (int)STOUC(Nularg); t0++)
	typtab[t0] |= ITOK | IMETA;

    for (t = argv; *t; *t = metafy(*t, -1, META_ALLOC), t++);

#ifndef WINNT
    if (!(zsh_name = strrchr(argv[0], '/')))
#else
    if (!(zsh_name = strrchr(argv[0], '/')) && 
    	!(zsh_name = strrchr(argv[0], '\\')) &&
    	!(zsh_name = strchr(argv[0],':'))
//    	!(argv[0][1] ==':')
	)
#endif /* WINNT */
	zsh_name = argv[0];
    else
	zsh_name++;
    if (*zsh_name == '-')
	zsh_name++;

    fdtable_size = OPEN_MAX;
    fdtable = zcalloc(fdtable_size);

    emulate(zsh_name, 1);   /* initialises most options */
    opts[LOGINSHELL] = (**argv == '-');
    opts[MONITOR] = 1;   /* may be unset in init_io() */
    opts[PRIVILEGED] = (getuid() != geteuid() || getgid() != getegid());
    opts[USEZLE] = 1;   /* may be unset in init_io() */
    parseargs(argv);   /* sets INTERACTIVE, SHINSTDIN and SINGLECOMMAND */

    SHTTY = -1;
    init_io();
    setupvals();
    init_signals();
    global_heapalloc();
    run_init_scripts();
    init_misc();

    for (;;) {
	do
	    loop(1,0);
	while (tok != ENDINPUT);
	if (!(isset(IGNOREEOF) && interact)) {
#if 0
	    if (interact)
		fputs(islogin ? "logout\n" : "exit\n", shout);
#endif
	    zexit(lastval, 0);
	    continue;
	}
	noexitct++;
	if (noexitct >= 10) {
	    stopmsg = 1;
	    zexit(lastval, 0);
	}
	zerrnam("zsh", (!islogin) ? "use 'exit' to exit."
		: "use 'logout' to logout.", NULL, 0);
    }
    return 0; /* WINNT change, patch I think */
}
示例#8
0
文件: zpty.c 项目: zsh-users/zsh
static int
newptycmd(char *nam, char *pname, char **args, int echo, int nblock)
{
    Ptycmd p;
    int master, slave, pid, oineval = ineval, ret;
    char *oscriptname = scriptname, syncch;
    Eprog prog;

    /* code borrowed from bin_eval() */
    ineval = !isset(EVALLINENO);
    if (!ineval)
	scriptname = "(zpty)";

    prog = parse_string(zjoin(args, ' ', 1), 0);
    if (!prog) {
	errflag &= ~ERRFLAG_ERROR;
	scriptname = oscriptname;
	ineval = oineval;
	return 1;
    }

    if (get_pty(1, &master)) {
	zwarnnam(nam, "can't open pseudo terminal: %e", errno);
	scriptname = oscriptname;
	ineval = oineval;
	return 1;
    }
    if ((pid = fork()) == -1) {
	zwarnnam(nam, "can't create pty command %s: %e", pname, errno);
	close(master);
	scriptname = oscriptname;
	ineval = oineval;
	return 1;
    } else if (!pid) {
	/* This code copied from the clone module, except for getting *
	 * the descriptor from get_pty() and duplicating it to 0/1/2. */

	deletehookfunc("exit", ptyhook);
	clearjobtab(0);
	ppid = getppid();
	mypid = getpid();
#ifdef HAVE_SETSID
	if (setsid() != mypid) {
	    zwarnnam(nam, "failed to create new session: %e", errno);
#endif
#ifdef TIOCNOTTY
	    if (ioctl(SHTTY, TIOCNOTTY, 0))
		zwarnnam(nam, "%e", errno);
	    setpgrp(0L, mypid);
#endif
#ifdef HAVE_SETSID
	}
#endif

	if (get_pty(0, &slave))
	    exit(1);
	SHTTY = slave;
	attachtty(mypid);
#ifdef TIOCGWINSZ
	/* Set the window size before associating with the terminal *
	 * so that we don't get hit with a SIGWINCH.  I'm paranoid. */
	if (interact) {
	    struct ttyinfo info;

	    if (ioctl(slave, TIOCGWINSZ, (char *) &info.winsize) == 0) {
		info.winsize.ws_row = zterm_lines;
		info.winsize.ws_col = zterm_columns;
		ioctl(slave, TIOCSWINSZ, (char *) &info.winsize);
	    }
	}
#endif /* TIOCGWINSZ */

	if (!echo) {
	    struct ttyinfo info;

	    if (!ptygettyinfo(slave, &info)) {
#ifdef HAVE_TERMIOS_H
		info.tio.c_lflag &= ~ECHO;
#else
#ifdef HAVE_TERMIO_H
		info.tio.c_lflag &= ~ECHO;
#else
		info.tio.lmodes &= ~ECHO; /**** dunno if this is right */
#endif
#endif
		ptysettyinfo(slave, &info);
	    }
	}

#ifdef TIOCSCTTY
	ioctl(slave, TIOCSCTTY, 0);
#endif

	close(0);
	close(1);
	close(2);

	dup2(slave, 0);
	dup2(slave, 1);
	dup2(slave, 2);

	closem(FDT_UNUSED, 0);
	close(slave);
	close(master);
	close(coprocin);
	close(coprocout);
	init_io(NULL);
	setsparam("TTY", ztrdup(ttystrname));

	opts[INTERACTIVE] = 0;

	syncch = 0;
	do {
	    ret = write(1, &syncch, 1);
	} while (ret != 1 && (
#ifdef EWOULDBLOCK
	    errno == EWOULDBLOCK ||
#else
#ifdef EAGAIN
	    errno == EAGAIN ||
#endif
#endif
	    errno == EINTR));

	execode(prog, 1, 0, "zpty");
	stopmsg = 2;
	mypid = 0; /* trick to ensure we _exit() */
	zexit(lastval, 0);
    }
    master = movefd(master);
    if (master == -1) {
	zerrnam(nam, "cannot duplicate fd %d: %e", master, errno);
	scriptname = oscriptname;
	ineval = oineval;
	return 1;
    }

    p = (Ptycmd) zalloc(sizeof(*p));

    p->name = ztrdup(pname);
    p->args = zarrdup(args);
    p->fd = master;
    p->pid = pid;
    p->echo = echo;
    p->nblock = nblock;
    p->fin = 0;
    p->read = -1;
    p->old = NULL;
    p->olen = 0;

    p->next = ptycmds;
    ptycmds = p;

    if (nblock)
	ptynonblock(master);

    scriptname = oscriptname;
    ineval = oineval;

    do {
	ret = read(master, &syncch, 1);
    } while (ret != 1 && (
#ifdef EWOULDBLOCK
	    errno == EWOULDBLOCK ||
#else
#ifdef EAGAIN
	    errno == EAGAIN ||
#endif
#endif
	    errno == EINTR));

    setiparam_no_convert("REPLY", (zlong)master);

    return 0;
}