⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gserv.c

📁 openGFS , a kind of file system.
💻 C
字号:
/* * *    Copyright 2000-2001 Sistina Software, Inc. *    Portions Copyright 2001 The OpenGFS Project * *    This is free software released under the GNU General Public License. *    There is no warranty for this software.  See the file COPYING for *    details. * *    See the file AUTHORS for a list of contributors. * *//* * This is a user level interface for setting up and configuring the * kgnbd kernel server.  Soon it will also be able to interface the  * gnbdd user level server. *//* * AUDIT: <Alan> *	- Fixed multiple local possible buffer overruns, nothing serious *	- Fixed malloc checks */#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <getopt.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <errno.h>#include <limits.h>#include <ctype.h>int kernel_server;int fd;int read_fd;int message_flag = 1;#define printm(fmt, args...)\{\	if(message_flag != 0) \		fprintf(stderr, "gserv: " fmt, ##args); \}size_t gserv_read(void *buf, size_t count){	if (kernel_server)		return read(fd, buf, count);	return read(read_fd, buf, count);}size_t gserv_write(const void *buf, size_t count){	return write(fd, buf, count);}int get_fd(int flags){	fd = open("/proc/kgnbd", flags);	if (fd < 0 && errno != ENOENT) {		fprintf(stderr, "could not open /proc/kgnbd: %s\n",			strerror(errno));		return -1;	}	if (fd >= 0) {		kernel_server = 1;		return 0;	}	if ((flags & O_ACCMODE) == O_WRONLY) {		fd = open("/dev/gnbd_rdpipe", flags);		if (fd < 0) {			fprintf(stderr,				"couldn't connect to gnbd_rdpipe: %s\n",				strerror(errno));			return -1;		}	}	if ((flags & O_ACCMODE) == O_RDONLY) {		read_fd = open("/dev/gnbd_wrpipe", flags);		if (read_fd < 0) {			fprintf(stderr,				"couldn't connect to gnbd_wrpipe: %s\n",				strerror(errno));			return -1;		}	}	kernel_server = 0;	return 0;}int servcreate(char *filename, char *pathname){	int len = strlen(filename) + strlen(pathname) + 9;	char *buf = (char *) malloc(len * sizeof(char));	if(buf == NULL)		exit(1);	snprintf(buf, len, "create/%s/%s", filename, pathname);	if (write(fd, buf, len) != len) {		fprintf(stderr, "create request failed: %s\n",			strerror(errno));		free(buf);		return 1;	}	free(buf);	printm("created GNBD %s serving file %s\n", filename, pathname);	return 0;}int servremove(char *filename){	int len = strlen(filename) + 8;	char *buf = (char *) malloc(len * sizeof(char));	if(!buf)		exit(1);	snprintf(buf, len, "remove/%s", filename);	if (gserv_write(buf, len) != len) {		fprintf(stderr, "remove request failed: %s\n",			strerror(errno));		free(buf);		return 1;	}	free(buf);	printm("removed GNBD %s\n", filename);	return 0;}int removeall(void){	int bytes, total = 0;	char *serv, *bufptr;	char buf[4096];	while ((bytes = gserv_read(buf + total, 4096 - total)) != 0) {		if (bytes < 0 && errno != -EINTR) {			fprintf(stderr, "remove request failed: %s\n",				strerror(errno));			return 1;		}		total += bytes;	}	if (total < 4096)		buf[total] = 0;	else		buf[total] = 0;	bufptr = buf;	while ((serv = strchr(bufptr, '/')) != NULL) {		serv++;		bufptr = strchr(serv, '/');		*bufptr++ = 0;		bufptr = strstr(bufptr, "blocksize");		servremove(serv);		if (bufptr == NULL) {			fprintf(stderr,				"incorrectly formatted serverlist\n");			return 1;		}	}	return 0;}int portstop(void){	char *buf = "portstop";	if (gserv_write(buf, 9) != 9) {		fprintf(stderr, "stop kgnbd_portd request failed: %s\n",			strerror(errno));		return 1;	}	printm("kgnbd_portd stopped\n");	return 0;}int portstart(unsigned int port){	int len;	char buf[16];	if (port != 0)		snprintf(buf, 16, "portstart/%u", port);	else		snprintf(buf, 16, "portstart");	len = strlen(buf);	if (gserv_write(buf, len + 1) != len + 1) {		fprintf(stderr, "start kgnbd_portd request failed: %s\n",			strerror(errno));		return 1;	}	printm("kgnbd_portd started\n");	return 0;}int list(void){	int n;	int bytes = 0;	char *serv;	char buf[4096];	char *bufptr = buf;	while ((n = gserv_read(buf + bytes, 4096 - bytes)) != 0) {		if (n < 0 && errno != -EINTR) {			fprintf(stderr, "list request failed: %s\n",				strerror(errno));			return 1;		}		bytes += n;	}	if (bytes < 4096)		buf[bytes] = 0;	else		buf[4095] = 0;	bufptr = strchr(buf, '\n');	*bufptr = 0;	bufptr = bufptr + 2;	printf("%s\n\n", buf);	if (strncmp(bufptr, "no", 2) == 0) {		serv = strchr(bufptr, '\n');		*serv = 0;		printf("%s\n", bufptr);		return 0;	}	while ((serv = strstr(bufptr, "Server")) != NULL) {		bufptr = strchr(serv, '/');		*bufptr++ = ' ';		bufptr = strchr(bufptr, '/');		*bufptr++ = ' ';		bufptr = strstr(serv, "\n       pid");		*bufptr++ = 0;		printf("%s\n\n", serv);	}	return 0;}int usage(void){	printf("Usage:\n\n");	printf("gserv [-q] <GNBD> <device or file>\n");	printf	    ("    Create and export new GNBD from named device or file.\n\n");	printf("gserv [-q] -r <GNBD>\n");	printf("    Remove (un-export) named GNBD.\n\n");	printf("gserv -l\n");	printf("    List exported GNBD's and kgnbd_portd server.\n\n");	printf("gserv [-q] -p [<port>]\n");	printf("    Start the kgnbd_portd server (default 14243).\n\n");	printf("gserv [-q] -s\n");	printf("    Stop the current kgnbd_portd server.\n\n");	printf("gserv -h\n");	printf("    Print help.\n\n");	printf("-q toggles gserv to quiet mode, so it does not print on "	       "success\n\n");#if 0	printf("Create an new kgnbd server for a file or block device\n"	       "   gserv <server name> <file or device>\n");	printf("Remove a kgnbd server\n" "   gserv -r <server name>\n");	printf("List the kgnbd and kgnbd_portd servers currently running\n"	       "   gserv -l\n");	printf	    ("Start up the kgnbd_portd server (if no port is specified, the default is 14243)\n"	     "   gserv -p [<server port>]\n");	printf("Stop the current kgnbd_portd server\n" "   gserv -s\n");	printf("Print this message\n" "   gserv -h\n\n");#endif	return 1;}int main(int argc, char **argv){	int c;	int i;	char *tailptr;	unsigned long int port = 0;	if (argc < 2) {		return usage();	}loop:	c = getopt(argc, argv, "qlrpsh");	switch (c) {	case 'q':		message_flag = 0;		goto loop;	case -1:		if (argc - optind != 2)			return usage();		if (get_fd(O_WRONLY) < 0)			return 1;		return servcreate(argv[optind], argv[optind + 1]);	case 'l':		if (optind != argc) {			fprintf(stderr,				"unnecessary argument after list request: %s\n\n",				argv[optind]);			return usage();		}		if (get_fd(O_RDONLY) < 0)			return 1;		return list();	case 'r':		if (get_fd(O_RDWR) < 0)			return 1;		if (optind == argc)			return removeall();		for (i = optind; i < argc; i++)			if (servremove(argv[i]) != 0) {				fprintf(stderr, "couldn't remove %s: %s\n",					argv[i], strerror(errno));				return 1;			}		return 0;	case 'p':		if (argc != optind) {			fprintf(stderr,				"unnecessary argument to kgnbd_portd request\n\n");			return usage();		}		/*		   if (argc - optind > 1){		   fprintf(stderr, "unnecessary argument after port number\n\n");		   return usage();		   }		 */		if (argc == optind)			port = 0;		else {			port = strtoul(argv[optind], &tailptr, 0);			if (port <= 0 || *tailptr != 0 || port > 65536) {				fprintf(stderr,					"invalid port number: %s\n\n",					argv[optind]);				return usage();			}		}		if (get_fd(O_WRONLY) < 0)			return 1;		return portstart((unsigned int) port);	case 's':		if (optind != argc) {			fprintf(stderr,				"unnecessary argument to stop kgnbd_portd "				"request\n\n");			return usage();		}		if (get_fd(O_WRONLY) < 0)			return 1;		return portstop();	case '?':		if (isprint(optopt))			fprintf(stderr, "Unknown option: -%c\n\n", optopt);		else			fprintf(stderr, "Unknown option\n\n");		return usage();	case 'h':	default:		return usage();	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -