Home | History | Annotate | Line # | Download | only in luactl
      1 /*	$NetBSD: luactl.c,v 1.2 2013/10/29 16:11:15 joerg Exp $ */
      2 
      3 /*
      4  * Copyright (c) 2011, Marc Balmer <mbalmer (at) NetBSD.org>.
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  * 3. The name of the Author may not be used to endorse or promote products
     16  *    derived from this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     28  * SUCH DAMAGE.
     29  */
     30 
     31 /*
     32  * Program to control Lua devices.
     33  */
     34 
     35 #include <stdbool.h>
     36 #include <sys/param.h>
     37 #include <sys/lua.h>
     38 #include <sys/ioctl.h>
     39 
     40 #include <err.h>
     41 #include <errno.h>
     42 #include <fcntl.h>
     43 #include <limits.h>
     44 #include <paths.h>
     45 #include <stdio.h>
     46 #include <stdlib.h>
     47 #include <string.h>
     48 #include <unistd.h>
     49 
     50 int devfd = -1;
     51 int quiet = 0;
     52 int docreate = 0;
     53 
     54 static void getinfo(void);
     55 static void create(char *, char *);
     56 static void destroy(char *);
     57 
     58 static void require(char *, char *);
     59 static void load(char *, char *);
     60 
     61 static void usage(void) __dead;
     62 
     63 #define _PATH_DEV_LUA	"/dev/lua"
     64 
     65 int
     66 main(int argc, char *argv[])
     67 {
     68 	int ch;
     69 
     70 	while ((ch = getopt(argc, argv, "cq")) != -1)
     71 		switch (ch) {
     72 		case 'c':
     73 			docreate = 1;
     74 			break;
     75 		case 'q':
     76 			quiet = 1;
     77 			break;
     78 		default:
     79 			usage();
     80 			/* NOTREACHED */
     81 		}
     82 	argc -= optind;
     83 	argv += optind;
     84 
     85 	if ((devfd = open(_PATH_DEV_LUA, O_RDWR)) == -1)
     86 		err(EXIT_FAILURE, "%s", _PATH_DEV_LUA);
     87 
     88 	if (argc == 0)
     89 		getinfo();
     90 	else if (!strcmp(argv[0], "create")) {
     91 		if (argc == 2)
     92 			create(argv[1], NULL);
     93 		else if (argc == 3)
     94 			create(argv[1], argv[2]);
     95 		else
     96 			usage();
     97 	} else if (!strcmp(argv[0], "destroy")) {
     98 		if (argc != 2)
     99 			usage();
    100 		destroy(argv[1]);
    101 	} else if (!strcmp(argv[0], "require")) {
    102 		if (argc != 3)
    103 			usage();
    104 		if (docreate)
    105 			create(argv[1], NULL);
    106 		require(argv[1], argv[2]);
    107 	} else if (!strcmp(argv[0], "load")) {
    108 		if (argc != 3)
    109 			usage();
    110 		if (docreate)
    111 			create(argv[1], NULL);
    112 		load(argv[1], argv[2]);
    113 	} else
    114 		usage();
    115 
    116 	return EXIT_SUCCESS;
    117 }
    118 
    119 static void
    120 getinfo(void)
    121 {
    122 	struct lua_info info;
    123 	int n;
    124 
    125 	info.states = NULL;
    126 	if (ioctl(devfd, LUAINFO, &info) == -1)
    127 		err(EXIT_FAILURE, "LUAINFO");
    128 
    129 	if (info.num_states > 0) {
    130 		info.states = calloc(info.num_states,
    131 		    sizeof(struct lua_state_info));
    132 		if (info.states == NULL)
    133 			err(EXIT_FAILURE, "calloc");
    134 		if (ioctl(devfd, LUAINFO, &info) == -1)
    135 			err(EXIT_FAILURE, "LUAINFO");
    136 	}
    137 	printf("%d active state%s:\n", info.num_states,
    138 	    info.num_states == 1 ? "" : "s");
    139 	if (info.num_states > 0)
    140 		printf("%-16s %-8s Description\n", "Name", "Creator");
    141 	for (n = 0; n < info.num_states; n++)
    142 		printf("%-16s %-8s %s\n", info.states[n].name,
    143 		    info.states[n].user == true ? "user" : "kernel",
    144 		    info.states[n].desc);
    145 }
    146 
    147 static void
    148 create(char *name, char *desc)
    149 {
    150 	struct lua_create cr;
    151 
    152 	strlcpy(cr.name, name, sizeof(cr.name));
    153 	if (desc != NULL)
    154 		strlcpy(cr.desc, desc, sizeof(cr.desc));
    155 	else
    156 		cr.desc[0] = '\0';
    157 
    158 	if (ioctl(devfd, LUACREATE, &cr) == -1)
    159 		err(EXIT_FAILURE, "LUACREATE");
    160 
    161 	if (quiet)
    162 		return;
    163 
    164 	printf("%s created\n", name);
    165 }
    166 
    167 static void
    168 destroy(char *name)
    169 {
    170 	struct lua_create cr;
    171 
    172 	strlcpy(cr.name, name, sizeof(cr.name));
    173 
    174 	if (ioctl(devfd, LUADESTROY, &cr) == -1)
    175 		err(EXIT_FAILURE, "LUADESTROY");
    176 
    177 	if (quiet)
    178 		return;
    179 
    180 	printf("%s destroyed\n", name);
    181 }
    182 
    183 static void
    184 require(char *name, char *module)
    185 {
    186 	struct lua_require r;
    187 
    188 	strlcpy(r.state, name, sizeof(r.state));
    189 	strlcpy(r.module, module, sizeof(r.module));
    190 
    191 	if (ioctl(devfd, LUAREQUIRE, &r) == -1)
    192 		err(EXIT_FAILURE, "LUAREQUIRE");
    193 
    194 	if (quiet)
    195 		return;
    196 
    197 	printf("%s required by %s\n", module, name);
    198 }
    199 
    200 static void
    201 load(char *name, char *path)
    202 {
    203 	struct lua_load l;
    204 
    205 	strlcpy(l.state, name, sizeof(l.state));
    206 	strlcpy(l.path, path, sizeof(l.path));
    207 
    208 	if (ioctl(devfd, LUALOAD, &l) == -1)
    209 		err(EXIT_FAILURE, "LUALOAD");
    210 
    211 	if (quiet)
    212 		return;
    213 
    214 	printf("%s loaded into %s\n", path, name);
    215 }
    216 
    217 static void
    218 usage(void)
    219 {
    220 	const char *p;
    221 
    222 	p = getprogname();
    223 	fprintf(stderr, "usage: %s [-cq]\n", p);
    224 	fprintf(stderr, "       %s [-cq] create name [desc]\n", p);
    225 	fprintf(stderr, "       %s [-cq] destroy name\n", p);
    226 	fprintf(stderr, "       %s [-cq] require name module\n", p);
    227 	fprintf(stderr, "       %s [-cq] load name path\n", p);
    228 
    229 	exit(EXIT_FAILURE);
    230 }
    231