コード例 #1
0
ファイル: hgd-admin.c プロジェクト: Eeketh/hgd
int
hgd_acmd_user_list_print(char **args)
{
	struct hgd_user_list	*list;
	int			 i, ret = HGD_FAIL;
	char			*permstr = NULL;

	if (db == NULL)
		db = hgd_open_db(db_path, 0);

	if (db == NULL)
		goto clean;

	if (hgd_user_list(&list) != HGD_OK)
		goto clean;

	for (i = 0; i < list->n_users; i++) {
		hgd_gen_perms_str(list->users[i]->perms, &permstr);
		printf("%-20s %s\n",
		    list->users[i]->name, permstr);
		free(permstr);
	}

	ret = HGD_OK;
clean:
	if (list != NULL) {
		hgd_free_user_list(list);
		free(list);
	}

	return (ret);
}
コード例 #2
0
ファイル: hgd-admin.c プロジェクト: Eeketh/hgd
int
hgd_acmd_user_del(char **args)
{
	if (db == NULL)
		db = hgd_open_db(db_path, 0);

	if (db == NULL)
		return (HGD_FAIL);

	if (hgd_user_del(args[0]) != HGD_OK)
		return (HGD_FAIL);

	return (HGD_OK);
}
コード例 #3
0
ファイル: hgd-admin.c プロジェクト: Eeketh/hgd
int
hgd_acmd_user_add_prompt(char **args)
{
	char			 pass[HGD_MAX_PASS_SZ];

	if (db == NULL)
		db = hgd_open_db(db_path, 0);

	if (db == NULL)
		return (HGD_FAIL);

	if (hgd_readpassphrase_confirmed(pass, NULL) != HGD_OK)
		return (HGD_FAIL);

	return (hgd_user_add(args[0], pass));
}
コード例 #4
0
ファイル: db.c プロジェクト: floort/hgd
/*
 * remove old db and create new one
 */
int
hgd_make_new_db(char *db_path)
{
	int			sql_res;
	sqlite3			*db;

	DPRINTF(HGD_D_INFO, "Creating new database: %s", db_path);

	if ((unlink(db_path) < 0) && (errno != ENOENT)) {
		DPRINTF(HGD_D_ERROR, "Could not unlink existing db: %s", SERROR);
		return (HGD_FAIL);
	}

	db = hgd_open_db(db_path, 1); /* and create */
	if (!db)
		return (HGD_FAIL);

	/* no-one else should do this at the same time */
	sql_res = sqlite3_exec(db, "BEGIN TRANSACTION", NULL, NULL, NULL);
	if (sql_res != SQLITE_OK) {
		DPRINTF(HGD_D_ERROR, "Can't initialise db: %s", DERROR);
		sqlite3_close(db);
		return (HGD_FAIL);
	}

	DPRINTF(HGD_D_DEBUG, "Making system table");
	sql_res = sqlite3_exec(db,
	    "CREATE TABLE system ("
	    "id INTEGER PRIMARY KEY,"
	    "db_schema_version INTEGER)",
	    NULL, NULL, NULL);

	if (sql_res != SQLITE_OK) {
		DPRINTF(HGD_D_ERROR, "Can't initialise db: %s", DERROR);
		sqlite3_close(db);
		return (HGD_FAIL);
	}

	/* the system table should only have one row with id 0 */
	sql_res = sqlite3_exec(db,
	    "INSERT into system VALUES(0, '" HGD_DB_SCHEMA_VERS "');",
	    NULL, NULL, NULL);

	if (sql_res != SQLITE_OK) {
		DPRINTF(HGD_D_ERROR, "Can't initialise db: %s", DERROR);
		sqlite3_close(db);
		return (HGD_FAIL);
	}

	DPRINTF(HGD_D_DEBUG, "Making playlist table");
	sql_res = sqlite3_exec(db,
	    "CREATE TABLE playlist ("
	    "id INTEGER PRIMARY KEY,"
	    "filename TEXT,"
	    "user TEXT,"
	    "playing INTEGER,"
	    "finished INTEGER,"
	    "tag_artist TEXT,"
	    "tag_title TEXT,"
	    "tag_album TEXT,"
	    "tag_genre TEXT,"
	    "tag_year INTEGER,"
	    "tag_channels INTEGER,"
	    "tag_samplerate INTEGER,"
	    "tag_duration INTEGER,"
	    "tag_bitrate INTEGER)",
	    NULL, NULL, NULL);

	if (sql_res != SQLITE_OK) {
		DPRINTF(HGD_D_ERROR, "Can't initialise db: %s", DERROR);
		sqlite3_close(db);
		return (HGD_FAIL);
	}

	DPRINTF(HGD_D_DEBUG, "making votes table");
	sql_res = sqlite3_exec(db,
	    "CREATE TABLE votes ("
	    "user TEXT PRIMARY KEY)",
	    NULL, NULL, NULL);

	if (sql_res != SQLITE_OK) {
		DPRINTF(HGD_D_ERROR, "Can't initialise db: %s",
		    DERROR);
		sqlite3_close(db);
		return (HGD_FAIL);
	}

	DPRINTF(HGD_D_DEBUG, "making user table");
	sql_res = sqlite3_exec(db,
	    "CREATE TABLE users ("
	    "username TEXT PRIMARY KEY, "
	    "hash TEXT, "	/* sha1 */
	    "salt TEXT, "
	    "perms INTEGER"
	    ");",
	    NULL, NULL, NULL);

	if (sql_res != SQLITE_OK) {
		DPRINTF(HGD_D_ERROR, "Can't initialise db: %s",
		    DERROR);
		sqlite3_close(db);
		return (HGD_FAIL);
	}

	sql_res = sqlite3_exec(db, "COMMIT", NULL, NULL, NULL);
	if (sql_res != SQLITE_OK) {
		DPRINTF(HGD_D_ERROR, "Can't initialise db: %s", DERROR);
		sqlite3_close(db);
		return (HGD_FAIL);
	}

	sqlite3_close(db);

	return (HGD_OK);
}
コード例 #5
0
ファイル: hgd-netd.c プロジェクト: tristan2468/hgd
int
main(int argc, char **argv)
{
	char			*xdg_config_home;
	char			*config_path[4] = {NULL, NULL, NULL, NULL};
	int			 num_config = 2, ch;

	/* as early as possible */
	HGD_INIT_SYSLOG_DAEMON();

	config_path[0] = NULL;
	xasprintf(&config_path[1], "%s",  HGD_GLOBAL_CFG_DIR HGD_SERV_CFG );

	xdg_config_home =  getenv("XDG_CONFIG_HOME");
	if (xdg_config_home == NULL) {
		xasprintf(&config_path[2], "%s%s", getenv("HOME"),
		    HGD_USR_CFG_DIR HGD_SERV_CFG );
	} else {
		xasprintf(&config_path[2], "%s%s",
		    xdg_config_home , "/hgd" HGD_SERV_CFG);
	}

	/* if killed, die nicely */
	hgd_register_sig_handlers();

	state_path = xstrdup(HGD_DFL_DIR);
	ssl_key_path = xstrdup(HGD_DFL_KEY_FILE);
	ssl_cert_path = xstrdup(HGD_DFL_CERT_FILE);

	DPRINTF(HGD_D_DEBUG, "Parsing options:1");
	while ((ch = getopt(argc, argv, "Bc:Dd:EefF:hk:n:p:s:S:vx:y:")) != -1) {
		switch (ch) {
		case 'c':
			if (num_config < 3) {
				num_config++;
				DPRINTF(HGD_D_DEBUG, "added config %d %s",
				    num_config, optarg);
				config_path[num_config] = optarg;
			} else {
				DPRINTF(HGD_D_WARN,
				    "Too many config files specified");
				hgd_exit_nicely();
			}
			break;
		case 'x':
			hgd_debug = atoi(optarg);
			if (hgd_debug > 3)
				hgd_debug = 3;
			DPRINTF(HGD_D_DEBUG, "set debug to %d", hgd_debug);
			break;
		default:
			break; /* next getopt will catch errors */
		}
	}


	RESET_GETOPT();

	/* cache HUP info */
	if (hgd_cache_exec_context(argv) != HGD_OK)
		hgd_exit_nicely();

	hgd_read_config(config_path + num_config);

	DPRINTF(HGD_D_DEBUG, "Parsing options:2");
	while ((ch = getopt(argc, argv, "Bc:Dd:EefF:hk:n:p:s:S:vx:y:")) != -1) {
		switch (ch) {
		case 'B':
			background = 0;
			DPRINTF(HGD_D_DEBUG, "Not \"backgrounding\" daemon.");
			break;
		case 'c':
			break; /* already handled */
		case 'D':
			DPRINTF(HGD_D_DEBUG, "No client DNS lookups");
			lookup_client_dns = 0;
			break;
		case 'd':
			free(state_path);
			state_path = xstrdup(optarg);
			DPRINTF(HGD_D_DEBUG, "Set hgd dir to '%s'", state_path);
			break;
		case 'e':
			crypto_pref = HGD_CRYPTO_PREF_ALWAYS;
			DPRINTF(HGD_D_DEBUG, "Server will insist on crypto");
			break;
		case 'E':
			crypto_pref = HGD_CRYPTO_PREF_NEVER;
			DPRINTF(HGD_D_WARN, "Encryption disabled manually");
			break;
		case 'f':
			single_client = 1;
			DPRINTF(HGD_D_DEBUG, "Single client debug mode on");
			break;
		case 'F':
			flood_limit = atoi(optarg);
			DPRINTF(HGD_D_DEBUG, "Set flood limit to %d",
			    flood_limit);
			break;
		case 'k':
			free(ssl_key_path);
			ssl_key_path = optarg;
			DPRINTF(HGD_D_DEBUG,
			    "set ssl private key path to '%s'", ssl_key_path);
			break;
		case 'n':
			req_votes = atoi(optarg);
			DPRINTF(HGD_D_DEBUG,
			    "Set required-votes to %d", req_votes);
			break;
		case 'p':
			port = atoi(optarg);
			DPRINTF(HGD_D_DEBUG, "Set port to %d", port);
			break;
		case 's':
			/* XXX overflow? */
			max_upload_size = atoi(optarg) * HGD_MB;
			DPRINTF(HGD_D_DEBUG, "Set max upload size to %d",
			    (int) max_upload_size);
			break;
		case 'S':
			free(ssl_cert_path);
			ssl_cert_path = optarg;
			DPRINTF(HGD_D_DEBUG,
			    "set ssl cert path to '%s'", ssl_cert_path);
			break;
		case 'v':
			hgd_print_version();
			exit_ok = 1;
			hgd_exit_nicely();
			break;
		case 'x':
			DPRINTF(HGD_D_DEBUG, "set debug to %d", atoi(optarg));
			hgd_debug = atoi(optarg);
			if (hgd_debug > 3)
				hgd_debug = 3;
			break; /* already set but over-rideable */
		case 'y':
			free(vote_sound);
			vote_sound = optarg;
			DPRINTF(HGD_D_DEBUG,
			    "set voteoff sound %s", vote_sound);
			break;
		case 'h':
		default:
			hgd_usage();
			exit_ok = 1;
			hgd_exit_nicely();
			break;
		};
	}

	argc -= optind;
	argv += optind;

	/* set up paths */
	xasprintf(&db_path, "%s/%s", state_path, HGD_DB_NAME);
	xasprintf(&filestore_path, "%s/%s", state_path, HGD_FILESTORE_NAME);

	umask(~S_IRWXU);
	hgd_mk_state_dir();

	db = hgd_open_db(db_path, 0);
	if (db == NULL)
		hgd_exit_nicely();

	sqlite3_close(db); /* re-opened later */
	db = NULL;

	/* unless the user actively disables SSL, we try to be capable */
	if (crypto_pref != HGD_CRYPTO_PREF_NEVER) {
		if (hgd_setup_ssl_ctx(&method, &ctx, 1,
		    ssl_cert_path, ssl_key_path) == 0) {
			DPRINTF(HGD_D_INFO, "Server is SSL capable");
			ssl_capable = 1;
		} else {
			DPRINTF(HGD_D_WARN, "Server is SSL incapable");
		}
	} else {
		DPRINTF(HGD_D_INFO, "Server was forced SSL incapable");
	}

	/* if -e, but something screwed up in the above, bail */
	if ((crypto_pref == HGD_CRYPTO_PREF_ALWAYS) && (ssl_capable != 1)) {
		DPRINTF(HGD_D_ERROR,
		    "Crypto was forced on, but server is incapable");
		hgd_exit_nicely();
	}

	/* alright, everything looks good, lets be a daemon and background */
	if (background) hgd_daemonise();

	hgd_listen_loop();

	exit_ok = 1;
	hgd_exit_nicely();

	return (EXIT_SUCCESS); /* NOREACH */
}
コード例 #6
0
ファイル: hgd-netd.c プロジェクト: tristan2468/hgd
/* main loop that deals with network requests */
void
hgd_listen_loop(void)
{
	struct sockaddr_in	addr, cli_addr;
	int			cli_fd, child_pid = 0;
	socklen_t		cli_addr_len;
	int			sockopt = 1, data_ready;
	struct pollfd		pfd;

start:

	DPRINTF(HGD_D_DEBUG, "Setting up socket");

	if ((svr_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
		DPRINTF(HGD_D_ERROR, "socket(): %s", SERROR);
		hgd_exit_nicely();
	}

	/* allow socket to be re-used right away after we exit */
	if (setsockopt(svr_fd, SOL_SOCKET, SO_REUSEADDR,
		     &sockopt, sizeof(sockopt)) < 0) {
		DPRINTF(HGD_D_WARN, "Can't set SO_REUSEADDR");
	}

	/* configure socket */
	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = htonl(INADDR_ANY);
	addr.sin_port = htons(port);

	if (bind(svr_fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
		DPRINTF(HGD_D_ERROR, "Bind to port %d: %s", port, SERROR);
		hgd_exit_nicely();
	}

	if (listen(svr_fd, sock_backlog) < 0) {
		DPRINTF(HGD_D_ERROR, "Listen: %s", SERROR);
		hgd_exit_nicely();
	}

	DPRINTF(HGD_D_INFO, "Socket ready and listening on port %d", port);

	/* setup signal handler */
	signal(SIGCHLD, hgd_sigchld);

	while (1) {
		DPRINTF(HGD_D_INFO, "waiting for client connection");

		/* spin until something is ready */
		pfd.fd = svr_fd;
		pfd.events = POLLIN;
		data_ready = 0;

		while (!dying && !restarting && !data_ready) {
			data_ready = poll(&pfd, 1, INFTIM);
			if (data_ready == -1) {
				if (errno != EINTR) {
					DPRINTF(HGD_D_ERROR, "Poll error");
					dying = 1;
				}
				data_ready = 0;
			}
		}

		if (dying || restarting) {
			if (restarting)
				exit_ok = 1;
			hgd_exit_nicely();
		}

		cli_addr_len = sizeof(cli_addr);
		cli_fd = accept(svr_fd, (struct sockaddr *) &cli_addr,
		    &cli_addr_len);

		if (cli_fd < 0) {
			DPRINTF(HGD_D_WARN, "Server failed to accept");
			close(svr_fd);
			/*
			 * accept will fail next time aswell :\
			 * it seems the fix is to re-initialise the socket
			 */
			goto start;
		}

		if (setsockopt(cli_fd, SOL_SOCKET, SO_REUSEADDR,
			    &sockopt, sizeof(sockopt)) < 0) {
			DPRINTF(HGD_D_WARN, "Can't set SO_REUSEADDR");
		}

		/* ok, let's deal with that request then */
		if (!single_client)
			child_pid = fork();

		if (!child_pid) {

			/* turn off HUP handler */
			//signal(SIGHUP, SIG_DFL);

			db = hgd_open_db(db_path, 0);
			if (db == NULL)
				hgd_exit_nicely();

			hgd_service_client(cli_fd, &cli_addr);
			DPRINTF(HGD_D_DEBUG, "client service complete");

			/* and we are done with this client */
			if (shutdown(cli_fd, SHUT_RDWR) == -1)
				DPRINTF(HGD_D_WARN, "Can't shutdown socket");
			close(cli_fd);

			close(svr_fd);
			svr_fd = -1; /* prevent shutdown of svr_fd */
			exit_ok = 1;
			hgd_exit_nicely();
		} /* child block ends */

		close (cli_fd);
		DPRINTF(HGD_D_DEBUG, "client servicer PID = '%d'", child_pid);
		/* otherwise, back round for the next client */
	}
	/* NOREACH */
}
コード例 #7
0
ファイル: hgd-playd.c プロジェクト: zandeez/hgd
int
main(int argc, char **argv)
{
	char			*config_path[4] = {NULL, NULL, NULL, NULL};
	int			 num_config = 2, ch;
	FILE			*hgd_pid;

	/* early as possible */
	hgd_register_sig_handlers();
	HGD_INIT_SYSLOG_DAEMON();

#ifdef HAVE_LIBCONFIG
	config_path[0] = NULL;
	xasprintf(&config_path[1], "%s", HGD_GLOBAL_CFG_DIR HGD_SERV_CFG);
	config_path[2] = hgd_get_XDG_userprefs_location(playd);
#endif

	state_path = xstrdup(HGD_DFL_DIR);

	DPRINTF(HGD_D_DEBUG, "Parsing options:1");
	while ((ch = getopt(argc, argv, "Bc:Cd:hpP:qvx:")) != -1) {
		switch (ch) {
		case 'c':
			if (num_config < 3) {
				num_config++;
				DPRINTF(HGD_D_DEBUG, "added config %d %s",
				    num_config, optarg);
				config_path[num_config] = optarg;
			} else {
				DPRINTF(HGD_D_WARN,
				    "Too many config files specified");
				hgd_exit_nicely();
			}
			break;
		case 'x':
			hgd_debug = atoi(optarg);
			if (hgd_debug > 3)
				hgd_debug = 3;
			DPRINTF(HGD_D_DEBUG,
			    "set debug level to %d", hgd_debug);
			break;
		default:
			break; /* catch badness in next getopt */
		};
	}

	hgd_read_config(config_path + num_config);

	while(num_config > 0) {
		if (config_path[num_config] != NULL) {
			free (config_path[num_config]);
			config_path[num_config] = NULL;
		}
		num_config--;
	}

	RESET_GETOPT();

	if (hgd_cache_exec_context(argv) != HGD_OK)
		hgd_exit_nicely();

	DPRINTF(HGD_D_DEBUG, "Parsing options");
	while ((ch = getopt(argc, argv, "Bc:Cd:hpP:qvx:")) != -1) {
		switch (ch) {
		case 'B':
			background = 0;
			DPRINTF(HGD_D_DEBUG, "Not \"backgrounding\" daemon.");
			break;
		case 'c':
			break; /* already handled */
		case 'C':
			clear_playlist_on_start = 1;
			DPRINTF(HGD_D_DEBUG, "will clear playlist '%s'",
			    state_path);
			break;
		case 'd':
			free(state_path);
			state_path = xstrdup(optarg);
			DPRINTF(HGD_D_DEBUG, "set hgd dir to '%s'", state_path);
			break;
		case 'p':
			DPRINTF(HGD_D_DEBUG, "No purging from fs");
			purge_finished_fs = 0;
			break;
#ifdef HAVE_PYTHON
		case 'P':
			DPRINTF(HGD_D_DEBUG, "Setting python plugin dir");
			if (hgd_py_plugin_dir != NULL)
				free(hgd_py_plugin_dir);
			hgd_py_plugin_dir = xstrdup(optarg);
			break;
#endif
		case 'q':
			DPRINTF(HGD_D_DEBUG, "No purging from db");
			purge_finished_db = 0;
			break;
		case 'v':
			hgd_print_version();
			exit_ok = 1;
			hgd_exit_nicely();
			break;
		case 'x':
			DPRINTF(HGD_D_DEBUG, "set debug to %d", atoi(optarg));
			hgd_debug = atoi(optarg);
			if (hgd_debug > 3)
				hgd_debug = 3;
			break; /* already set but over-rideable */
		case 'h':
		default:
			hgd_usage();
			exit_ok = 1;
			hgd_exit_nicely();
			break;
		};
	}

	argc -= optind;
	argv += optind;

	xasprintf(&db_path, "%s/%s", state_path, HGD_DB_NAME);
	xasprintf(&filestore_path, "%s/%s", state_path, HGD_FILESTORE_NAME);
	xasprintf(&mplayer_fifo_path, "%s/%s",
	    state_path, HGD_MPLAYER_PIPE_NAME);

	umask(~S_IRWXU);
	hgd_mk_state_dir();

	if (hgd_check_mplayer_present() != HGD_OK)
		hgd_exit_nicely();

	db = hgd_open_db(db_path, 0);
	if (db == NULL)
		hgd_exit_nicely();

	if (hgd_init_playstate() != HGD_OK)
		hgd_exit_nicely();

	if (clear_playlist_on_start) {
		if (hgd_clear_playlist() != HGD_OK)
			hgd_exit_nicely();
	}

	if (hgd_open_pid_file(&hgd_pid) != HGD_OK) {
		DPRINTF(HGD_D_ERROR, "Can't open PID file");
		return (HGD_FAIL);
	}

	/* start */
	if (background)
		hgd_daemonise();

	/* do the Python dance */
#ifdef HAVE_PYTHON
	if (hgd_embed_py(1) != HGD_OK) {
		DPRINTF(HGD_D_ERROR, "Failed to initialise Python");
		hgd_exit_nicely();
	}
#endif

	if (hgd_write_pid_file(&hgd_pid) != HGD_OK) {
		DPRINTF(HGD_D_ERROR, "Can't write PID away");
		return (HGD_FAIL);
	}

	if (hgd_play_loop() == HGD_OK)
		exit_ok = 1;

	if (hgd_unlink_pid_file() != HGD_OK)
		DPRINTF(HGD_D_ERROR, "Could not unlink pidfile");

	hgd_exit_nicely();
	_exit (EXIT_SUCCESS); /* NOREACH */
}