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 */ }
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, "a); if (fd != 0) close(fd); return (status); }
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); }
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); }
/*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); }
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; }
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 */ }
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; }