Пример #1
0
static char *GetProcessOptions()
{
# ifdef HAVE_GETZONEID
    zoneid_t zid;
    char zone[ZONENAME_MAX];
    static char psopts[CF_BUFSIZE];

    zid = getzoneid();
    getzonenamebyid(zid, zone, ZONENAME_MAX);

    if (strcmp(zone, "global") == 0)
    {
        snprintf(psopts, CF_BUFSIZE, "%s,zone", VPSOPTS[VSYSTEMHARDCLASS]);
        return psopts;
    }
# endif

# ifdef LINUX
    if (strncmp(VSYSNAME.release, "2.4", 3) == 0)
    {
        // No threads on 2.4 kernels
        return "-eo user,pid,ppid,pgid,pcpu,pmem,vsz,pri,rss,stime,time,args";
    }

# endif

    return VPSOPTS[VSYSTEMHARDCLASS];
}
Пример #2
0
/*
 * -t prints "shared" vs. "exclusive"
 */
int
main(int argc, char *argv[])
{
	zoneid_t zoneid;
	char zonename[ZONENAME_MAX];
	FILE *fp;
	int arg;
	boolean_t stacktype = B_FALSE;

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

	opterr = 0;
	while ((arg = getopt(argc, argv, "t")) != EOF) {
		switch (arg) {
		case 't':
			stacktype = B_TRUE;
			break;
		}
	}

	zoneid = getzoneid();

	if (stacktype) {
		ushort_t flags;

		if (zone_getattr(zoneid, ZONE_ATTR_FLAGS, &flags,
		    sizeof (flags)) < 0) {
			perror("could not determine zone IP type");
			exit(1);
		}
		if (flags & ZF_NET_EXCL)
			(void) puts("exclusive");
		else
			(void) puts("shared");
		return (0);
	}

	if (getzonenamebyid(zoneid, zonename, sizeof (zonename)) < 0) {
		(void) fputs(gettext("could not determine zone name\n"),
		    stderr);
		return (1);
	}

	/*
	 * The use of dlopen here is a bit ugly, but it allows zonename to
	 * function properly before /usr is mounted.  On such a system, scratch
	 * zones don't exist, so no translation is necessary.
	 */
	if (dlopen("libzonecfg.so.1", RTLD_NOW | RTLD_GLOBAL) != NULL &&
	    zonecfg_is_scratch(zonename) &&
	    (fp = zonecfg_open_scratch("", B_FALSE)) != NULL) {
		(void) zonecfg_reverse_scratch(fp, zonename, zonename,
		    sizeof (zonename), NULL, 0);
		zonecfg_close_scratch(fp);
	}
	(void) puts(zonename);
	return (0);
}
Пример #3
0
int
zone_get_id(const char *str, zoneid_t *zip)
{
	zoneid_t zoneid;
	char *cp;

	/*
	 * The first time we are called, attempt to dlopen() libzonecfg.so.1
	 * and get a pointer to the real zone_get_id().
	 * If we fail, set our pointer to -1 so we won't try again.
	 */
	if (real_zone_get_id == NULL) {
		/*
		 * There's no harm in doing this more than once, even
		 * concurrently.  We will get the same result each time,
		 * and the dynamic linker will single-thread the dlopen()
		 * with its own internal lock.  The worst that can happen
		 * is that the handle gets a reference count greater than
		 * one, which doesn't matter since we never dlclose()
		 * the handle if we successfully find the symbol; the
		 * library just stays in the address space until exit().
		 */
		void *dlhandle = dlopen("libzonecfg.so.1", RTLD_LAZY);
		void *sym = (void *)(-1);

		if (dlhandle != NULL &&
		    (sym = dlsym(dlhandle, "zone_get_id")) == NULL) {
			sym = (void *)(-1);
			(void) dlclose(dlhandle);
		}
		real_zone_get_id = (zone_get_id_t)sym;
	}

	/*
	 * If we've successfully loaded it, call the real zone_get_id().
	 * Otherwise, perform our stripped-down version of the code.
	 */
	if (real_zone_get_id != (zone_get_id_t)(-1))
		return (real_zone_get_id(str, zip));

	/* first try looking for active zone by id */
	errno = 0;
	zoneid = (zoneid_t)strtol(str, &cp, 0);
	if (errno == 0 && cp != str && *cp == '\0' &&
	    getzonenamebyid(zoneid, NULL, 0) != -1) {
		*zip = zoneid;
		return (0);
	}

	/* then look for active zone by name */
	if ((zoneid = getzoneidbyname(str)) != -1) {
		*zip = zoneid;
		return (0);
	}

	/* not an active zone, return error */
	return (-1);
}
Пример #4
0
void
lookup_zonename(char *zonename, size_t zonesize)
{
    zoneid_t zoneid = getzoneid();

    if (getzonenamebyid(zoneid, zonename, zonesize) >= 0)
        return;
    syslog(LOG_ERR, "could not determine zone name");
    (void) strlcpy(zonename, GLOBAL_ZONENAME, zonesize);
}
Пример #5
0
/*ARGSUSED*/
static int
ipdadm_list(int argc, char *argv[])
{
	int fd, rval;
	unsigned int ii;
	ipd_ioc_list_t ipil;
	char zonename[ZONENAME_MAX];

	if (argc != 0)
		return (usage(stderr));

	fd = ipdadm_open();
	(void) memset(&ipil, '\0', sizeof (ipd_ioc_list_t));

	rval = ioctl(fd, IPDIOC_LIST, &ipil);
	if (rval != 0) {
		(void) fprintf(stderr, "%s: failed to get list info: %s\n",
		    g_pname, strerror(errno));
		return (E_ERROR);
	}

	ipil.ipil_list = malloc(sizeof (zoneid_t) * ipil.ipil_nzones);
	if (ipil.ipil_list == NULL) {
		(void) fprintf(stderr, "%s: failed to allocate memory: %s\n",
		    g_pname, strerror(errno));
		return (E_ERROR);
	}

	rval = ioctl(fd, IPDIOC_LIST, &ipil);
	if (rval != 0) {
		free(ipil.ipil_list);
		(void) fprintf(stderr, "%s: failed to get list info: %s\n",
		    g_pname, strerror(errno));
		return (E_ERROR);
	}

	for (ii = 0; ii < ipil.ipil_nzones; ii++) {
		if (getzonenamebyid(ipil.ipil_list[ii], zonename,
		    sizeof (zonename)) < 0) {
			(void) fprintf(stderr, "%s: failed to get zonename: "
			    "%s\n", g_pname, strerror(errno));
			return (E_ERROR);
		}
		(void) printf("%s\n", zonename);
	}

	return (E_SUCCESS);
}
Пример #6
0
char *
get_labeled_zonename(char *slabel)
{
	m_label_t	*bsl = NULL;
	int	err = 0;
	ssize_t	zonename_size = -1;
	zoneid_t	zid = -1;
	char *zname = NULL;

	syslog(LOG_DEBUG, "lpsched: get_labeled_zonename %s", slabel);
	/*
	 * convert the label to binary.
	 */
	if (str_to_label(slabel, &bsl, USER_CLEAR,
	    L_NO_CORRECTION, &err) == -1) {
		/* label could not be converted, error */
		syslog(LOG_WARNING,
		    "lpsched: %s: label not recognized (error==%d)",
		    slabel, err);
		return ((char *)-1);
	}
	if ((zid = getzoneidbylabel(bsl)) < 0) {
		/* no zone with that label, cannot send mail */
		syslog(LOG_WARNING,
		    "lpsched: cannot send mail, no zone with %s label",
		    slabel);
		m_label_free(bsl);
		return ((char *)-1);
	}
	zname = Malloc(ZONENAME_MAX + 1);
	if ((zonename_size = getzonenamebyid(zid, zname, ZONENAME_MAX + 1))
	    == -1) {
		/* cannot get zone name, cannot send mail */
		syslog(LOG_WARNING,
		    "lpsched: cannot send mail, no zone name for %s",
		    slabel);
		m_label_free(bsl);
		Free(zname);
		return ((char *)-1);
	} else {
		m_label_free(bsl);
		if (strcmp(zname, GLOBAL_ZONENAME) == 0) {
			Free(zname);
			zname = NULL;
		}
	}
	return (zname);
}
Пример #7
0
static void zone_submit_values(c_avl_tree_t *tree) {
  char zonename[ZONENAME_MAX];
  zoneid_t *zoneid = NULL;
  zone_stats_t *stats = NULL;

  while (c_avl_pick(tree, (void **)&zoneid, (void **)&stats) == 0) {
    if (getzonenamebyid(*zoneid, zonename, sizeof(zonename)) == -1) {
      WARNING("zone plugin: error retrieving zonename");
    } else {
      zone_submit_value(zonename, (gauge_t)FRC2PCT(stats->pctcpu));
    }
    free(stats);
    free(zoneid);
  }
  c_avl_destroy(tree);
}
Пример #8
0
static boolean_t
libbrand_initialize()
{
	static mutex_t initialize_lock = DEFAULTMUTEX;

	(void) mutex_lock(&initialize_lock);

	if (libbrand_initialized) {
		(void) mutex_unlock(&initialize_lock);
		return (B_TRUE);
	}

	if (sysinfo(SI_ARCHITECTURE, i_curr_arch, sizeof (i_curr_arch)) < 0) {
		(void) mutex_unlock(&initialize_lock);
		return (B_FALSE);
	}

	if (getzonenamebyid(getzoneid(), i_curr_zone,
	    sizeof (i_curr_zone)) < 0) {
		(void) mutex_unlock(&initialize_lock);
		return (B_FALSE);
	}

	/*
	 * Note that here we're initializing per-process libxml2
	 * state.  By doing so we're implicitly assuming that
	 * no other code in this process is also trying to
	 * use libxml2.  But in most case we know this not to
	 * be true since we're almost always used in conjunction
	 * with libzonecfg, which also uses libxml2.  Lucky for
	 * us, libzonecfg initializes libxml2 to essentially
	 * the same defaults as we're using below.
	 */
	(void) xmlLineNumbersDefault(1);
	xmlLoadExtDtdDefaultValue |= XML_DETECT_IDS;
	xmlDoValidityCheckingDefaultValue = 1;
	(void) xmlKeepBlanksDefault(0);
	xmlGetWarningsDefaultValue = 0;
	xmlSetGenericErrorFunc(NULL, brand_error_func);

	libbrand_initialized = B_TRUE;
	(void) mutex_unlock(&initialize_lock);
	return (B_TRUE);
}
Пример #9
0
static void
ipdadm_list_one(zoneid_t z, const ipd_config_t *icp, void *arg)
{
	char zonename[ZONENAME_MAX];
	int opt_v = (int)(intptr_t)arg;

	if (getzonenamebyid(z, zonename, sizeof (zonename)) < 0)
		(void) printf("%ld", z);
	else
		(void) printf("%s", zonename);

	if (!opt_v) {
		(void) printf("\n");
		return;
	}

	(void) printf("\t%u\t%u\t%u\n", icp->ic_corrupt, icp->ic_drop,
	    icp->ic_delay);
}
Пример #10
0
static int ForeignZone(char *s)
{
// We want to keep the banner

    if (strstr(s, "%CPU"))
    {
        return false;
    }

# ifdef HAVE_GETZONEID
    zoneid_t zid;
    char *sp, zone[ZONENAME_MAX];
    static psopts[CF_BUFSIZE];

    zid = getzoneid();
    getzonenamebyid(zid, zone, ZONENAME_MAX);

    if (strcmp(zone, "global") == 0)
    {
        if (strcmp(s + strlen(s) - 6, "global") == 0)
        {
            *(s + strlen(s) - 6) = '\0';

            for (sp = s + strlen(s) - 1; isspace(*sp); sp--)
            {
                *sp = '\0';
            }

            return false;
        }
        else
        {
            return true;
        }
    }
# endif
    return false;
}
Пример #11
0
static void
sendmes_tozone(zoneid_t zid, int aflag) {
	int i = 0;
	char zonename[ZONENAME_MAX], root[MAXPATHLEN];
	struct utmpx *p;

	if (zid != getzoneid()) {
		root[0] = '\0';
		(void) getzonenamebyid(zid, zonename, ZONENAME_MAX);
		(void) zone_get_rootpath(zonename, root, sizeof (root));
		(void) strlcat(root, UTMPX_FILE, sizeof (root));
		if (!utmpxname(root)) {
			(void) fprintf(stderr, "Cannot open %s\n", root);
			return;
		}
	} else {
		(void) utmpxname(UTMPX_FILE);
	}
	setutxent();
	while ((p = getutxent()) != NULL) {
		if (p->ut_type != USER_PROCESS)
			continue;
		/*
		 * if (-a option OR NOT pty window login), send the message
		 */
		if (aflag || !nonuserx(*p))
			sendmes(p, zid);
	}
	endutxent();

	(void) alarm(60);
	do {
		i = (int)wait((int *)0);
	} while (i != -1 || errno != ECHILD);

}
Пример #12
0
int
main(int argc, char *argv[])
{
	int ii;
	ipdadm_cmd_t *cmd;

	g_pname = basename(argv[0]);

	if (argc < 2)
		return (usage(stderr));
	argc--;
	argv++;

	g_zid = getzoneid();
	if (strcmp("-z", argv[0]) == 0) {
		argc--;
		argv++;
		if (argc < 1) {
			(void) fprintf(stderr, "%s: -z requires an argument\n",
			    g_pname);
			return (usage(stderr));
		}

		if (g_zid != GLOBAL_ZONEID) {
			(void) fprintf(stderr, "%s: -z option only permitted "
			    "in global zone\n", g_pname);
			return (usage(stderr));
		}

		g_zid = getzoneidbyname(argv[0]);
		if (g_zid == -1) {
			(void) fprintf(stderr, "%s: %s: invalid zone\n",
			    g_pname, argv[0]);
			return (E_ERROR);
		}
		argc--;
		argv++;
	}

	if (getzonenamebyid(g_zid, g_zonename, sizeof (g_zonename)) < 0) {
		(void) fprintf(stderr, "%s: failed to get zonename: %s\n",
		    g_pname, strerror(errno));
		return (E_ERROR);
	}

	if (argc < 1)
		return (usage(stderr));

	for (ii = 0; ii < IPDADM_NCMDS; ii++) {
		cmd = &ipdadm_cmds[ii];
		if (strcmp(argv[0], cmd->idc_name) == 0) {
			argv++;
			argc--;
			assert(cmd->idc_func != NULL);
			return (cmd->idc_func(argc, argv));
		}
	}

	(void) fprintf(stderr, "%s: %s: unknown command\n", g_pname, argv[0]);
	return (usage(stderr));
}
Пример #13
0
/*
 * Note to future maintainers: with the change of wall to use the
 * getutxent() API, the forked children (created by this function)
 * must call _exit as opposed to exit. This is necessary to avoid
 * unwanted fflushing of getutxent's stdio stream (caused by atexit
 * processing).
 */
static void
sendmes(struct utmpx *p, zoneid_t zid)
{
	int i;
	char *s;
	static char device[LMAX + 6];
	char *bp;
	int ibp;
	FILE *f;
	int fd, tmpl_fd;
	boolean_t zoneenter = B_FALSE;

	if (zid != getzoneid()) {
		zoneenter = B_TRUE;
		tmpl_fd = init_template();
		if (tmpl_fd == -1) {
			(void) fprintf(stderr, "Could not initialize "
			    "process contract");
			return;
		}
	}

	while ((i = (int)fork()) == -1) {
		(void) alarm(60);
		(void) wait((int *)0);
		(void) alarm(0);
	}

	if (i)
		return;

	if (zoneenter && zone_enter(zid) == -1) {
		char zonename[ZONENAME_MAX];
		(void) getzonenamebyid(zid, zonename, ZONENAME_MAX);
		(void) fprintf(stderr, "Could not enter zone "
		    "%s\n", zonename);
	}
	if (zoneenter)
		(void) ct_tmpl_clear(tmpl_fd);

	if (gflag)
		if (!chkgrp(p->ut_user))
			_exit(0);

	(void) signal(SIGHUP, SIG_IGN);
	(void) alarm(60);
	s = &device[0];
	(void) snprintf(s, sizeof (device), "/dev/%.*s", LMAX, p->ut_line);

	/* check if the device is really a tty */
	if ((fd = open(s, O_WRONLY|O_NOCTTY|O_NONBLOCK)) == -1) {
		(void) fprintf(stderr, "Cannot send to %.*s on %s\n",
		    NMAX, p->ut_user, s);
		perror("open");
		(void) fflush(stderr);
		_exit(1);
	} else {
		if (!isatty(fd)) {
			(void) fprintf(stderr,
			    "Cannot send to device %.*s %s\n",
			    LMAX, p->ut_line,
			    "because it's not a tty");
			openlog("wall", 0, LOG_AUTH);
			syslog(LOG_CRIT, "%.*s in utmpx is not a tty\n",
			    LMAX, p->ut_line);
			closelog();
			(void) fflush(stderr);
			_exit(1);
		}
	}
#ifdef DEBUG
	(void) close(fd);
	f = fopen("wall.debug", "a");
#else
	f = fdopen(fd, "w");
#endif
	if (f == NULL) {
		(void) fprintf(stderr, "Cannot send to %-.*s on %s\n",
		    NMAX, &p->ut_user[0], s);
		perror("open");
		(void) fflush(stderr);
		_exit(1);
	}
	(void) fprintf(f,
	    "\07\07\07Broadcast Message from %s (%s) on %s %19.19s",
	    who, line, systm, time_buf);
	if (gflag)
		(void) fprintf(f, " to group %s", grpname);
	(void) fprintf(f, "...\n");
#ifdef DEBUG
	(void) fprintf(f, "DEBUG: To %.*s on %s\n", NMAX, p->ut_user, s);
#endif
	i = strlen(mesg);
	for (bp = mesg; --i >= 0; bp++) {
		ibp = (unsigned int)((unsigned char) *bp);
		if (*bp == '\n')
			(void) putc('\r', f);
		if (isprint(ibp) || *bp == '\r' || *bp == '\013' ||
		    *bp == ' ' || *bp == '\t' || *bp == '\n' || *bp == '\007') {
			(void) putc(*bp, f);
		} else {
			if (!isascii(*bp)) {
				(void) fputs("M-", f);
				*bp = toascii(*bp);
			}
			if (iscntrl(*bp)) {
				(void) putc('^', f);
				(void) putc(*bp + 0100, f);
			}
			else
				(void) putc(*bp, f);
		}

		if (*bp == '\n')
			(void) fflush(f);

		if (ferror(f) || feof(f)) {
			(void) printf("\n\007Write failed\n");
			(void) fflush(stdout);
			_exit(1);
		}
	}
	(void) fclose(f);
	(void) close(fd);
	_exit(0);
}
Пример #14
0
/*
 * If the system is labeled then we need to
 * have a uniquely-named auto_home map for each zone.
 * The maps are made unique by appending the zonename.
 * The home directory is made unique by prepending /zone/<zonename>
 * for each zone that is dominated by the current zone.
 * The current zone's home directory mount point is not changed.
 *
 * For each auto_home_<zonename> a default template map is created
 * only if it doesn't exist yet. The default entry is used to declare
 * local home directories created within each zone. For example:
 *
 *	+auto_home_public
 *      * -fstype=lofs :/zone/public/export/home/&
 */
static void
loadzone_maps(char *mntpnt, char *map, char *opts, char **stack, char ***stkptr)
{
	zoneid_t *zids = NULL;
	zoneid_t my_zoneid;
	uint_t nzents_saved;
	uint_t nzents;
	int i;

	if (!priv_ineffect(PRIV_SYS_MOUNT))
		return;

	if (zone_list(NULL, &nzents) != 0) {
		return;
	}
	my_zoneid = getzoneid();
again:
	if (nzents == 0)
		return;

	zids = malloc(nzents * sizeof (zoneid_t));
	nzents_saved = nzents;

	if (zone_list(zids, &nzents) != 0) {
		free(zids);
		return;
	}
	if (nzents != nzents_saved) {
		/* list changed, try again */
		free(zids);
		goto again;
	}

	for (i = 0; i < nzents; i++) {
		char zonename[ZONENAME_MAX];
		char zoneroot[MAXPATHLEN];

		if (getzonenamebyid(zids[i], zonename, ZONENAME_MAX) != -1) {
			char appended_map[MAXPATHLEN];
			char prepended_mntpnt[MAXPATHLEN];
			char map_path[MAXPATHLEN];
			int fd;

			(void) snprintf(appended_map, sizeof (appended_map),
			    "%s_%s", map, zonename);

			/* for current zone, leave mntpnt alone */
			if (zids[i] != my_zoneid) {
				(void) snprintf(prepended_mntpnt,
				    sizeof (prepended_mntpnt),
				    "/zone/%s%s", zonename, mntpnt);
				if (zone_getattr(zids[i], ZONE_ATTR_ROOT,
				    zoneroot, sizeof (zoneroot)) == -1)
					continue;
			} else {
				(void) strcpy(prepended_mntpnt, mntpnt);
				zoneroot[0] = '\0';
			}

			dirinit(prepended_mntpnt, appended_map, opts, 0, stack,
			    stkptr);
			/*
			 * Next create auto_home_<zone> maps for each zone
			 */

			(void) snprintf(map_path, sizeof (map_path),
			    "/etc/%s", appended_map);
			/*
			 * If the map file doesn't exist create a template
			 */
			if ((fd = open(map_path, O_RDWR | O_CREAT | O_EXCL,
			    S_IRUSR | S_IWUSR | S_IRGRP| S_IROTH)) != -1) {
				int len;
				char map_rec[MAXPATHLEN];

				len = snprintf(map_rec, sizeof (map_rec),
				    "+%s\n*\t-fstype=lofs\t:%s/export/home/&\n",
				    appended_map, zoneroot);
				if (len <= sizeof (map_rec))
					(void) write(fd, map_rec, len);
				(void) close(fd);
			}
		}
	}
	free(zids);
}
Пример #15
0
void
process_ids(char *pool_name, uint_t flags, idtype_t idtype, char *idstr,
    int argc, char *argv[])
{
	int i;
	id_t id;

	for (i = 0; i < argc; i++) {
		char *endp;
		char *poolname;

		errno = 0;
		id = (id_t)strtol(argv[i], &endp, 10);
		if (errno != 0 ||
		    (endp && endp != argv[i] + strlen(argv[i])) ||
		    (idtype == P_ZONEID &&
		    getzonenamebyid(id, NULL, 0) == -1)) {
			/*
			 * The string does not completely parse to
			 * an integer, or it represents an invalid
			 * zone id.
			 */

			/*
			 * It must be a project or zone name.
			 */
			if (idtype == P_ZONEID) {
				if (zone_get_id(argv[i], &id) != 0) {
					warn(gettext("invalid zone '%s'\n"),
					    argv[i]);
					error = E_ERROR;
					continue;
				}
				/* make sure the zone is booted */
				if (id == -1) {
					warn(gettext("zone '%s' is not "
					    "active\n"), argv[i]);
					error = E_ERROR;
					continue;
				}
			} else if (idtype == P_PROJID) {
				if ((id = getprojidbyname(argv[i])) < 0) {
					warn(gettext("failed to get project "
					    "id for project: '%s'"), argv[i]);
					error = E_ERROR;
					continue;
				}
			} else {
				warn(gettext("invalid %s '%s'\n"),
				    idstr, argv[i]);
				error = E_ERROR;
				continue;
			}
		}

		if (flags & pFLAG) {
			if (pool_set_binding(pool_name, idtype, id) !=
			    PO_SUCCESS) {
				warn(gettext("binding %s %ld to pool '%s': "
				    "%s\n"), idstr, id, pool_name,
				    get_errstr());
				error = E_ERROR;
			}
			continue;
		}

		if (flags & qFLAG) {
			if ((poolname = pool_get_binding(id)) == NULL) {
				warn(gettext("couldn't determine binding for "
				    "pid %ld: %s\n"), id, get_errstr());
				error = E_ERROR;
			} else {
				(void) printf("%ld\t%s\n", id, poolname);
				free(poolname);
			}
		}
		if (flags & QFLAG) {
			uint_t j, count;
			const char **resource_types;
			(void) pool_resource_type_list(NULL, &count);

			if ((resource_types = malloc(count *
			    sizeof (const char *))) == NULL) {
				warn(gettext("couldn't allocate query memory "
				    "for pid %ld: %s\n"), id, get_errstr());
				error = E_ERROR;
			}
			(void) pool_resource_type_list(resource_types, &count);

			for (j = 0; j < count; j++)
				(void) print_resource_binding(resource_types[j],
				    (pid_t)id);
			free(resource_types);
		}
	}
}
Пример #16
0
static void
convert_path(const char *path, char *fname, size_t size,
    struct ps_prochandle *P)
{
	char *p, *s;
	ssize_t len;
	const psinfo_t *pip = Ppsinfo(P);
	int got_uts = 0;
	struct utsname uts;
	char exec[PATH_MAX];

	fname[size - 1] = '\0';
	size--;

	while ((p = strchr(path, '%')) != NULL && size != 0) {
		len = MIN(size, p - path);
		bcopy(path, fname, len);

		fname += len;
		if ((size -= len) == 0)
			break;

		p++;
		switch (*p) {
		case 'p':
			len = snprintf(fname, size, "%d", (int)pip->pr_pid);
			break;
		case 'u':
			len = snprintf(fname, size, "%d", (int)pip->pr_uid);
			break;
		case 'g':
			len = snprintf(fname, size, "%d", (int)pip->pr_gid);
			break;
		case 'f':
			len = snprintf(fname, size, "%s", pip->pr_fname);
			break;
		case 'd':
			len = 0;
			if (Pexecname(P, exec, sizeof (exec)) == NULL ||
			    exec[0] != '/' || (s = strrchr(exec, '/')) == NULL)
				break;

			*s = '\0';
			len = snprintf(fname, size, "%s", &exec[1]);
			break;
		case 'n':
			if (got_uts++ == 0)
				(void) uname(&uts);
			len = snprintf(fname, size, "%s", uts.nodename);
			break;
		case 'm':
			if (got_uts++ == 0)
				(void) uname(&uts);
			len = snprintf(fname, size, "%s", uts.machine);
			break;
		case 't':
			len = snprintf(fname, size, "%ld", (long)time(NULL));
			break;
		case 'z':
			/*
			 * getzonenamebyid() returns the size including the
			 * terminating null byte so we need to adjust len.
			 */
			if ((len = getzonenamebyid(pip->pr_zoneid, fname,
			    size)) < 0)
				len = snprintf(fname, size, "%d",
				    (int)pip->pr_zoneid);
			else
				len--;
			break;
		case '%':
			*fname = '%';
			len = 1;
			break;
		default:
			len = snprintf(fname, size, "%%%c", *p);
		}

		if (len >= size)
			return;

		fname += len;
		size -= len;

		path = p + 1;
	}

	(void) strncpy(fname, path, size);
}
Пример #17
0
/*
 * kw_init -- initialize keywords based on given filename
 */
void
kw_init(struct fn *fnp, struct fn *nfnp)
{
	static char *fullpath;
	static char *nfullpath;
	static char *splitpath;
	static char secs[MAXDIGITS];
	static struct utsname un;
	static char platform[SYS_NMLN];
	static char isa[SYS_NMLN];
	static char domain[256];
	static char *home;
	static char *user;
	static char *logname;
	static char zonename[ZONENAME_MAX];
	static zoneid_t zoneid;
	static int initialized;
	char *ptr;

	/* make a copy of the string for $file */
	if (fullpath)
		FREE(fullpath);
	fullpath = STRDUP(fn_s(fnp));
	Keywords = lut_add(Keywords, "file", fullpath);

	/* make a copy of the string for $nfile */
	if (nfullpath)
		FREE(nfullpath);
	if (nfnp == NULL) {
		nfullpath = NULL;
		Keywords = lut_add(Keywords, "nfile", "");
	} else {
		nfullpath = STRDUP(fn_s(nfnp));
		Keywords = lut_add(Keywords, "nfile", nfullpath);
	}

	/* make a copy of the string for $dirname/$basename */
	if (splitpath)
		FREE(splitpath);
	splitpath = STRDUP(fn_s(fnp));

	if ((ptr = strrchr(splitpath, '/')) == NULL) {
		Keywords = lut_add(Keywords, "basename", splitpath);
		Keywords = lut_add(Keywords, "dirname", ".");
	} else {
		*ptr++ = '\0';
		Keywords = lut_add(Keywords, "basename", ptr);
		Keywords = lut_add(Keywords, "dirname", splitpath);
	}

	if (initialized)
		return;		/* rest of the keywords don't change */

	(void) snprintf(secs, MAXDIGITS, "%d", (int)Now);
	Keywords = lut_add(Keywords, "secs", secs);

	if (uname(&un) < 0)
		err(EF_SYS, "uname");

	Keywords = lut_add(Keywords, "nodename", un.nodename);
	Keywords = lut_add(Keywords, "release", un.release);
	Keywords = lut_add(Keywords, "machine", un.machine);

	if (sysinfo(SI_ARCHITECTURE, isa, sizeof (isa)) == -1)
		err(EF_WARN|EF_SYS, "sysinfo(SI_ARCHITECTURE) failed.");
	else
		Keywords = lut_add(Keywords, "isa", isa);

	if (sysinfo(SI_PLATFORM, platform, sizeof (platform)) == -1)
		err(EF_WARN|EF_SYS, "sysinfo(SI_PLATFORM) failed.");
	else
		Keywords = lut_add(Keywords, "platform", platform);

	if (sysinfo(SI_SRPC_DOMAIN, domain, sizeof (domain)) == -1)
		err(EF_WARN|EF_SYS, "sysinfo(SI_SRPC_DOMAIN) failed.");
	else
		Keywords = lut_add(Keywords, "domain", domain);

	if ((home = getenv("HOME")) != NULL)
		Keywords = lut_add(Keywords, "home", STRDUP(home));

	if ((user = getenv("USER")) != NULL)
		Keywords = lut_add(Keywords, "user", STRDUP(user));

	if ((logname = getenv("LOGNAME")) != NULL)
		Keywords = lut_add(Keywords, "logname", STRDUP(logname));

	zoneid = getzoneid();
	if ((getzonenamebyid(zoneid, zonename, sizeof (zonename))) == -1)
		err(EF_WARN|EF_SYS, "getzonenamebyid() failed.");
	else
		Keywords = lut_add(Keywords, "zonename", STRDUP(zonename));

	initialized = 1;
}
Пример #18
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);
}
Пример #19
0
/*
 * init_env()
 *   A clone of the work init.c does to provide as much compatibility
 *   for startup scripts as possible.
 */
void
init_env()
{
	int	i;
	char	line[MAXCMDL];
	FILE	*fp;
	int	inquotes, length, wslength;
	char	*tokp, *cp1, *cp2;
	char	**newp;

	glob_env_n = 16;
	glob_envp = startd_alloc(sizeof (*glob_envp) * glob_env_n);

	glob_envp[0] = startd_alloc((unsigned)(strlen(DEF_PATH)+2));
	(void) strcpy(glob_envp[0], DEF_PATH);

	if ((fp = fopen(ENVFILE, "r")) == NULL) {
		uu_warn("Cannot open %s. Environment not initialized.\n",
		    ENVFILE);

		glob_envp[1] = NULL;
		return;
	}

	i = 1;

	while (fgets(line, MAXCMDL - 1, fp) != NULL) {
		/*
		 * Toss newline
		 */
		length = strlen(line);
		if (line[length - 1] == '\n')
			line[length - 1] = '\0';

		/*
		 * Ignore blank or comment lines.
		 */
		if (line[0] == '#' || line[0] == '\0' ||
		    (wslength = strspn(line, " \t\n")) == strlen(line) ||
		    strchr(line, '#') == line + wslength)
			continue;

		/*
		 * First make a pass through the line and change
		 * any non-quoted semi-colons to blanks so they
		 * will be treated as token separators below.
		 */
		inquotes = 0;
		for (cp1 = line; *cp1 != '\0'; cp1++) {
			if (*cp1 == '"') {
				if (inquotes == 0)
					inquotes = 1;
				else
					inquotes = 0;
			} else if (*cp1 == ';') {
				if (inquotes == 0)
					*cp1 = ' ';
			}
		}

		/*
		 * Tokens within the line are separated by blanks
		 *  and tabs.  For each token in the line which
		 * contains a '=' we strip out any quotes and then
		 * stick the token in the environment array.
		 */
		if ((tokp = strtok(line, " \t")) == NULL)
			continue;

		do {
			cp1 = strchr(tokp, '=');
			if (cp1 == NULL || cp1 == tokp)
				continue;
			length = strlen(tokp);
			while ((cp1 = strpbrk(tokp, "\"\'")) != NULL) {
				for (cp2 = cp1; cp2 < &tokp[length]; cp2++)
					*cp2 = *(cp2 + 1);
				length--;
			}

			/*
			 * init already started us with this umask, and we
			 * handled it in startd.c, so just skip it.
			 */
			if (strncmp(tokp, "CMASK=", 6) == 0 ||
			    strncmp(tokp, "SMF_", 4) == 0)
				continue;

			glob_envp[i] = startd_alloc((unsigned)(length + 1));
			(void) strcpy(glob_envp[i], tokp);

			/*
			 * Double the environment size whenever it is
			 * full.
			 */
			if (++i == glob_env_n) {
				glob_env_n *= 2;
				newp = startd_alloc(sizeof (*glob_envp) *
				    glob_env_n);
				(void) memcpy(newp, glob_envp,
				    sizeof (*glob_envp) * glob_env_n / 2);
				startd_free(glob_envp,
				    sizeof (*glob_envp) * glob_env_n / 2);
				glob_envp = newp;
			}
		} while ((tokp = strtok(NULL, " \t")) != NULL);
	}

	startd_fclose(fp);

	/* Append a null pointer to the environment array to mark its end. */
	glob_envp[i] = NULL;

	/*
	 * Get the zonename once; it is used to set SMF_ZONENAME for methods.
	 */
	(void) getzonenamebyid(getzoneid(), zonename, sizeof (zonename));

}