mirror of
				https://github.com/SuperBFG7/ympd
				synced 2025-10-30 21:33:00 +00:00 
			
		
		
		
	Replaced websocket through ajax requests for requests.
Now the websocket pushes only the states of mpd. Merged outputstate in state notify
This commit is contained in:
		| @@ -2,8 +2,8 @@ cmake_minimum_required(VERSION 2.6) | ||||
|  | ||||
| project (mympd C) | ||||
| set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake/") | ||||
| set(CPACK_PACKAGE_VERSION_MAJOR "2") | ||||
| set(CPACK_PACKAGE_VERSION_MINOR "3") | ||||
| set(CPACK_PACKAGE_VERSION_MAJOR "3") | ||||
| set(CPACK_PACKAGE_VERSION_MINOR "0") | ||||
| set(CPACK_PACKAGE_VERSION_PATCH "0") | ||||
| if(CMAKE_BUILD_TYPE MATCHES RELEASE) | ||||
|     set(ASSETS_PATH "${CMAKE_INSTALL_PREFIX}/share/${PROJECT_NAME}/htdocs") | ||||
| @@ -23,8 +23,8 @@ include_directories(${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR}	${LIBMPDCLIENT_I | ||||
|  | ||||
| include(CheckCSourceCompiles) | ||||
|  | ||||
| set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99 -Wall -Wextra -pedantic") | ||||
| #set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99 -Wall -Wextra -pedantic -D_FORTIFY_SOURCE=2 -fstack-protector -fsanitize=address -fno-omit-frame-pointer -fsanitize=undefined -fsanitize=shift -fsanitize=integer-divide-by-zero -fsanitize=unreachable -fsanitize=vla-bound -fsanitize=null -fsanitize=return -fsanitize=signed-integer-overflow -fsanitize=bounds -fsanitize=bounds-strict -fsanitize=alignment -fsanitize=object-size -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow -fsanitize=nonnull-attribute -fsanitize=returns-nonnull-attribute -fsanitize=bool -fsanitize=enum -fsanitize=vptr -static-libasan") | ||||
| #set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99 -Wall -Wextra -pedantic") | ||||
| set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99 -Wall -Wextra -pedantic -D_FORTIFY_SOURCE=2 -fstack-protector -fsanitize=address -fno-omit-frame-pointer -fsanitize=undefined -fsanitize=shift -fsanitize=integer-divide-by-zero -fsanitize=unreachable -fsanitize=vla-bound -fsanitize=null -fsanitize=return -fsanitize=signed-integer-overflow -fsanitize=bounds -fsanitize=bounds-strict -fsanitize=alignment -fsanitize=object-size -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow -fsanitize=nonnull-attribute -fsanitize=returns-nonnull-attribute -fsanitize=bool -fsanitize=enum -fsanitize=vptr -static-libasan") | ||||
| set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -ggdb") | ||||
| if(WITH_IPV6) | ||||
|     set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS NS_ENABLE_IPV6) | ||||
|   | ||||
| @@ -45,11 +45,8 @@ Run flags | ||||
| ``` | ||||
| Usage: ./mympd [OPTION]... | ||||
|  | ||||
|  -D, --digest <htdigest>       path to htdigest file for authorization | ||||
|                                (realm mympd) [no authorization] | ||||
|  -h, --host <host>             connect to mpd at host [localhost] | ||||
|  -p, --port <port>             connect to mpd at port [6600] | ||||
|  -l, --localport <port>	       skip authorization for local port | ||||
|  -w, --webport [ip:]<port>     listen interface/port for webserver [8080] | ||||
|  -s, --streamport <port>       connect to mpd http stream at port [8000] | ||||
|  -u, --user <username>         drop priviliges to user after socket bind | ||||
|   | ||||
							
								
								
									
										827
									
								
								htdocs/js/mpd.js
									
									
									
									
									
								
							
							
						
						
									
										827
									
								
								htdocs/js/mpd.js
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										6
									
								
								mympd.1
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								mympd.1
									
									
									
									
									
								
							| @@ -18,12 +18,6 @@ connect to mpd at host, defaults to localhost | ||||
| \fB\-p\fR, \fB\-\-port PORT\fR | ||||
| connect to mpd at port, defaults to 6600 | ||||
| .TP | ||||
| \fB\-D\fR, \fB\-\-digest HTDIGEST\fR	 | ||||
| path to htdigest file for authorization | ||||
| .TP | ||||
| \fB\-l\fR, \fB\-\-localport PORT\fR | ||||
| skip authorization for local port | ||||
| .TP | ||||
| \fB\-w\fR, \fB\-\-webport PORT\fR | ||||
| specifies the port for the webserver to listen to, defaults to 8080 | ||||
| .TP | ||||
|   | ||||
							
								
								
									
										149
									
								
								src/mpd_client.c
									
									
									
									
									
								
							
							
						
						
									
										149
									
								
								src/mpd_client.c
									
									
									
									
									
								
							| @@ -146,9 +146,8 @@ void callback_mpd(struct mg_connection *nc, const struct mg_str msg) | ||||
|             if(sscanf(msg.p, "MPD_API_SET_MIXRAMPDELAY,%f", &float_buf)) | ||||
|                 mpd_run_mixrampdelay(mpd.conn, float_buf); | ||||
|             break;             | ||||
|         case MPD_API_GET_OUTPUTS: | ||||
|             mpd.buf_size = mpd_put_outputs(mpd.buf, 1); | ||||
|             mpd_notify_callback(nc, NULL); | ||||
|         case MPD_API_GET_OUTPUTNAMES: | ||||
|             n = mpd_put_outputnames(mpd.buf); | ||||
|             break; | ||||
|         case MPD_API_TOGGLE_OUTPUT: | ||||
|             if (sscanf(msg.p, "MPD_API_TOGGLE_OUTPUT,%u,%u", &uint_buf, &uint_buf_2)) { | ||||
| @@ -245,9 +244,9 @@ out_artistalbumtitle: | ||||
| out_playlists: | ||||
|             free(p_charbuf);         | ||||
|             break; | ||||
|         case MPD_API_GET_BROWSE: | ||||
|         case MPD_API_GET_FILESYSTEM: | ||||
|             p_charbuf = strdup(msg.p); | ||||
|             if(strcmp(strtok(p_charbuf, ","), "MPD_API_GET_BROWSE")) | ||||
|             if(strcmp(strtok(p_charbuf, ","), "MPD_API_GET_FILESYSTEM")) | ||||
|                 goto out_browse; | ||||
|  | ||||
|             uint_buf = strtoul(strtok(NULL, ","), NULL, 10); | ||||
| @@ -478,10 +477,19 @@ out_set_replaygain: | ||||
|     } | ||||
|  | ||||
|     if(n > 0) { | ||||
|         #ifdef DEBUG | ||||
|         fprintf(stdout,"Send response:\n %s\n",mpd.buf); | ||||
|         #endif | ||||
|         mg_send_websocket_frame(nc, WEBSOCKET_OP_TEXT, mpd.buf, n); | ||||
|          | ||||
|         if(is_websocket(nc)) { | ||||
|             #ifdef DEBUG | ||||
|             fprintf(stdout,"Send response over websocket:\n %s\n",mpd.buf); | ||||
|             #endif | ||||
|             mg_send_websocket_frame(nc, WEBSOCKET_OP_TEXT, mpd.buf, n); | ||||
|         } | ||||
|         else { | ||||
|             #ifdef DEBUG | ||||
|             fprintf(stdout,"Send http response:\n %s\n",mpd.buf); | ||||
|             #endif | ||||
|             mg_send_http_chunk(nc, mpd.buf, n);         | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -590,12 +598,6 @@ void mpd_poll(struct mg_mgr *s) | ||||
|             fprintf(stderr, "MPD connected.\n"); | ||||
|             mpd_connection_set_timeout(mpd.conn, 10000); | ||||
|             mpd.conn_state = MPD_CONNECTED; | ||||
|             /* write outputs */ | ||||
|             mpd.buf_size = mpd_put_outputs(mpd.buf, 1); | ||||
|             for (struct mg_connection *c = mg_next(s, NULL); c != NULL; c = mg_next(s, c)) | ||||
|             { | ||||
|                 mpd_notify_callback(c, NULL); | ||||
|             } | ||||
|             break; | ||||
|  | ||||
|         case MPD_FAILURE: | ||||
| @@ -615,11 +617,6 @@ void mpd_poll(struct mg_mgr *s) | ||||
|             { | ||||
|                 mpd_notify_callback(c, NULL); | ||||
|             } | ||||
|             mpd.buf_size = mpd_put_outputs(mpd.buf, 0); | ||||
|             for (struct mg_connection *c = mg_next(s, NULL); c != NULL; c = mg_next(s, c)) | ||||
|             { | ||||
|                 mpd_notify_callback(c, NULL); | ||||
|             } | ||||
|             break; | ||||
|     } | ||||
| } | ||||
| @@ -701,7 +698,9 @@ int mpd_put_state(char *buffer, int *current_song_id, int *next_song_id,  unsign | ||||
| { | ||||
|     struct mpd_status *status; | ||||
|     const struct mpd_audio_format *audioformat; | ||||
|     int len; | ||||
|     struct mpd_output *out; | ||||
|     char *cur = buffer; | ||||
|     const char *end = buffer + MAX_SIZE; | ||||
|  | ||||
|     status = mpd_run_status(mpd.conn); | ||||
|     if (!status) { | ||||
| @@ -713,35 +712,59 @@ int mpd_put_state(char *buffer, int *current_song_id, int *next_song_id,  unsign | ||||
|      audioformat = mpd_status_get_audio_format(status); | ||||
|     } | ||||
|  | ||||
|     len = snprintf(buffer, MAX_SIZE, | ||||
|         "{\"type\":\"state\", \"data\":{" | ||||
|         "\"state\":%d, \"volume\":%d, \"songpos\": %d, \"elapsedTime\": %d, " | ||||
|         "\"totalTime\":%d, \"currentsongid\": %d, \"kbitrate\": %d, " | ||||
|         "\"audioformat\": { \"sample_rate\": %d, \"bits\": %d, \"channels\": %d}, " | ||||
|         "\"queue_length\": %d, \"nextsongpos\": %d, \"nextsongid\": %d, " | ||||
|         "\"queue_version\": %d" | ||||
|         "}}",  | ||||
|         mpd_status_get_state(status), | ||||
|         mpd_status_get_volume(status),  | ||||
|         mpd_status_get_song_pos(status), | ||||
|         mpd_status_get_elapsed_time(status), | ||||
|         mpd_status_get_total_time(status), | ||||
|         mpd_status_get_song_id(status), | ||||
|         mpd_status_get_kbit_rate(status), | ||||
|         audioformat ? audioformat->sample_rate : 0,  | ||||
|         audioformat ? audioformat->bits : 0,  | ||||
|         audioformat ? audioformat->channels : 0, | ||||
|         mpd_status_get_queue_length(status), | ||||
|         mpd_status_get_next_song_pos(status), | ||||
|         mpd_status_get_next_song_id(status), | ||||
|         mpd_status_get_queue_version(status) | ||||
|     ); | ||||
|     cur += json_emit_raw_str(cur, end - cur, "{\"type\": \"state\", \"data\":{\"state\":"); | ||||
|     cur += json_emit_int(cur, end - cur, mpd_status_get_state(status)); | ||||
|     cur += json_emit_raw_str(cur, end - cur, ",\"volume\":"); | ||||
|     cur += json_emit_int(cur, end - cur, mpd_status_get_volume(status));     | ||||
|     cur += json_emit_raw_str(cur, end - cur, ",\"songpos\":"); | ||||
|     cur += json_emit_int(cur, end - cur, mpd_status_get_song_pos(status)); | ||||
|     cur += json_emit_raw_str(cur, end - cur, ",\"elapsedTime\":"); | ||||
|     cur += json_emit_int(cur, end - cur, mpd_status_get_elapsed_time(status)); | ||||
|     cur += json_emit_raw_str(cur, end - cur, ",\"totalTime\":"); | ||||
|     cur += json_emit_int(cur, end - cur, mpd_status_get_total_time(status)); | ||||
|     cur += json_emit_raw_str(cur, end - cur, ",\"currentsongid\":"); | ||||
|     cur += json_emit_int(cur, end - cur, mpd_status_get_song_id(status)); | ||||
|     cur += json_emit_raw_str(cur, end - cur, ",\"kbitrate\":"); | ||||
|     cur += json_emit_int(cur, end - cur, mpd_status_get_kbit_rate(status)); | ||||
|     cur += json_emit_raw_str(cur, end - cur, ",\"audioformat\": {"); | ||||
|     cur += json_emit_raw_str(cur, end - cur, "\"sample_rate\":"); | ||||
|     cur += json_emit_int(cur, end - cur, audioformat ? audioformat->sample_rate : 0); | ||||
|     cur += json_emit_raw_str(cur, end - cur, ",\"bits\":"); | ||||
|     cur += json_emit_int(cur, end - cur, audioformat ? audioformat->bits : 0); | ||||
|     cur += json_emit_raw_str(cur, end - cur, ",\"channels\":"); | ||||
|     cur += json_emit_int(cur, end - cur, audioformat ? audioformat->channels : 0); | ||||
|     cur += json_emit_raw_str(cur, end - cur, "},\"queue_length\":"); | ||||
|     cur += json_emit_int(cur, end - cur, mpd_status_get_queue_length(status)); | ||||
|     cur += json_emit_raw_str(cur, end - cur, ",\"nextsongpos\":"); | ||||
|     cur += json_emit_int(cur, end - cur, mpd_status_get_next_song_pos(status)); | ||||
|     cur += json_emit_raw_str(cur, end - cur, ",\"nextsongid\":"); | ||||
|     cur += json_emit_int(cur, end - cur, mpd_status_get_next_song_id(status)); | ||||
|     cur += json_emit_raw_str(cur, end - cur, ",\"queue_version\":"); | ||||
|     cur += json_emit_int(cur, end - cur, mpd_status_get_queue_version(status)); | ||||
|     cur += json_emit_raw_str(cur, end - cur, ",\"outputs\": {"); | ||||
|  | ||||
|     mpd_send_outputs(mpd.conn); | ||||
|     while ((out = mpd_recv_output(mpd.conn)) != NULL) { | ||||
|         cur += json_emit_raw_str(cur, end - cur, "\""); | ||||
|         cur += json_emit_int(cur, end - cur, mpd_output_get_id(out)); | ||||
|         cur += json_emit_raw_str(cur, end - cur, "\":"); | ||||
|         cur += json_emit_int(cur, end - cur, mpd_output_get_enabled(out)); | ||||
|         cur += json_emit_raw_str(cur, end - cur, ","); | ||||
|         mpd_output_free(out); | ||||
|     } | ||||
|     if (!mpd_response_finish(mpd.conn)) { | ||||
|         fprintf(stderr, "MPD outputs: %s\n", mpd_connection_get_error_message(mpd.conn)); | ||||
|         mpd_connection_clear_error(mpd.conn); | ||||
|     } | ||||
|  | ||||
|     cur --; | ||||
|     cur += json_emit_raw_str(cur, end - cur, "}}}"); | ||||
|  | ||||
|     *current_song_id = mpd_status_get_song_id(status); | ||||
|     *next_song_id = mpd_status_get_next_song_id(status); | ||||
|     *queue_version = mpd_status_get_queue_version(status); | ||||
|     mpd_status_free(status); | ||||
|     return len; | ||||
|     return cur - buffer; | ||||
| } | ||||
|  | ||||
| int mympd_put_settings(char *buffer) | ||||
| @@ -788,37 +811,33 @@ int mympd_put_settings(char *buffer) | ||||
| } | ||||
|  | ||||
|  | ||||
| int mpd_put_outputs(char *buffer, int names) | ||||
| int mpd_put_outputnames(char *buffer) | ||||
| { | ||||
|     char *cur = buffer; | ||||
|     const char *end = buffer + MAX_SIZE; | ||||
|     struct mpd_output *out; | ||||
|     int nout; | ||||
|     char *str, *strend; | ||||
|  | ||||
|     str = buffer; | ||||
|     strend = buffer+MAX_SIZE; | ||||
|     str += snprintf(str, strend-str, "{\"type\":\"%s\", \"data\":{", | ||||
|             names ? "outputnames" : "outputs"); | ||||
|      | ||||
|     cur += json_emit_raw_str(cur, end - cur, "{\"type\": \"outputnames\", \"data\":{"); | ||||
|  | ||||
|     mpd_send_outputs(mpd.conn); | ||||
|     nout = 0; | ||||
|      | ||||
|     while ((out = mpd_recv_output(mpd.conn)) != NULL) { | ||||
|         if (nout++) | ||||
|             *str++ = ','; | ||||
|         if (names) | ||||
|             str += snprintf(str, strend - str, " \"%d\":\"%s\"", | ||||
|                     mpd_output_get_id(out), mpd_output_get_name(out)); | ||||
|         else | ||||
|             str += snprintf(str, strend-str, " \"%d\":%d", | ||||
|                     mpd_output_get_id(out), mpd_output_get_enabled(out)); | ||||
|         cur += json_emit_raw_str(cur, end - cur, "\""); | ||||
|         cur += json_emit_int(cur, end - cur, mpd_output_get_id(out)); | ||||
|         cur += json_emit_raw_str(cur, end - cur, "\":"); | ||||
|         cur += json_emit_quoted_str(cur, end - cur, mpd_output_get_name(out)); | ||||
|         cur += json_emit_raw_str(cur, end - cur, ","); | ||||
|         mpd_output_free(out); | ||||
|     } | ||||
|     if (!mpd_response_finish(mpd.conn)) { | ||||
|         fprintf(stderr, "MPD outputs: %s\n", mpd_connection_get_error_message(mpd.conn)); | ||||
|         mpd_connection_clear_error(mpd.conn); | ||||
|         return 0; | ||||
|     } | ||||
|     str += snprintf(str, strend-str, " }}"); | ||||
|     return str-buffer; | ||||
|  | ||||
|     cur --; | ||||
|     cur += json_emit_raw_str(cur, end - cur, "}}"); | ||||
|      | ||||
|     return cur - buffer; | ||||
| } | ||||
|  | ||||
| int mpd_put_current_song(char *buffer) | ||||
|   | ||||
| @@ -44,7 +44,7 @@ | ||||
| #define GEN_STR(X) #X, | ||||
| #define MPD_CMDS(X) \ | ||||
|     X(MPD_API_GET_QUEUE) \ | ||||
|     X(MPD_API_GET_BROWSE) \ | ||||
|     X(MPD_API_GET_FILESYSTEM) \ | ||||
|     X(MPD_API_ADD_TRACK) \ | ||||
|     X(MPD_API_ADD_PLAY_TRACK) \ | ||||
|     X(MPD_API_ADD_PLAYLIST) \ | ||||
| @@ -66,7 +66,7 @@ | ||||
|     X(MPD_API_SET_NEXT) \ | ||||
|     X(MPD_API_SET_PREV) \ | ||||
|     X(MPD_API_UPDATE_DB) \ | ||||
|     X(MPD_API_GET_OUTPUTS) \ | ||||
|     X(MPD_API_GET_OUTPUTNAMES) \ | ||||
|     X(MPD_API_TOGGLE_OUTPUT) \ | ||||
|     X(MPD_API_TOGGLE_RANDOM) \ | ||||
|     X(MPD_API_TOGGLE_CONSUME) \ | ||||
| @@ -134,7 +134,7 @@ void mpd_poll(struct mg_mgr *s); | ||||
| void callback_mpd(struct mg_connection *nc, const struct mg_str msg); | ||||
| int mpd_close_handler(struct mg_connection *c); | ||||
| int mpd_put_state(char *buffer, int *current_song_id, int *next_song_id, unsigned *queue_version); | ||||
| int mpd_put_outputs(char *buffer, int putnames); | ||||
| int mpd_put_outputnames(char *buffer); | ||||
| int mpd_put_current_song(char *buffer); | ||||
| int mpd_put_queue(char *buffer, unsigned int offset); | ||||
| int mpd_put_browse(char *buffer, char *path, unsigned int offset, char *filter); | ||||
|   | ||||
							
								
								
									
										68
									
								
								src/mympd.c
									
									
									
									
									
								
							
							
						
						
									
										68
									
								
								src/mympd.c
									
									
									
									
									
								
							| @@ -28,7 +28,8 @@ | ||||
| #include <unistd.h> | ||||
| #include <getopt.h> | ||||
| #include <sys/time.h> | ||||
| #include <pthread.h> | ||||
| //#include <pthread.h> | ||||
| #include <pwd.h> | ||||
|  | ||||
| #include "mongoose/mongoose.h" | ||||
| #include "mpd_client.h" | ||||
| @@ -43,6 +44,15 @@ static void signal_handler(int sig_num) { | ||||
|   s_signal_received = sig_num; | ||||
| } | ||||
|  | ||||
| static void handle_api(struct mg_connection *nc, struct http_message *hm) { | ||||
|   mg_printf(nc, "%s", "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"); | ||||
|   char buf[1000] = {0}; | ||||
|   memcpy(buf, hm->body.p,sizeof(buf) - 1 < hm->body.len ? sizeof(buf) - 1 : hm->body.len); | ||||
|   struct mg_str d = {buf, strlen(buf)}; | ||||
|   callback_mpd(nc, d); | ||||
|   mg_send_http_chunk(nc, "", 0); /* Send empty chunk, the end of response */ | ||||
| } | ||||
|  | ||||
| static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) { | ||||
|     switch(ev) { | ||||
|         case MG_EV_WEBSOCKET_HANDSHAKE_DONE: { | ||||
| @@ -71,7 +81,13 @@ static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) { | ||||
|             #ifdef DEBUG | ||||
|             printf("HTTP request: %.*s\n",hm->uri.len,hm->uri.p); | ||||
|             #endif | ||||
|             mg_serve_http(nc, hm, s_http_server_opts); | ||||
|             if (mg_vcmp(&hm->uri, "/api") == 0) { | ||||
|               handle_api(nc, hm); | ||||
|  | ||||
|             } | ||||
|             else { | ||||
|               mg_serve_http(nc, hm, s_http_server_opts); | ||||
|             } | ||||
|             break; | ||||
|         } | ||||
|         case MG_EV_CLOSE: { | ||||
| @@ -94,23 +110,11 @@ static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) { | ||||
| int main(int argc, char **argv) | ||||
| { | ||||
|     int n, option_index = 0; | ||||
|  | ||||
|     struct mg_mgr mgr; | ||||
|     struct mg_connection *nc; | ||||
|  | ||||
|     unsigned int current_timer = 0, last_timer = 0; | ||||
|  | ||||
|     signal(SIGTERM, signal_handler); | ||||
|     signal(SIGINT, signal_handler); | ||||
|     setvbuf(stdout, NULL, _IOLBF, 0); | ||||
|     setvbuf(stderr, NULL, _IOLBF, 0); | ||||
|      | ||||
|     mg_mgr_init(&mgr, NULL); | ||||
|      | ||||
|     char *run_as_user = NULL; | ||||
|     char const *error_msg = NULL; | ||||
|     char *webport = "8080"; | ||||
|  | ||||
|     mpd.port = 6600; | ||||
|     mpd.local_port = 0; | ||||
|     mpd.gpass = NULL; | ||||
| @@ -119,10 +123,8 @@ int main(int argc, char **argv) | ||||
|     strcpy(coverimage, "folder.jpg"); | ||||
|  | ||||
|     static struct option long_options[] = { | ||||
|         {"digest",       required_argument, 0, 'D'}, | ||||
|         {"host",         required_argument, 0, 'h'}, | ||||
|         {"port",         required_argument, 0, 'p'}, | ||||
|         {"localport",    required_argument, 0, 'l'}, | ||||
|         {"webport",      required_argument, 0, 'w'}, | ||||
|         {"user",         required_argument, 0, 'u'}, | ||||
|         {"version",      no_argument,       0, 'v'}, | ||||
| @@ -145,9 +147,6 @@ int main(int argc, char **argv) | ||||
|             case 'p': | ||||
|                 mpd.port = atoi(optarg); | ||||
|                 break; | ||||
|             case 'l': | ||||
|                 mpd.local_port = atoi(optarg); | ||||
|                 break; | ||||
|             case 'w': | ||||
|                 webport = strdup(optarg); | ||||
|                 break; | ||||
| @@ -173,11 +172,8 @@ int main(int argc, char **argv) | ||||
|                 break; | ||||
|             default: | ||||
|                 fprintf(stderr, "Usage: %s [OPTION]...\n\n" | ||||
|                         " -D, --digest <htdigest>\tpath to htdigest file for authorization\n" | ||||
|                         "                        \t(realm ympd) [no authorization]\n" | ||||
|                         " -h, --host <host>\t\tconnect to mpd at host [localhost]\n" | ||||
|                         " -p, --port <port>\t\tconnect to mpd at port [6600]\n" | ||||
|                         " -l, --localport <port>\t\tskip authorization for local port\n" | ||||
|                         " -w, --webport [ip:]<port>\tlisten interface/port for webserver [8080]\n" | ||||
|                         " -u, --user <username>\t\tdrop priviliges to user after socket bind\n" | ||||
|                         " -v, --version\t\t\tget version\n" | ||||
| @@ -191,7 +187,35 @@ int main(int argc, char **argv) | ||||
|  | ||||
|     } | ||||
|  | ||||
|     signal(SIGTERM, signal_handler); | ||||
|     signal(SIGINT, signal_handler); | ||||
|     setvbuf(stdout, NULL, _IOLBF, 0); | ||||
|     setvbuf(stderr, NULL, _IOLBF, 0); | ||||
|      | ||||
|     mg_mgr_init(&mgr, NULL); | ||||
|  | ||||
|     nc = mg_bind(&mgr, webport, ev_handler); | ||||
|     if (nc == NULL) { | ||||
|        printf("myMPD can't bind to port %s\n", webport); | ||||
|        return EXIT_FAILURE; | ||||
|     } | ||||
|  | ||||
|     if(run_as_user != NULL) { | ||||
|         printf("Droping privileges\n"); | ||||
|         struct passwd *pw; | ||||
|         if ((pw = getpwnam(run_as_user)) == NULL) { | ||||
|             printf("Unknown user\n"); | ||||
|             return EXIT_FAILURE; | ||||
|         } else if (setgid(pw->pw_gid) != 0) { | ||||
|             printf("setgid() failed"); | ||||
|             return EXIT_FAILURE; | ||||
|         } else if (setuid(pw->pw_uid) != 0) { | ||||
|             printf("setuid() failed\n"); | ||||
|             return EXIT_FAILURE; | ||||
|         } | ||||
|         free(run_as_user); | ||||
|     } | ||||
|  | ||||
|     mg_set_protocol_http_websocket(nc); | ||||
|     s_http_server_opts.document_root = SRC_PATH; | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 jcorporation
					jcorporation