mirror of
https://github.com/SuperBFG7/ympd
synced 2024-11-26 06:47:17 +00:00
better json generator, various fixups
This commit is contained in:
parent
38b4544542
commit
b9a4d83130
13
.drone.yml
13
.drone.yml
@ -1,10 +1,17 @@
|
|||||||
image: gcc4.8
|
image: gcc4.8
|
||||||
script:
|
script:
|
||||||
- sudo apt-get install -y libmpdclient-dev &> /dev/null
|
- sudo apt-get install -y libmpdclient-dev &> /dev/null
|
||||||
- cmake . -DCMAKE_INSTALL_PREFIX:PATH=/usr
|
- cmake . -DCMAKE_INSTALL_PREFIX:PATH=/usr -DCMAKE_BUILD_TYPE=Debug
|
||||||
- make
|
- make VERBOSE=1
|
||||||
- cpack -D CPACK_DEBIAN_PACKAGE_MAINTAINER="ympd Team" -G DEB
|
|
||||||
notify:
|
notify:
|
||||||
email:
|
email:
|
||||||
recipients:
|
recipients:
|
||||||
- andy@ndyk.de
|
- andy@ndyk.de
|
||||||
|
irc:
|
||||||
|
server: irc.freenode.org
|
||||||
|
nick: droneBot
|
||||||
|
channel: '#nicotest'
|
||||||
|
on_started: true
|
||||||
|
on_success: true
|
||||||
|
on_failure: true
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.6)
|
|||||||
project (ympd)
|
project (ympd)
|
||||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake/")
|
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake/")
|
||||||
set(CPACK_PACKAGE_VERSION_MAJOR "1")
|
set(CPACK_PACKAGE_VERSION_MAJOR "1")
|
||||||
set(CPACK_PACKAGE_VERSION_MINOR "0")
|
set(CPACK_PACKAGE_VERSION_MINOR "2")
|
||||||
set(CPACK_PACKAGE_VERSION_PATCH "0")
|
set(CPACK_PACKAGE_VERSION_PATCH "0")
|
||||||
|
|
||||||
option(WITH_MPD_HOST_CHANGE "Let users of the web frontend change the MPD Host" ON)
|
option(WITH_MPD_HOST_CHANGE "Let users of the web frontend change the MPD Host" ON)
|
||||||
@ -39,6 +39,7 @@ set(SOURCES
|
|||||||
src/http_server.c
|
src/http_server.c
|
||||||
src/mpd_client.c
|
src/mpd_client.c
|
||||||
src/mongoose.c
|
src/mongoose.c
|
||||||
|
src/json_encode.c
|
||||||
)
|
)
|
||||||
|
|
||||||
add_executable(ympd ${SOURCES} ${PROJECT_BINARY_DIR}/http_files.h)
|
add_executable(ympd ${SOURCES} ${PROJECT_BINARY_DIR}/http_files.h)
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
|
|
||||||
<ul id="nav_links" class="nav navbar-nav">
|
<ul id="nav_links" class="nav navbar-nav">
|
||||||
<li id="queue"><a href="#/">Queue</a></li>
|
<li id="queue"><a href="#/">Queue</a></li>
|
||||||
<li id="browse"><a href="#/browse/">Browse database</a></li>
|
<li id="browse"><a href="#/browse/0/">Browse database</a></li>
|
||||||
<li><a href="#" data-toggle="modal" data-target="#settings" onclick="getHost();">Settings</a></li>
|
<li><a href="#" data-toggle="modal" data-target="#settings" onclick="getHost();">Settings</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
@ -82,7 +82,7 @@
|
|||||||
|
|
||||||
<div class="panel panel-primary">
|
<div class="panel panel-primary">
|
||||||
<!-- Default panel contents -->
|
<!-- Default panel contents -->
|
||||||
<div id="panel-heading" class="panel-heading">Queue</div>
|
<div class="panel-heading"><b id="panel-heading">Queue</b></div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<h1>
|
<h1>
|
||||||
<span id="track-icon" class="glyphicon glyphicon-play"></span>
|
<span id="track-icon" class="glyphicon glyphicon-play"></span>
|
||||||
@ -116,6 +116,10 @@
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div><!-- /.panel -->
|
</div><!-- /.panel -->
|
||||||
|
<ul class="pager">
|
||||||
|
<li id="prev" class="page-btn hide"><a href="">Previous</a></li>
|
||||||
|
<li id="next" class="page-btn"><a href="">Next</a></li>
|
||||||
|
</ul>
|
||||||
</div><!-- /.col-md-10 -->
|
</div><!-- /.col-md-10 -->
|
||||||
|
|
||||||
<div class="col-md-2 col-xs-12" >
|
<div class="col-md-2 col-xs-12" >
|
||||||
@ -192,6 +196,10 @@
|
|||||||
data-placement="right" data-toggle="popover" data-content="Password does not match!"
|
data-placement="right" data-toggle="popover" data-content="Password does not match!"
|
||||||
data-trigger="manual" />
|
data-trigger="manual" />
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group col-md-12">
|
||||||
|
<div id="mpd_password_set" class="hide alert alert-info">MPD Password is set</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
@ -203,6 +211,22 @@
|
|||||||
</div><!-- /.modal-dialog -->
|
</div><!-- /.modal-dialog -->
|
||||||
</div><!-- /.modal -->
|
</div><!-- /.modal -->
|
||||||
|
|
||||||
|
<div class="modal fade bs-example-modal-sm" id="wait" tabindex="-1" role="dialog" data-backdrop="static" data-keyboard="false" aria-hidden="true">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h1>Searching...</h1>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="progress progress-striped active">
|
||||||
|
<div class="progress-bar" role="progressbar" aria-valuenow="45" aria-valuemin="0" aria-valuemax="100" style="width: 100%">
|
||||||
|
<span class="sr-only">Please Wait</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<!-- Bootstrap core JavaScript
|
<!-- Bootstrap core JavaScript
|
||||||
|
152
htdocs/js/mpd.js
152
htdocs/js/mpd.js
@ -19,34 +19,49 @@
|
|||||||
var socket;
|
var socket;
|
||||||
var last_state;
|
var last_state;
|
||||||
var current_app;
|
var current_app;
|
||||||
|
var pagination = 0;
|
||||||
|
var browsepath;
|
||||||
var lastSongTitle = "";
|
var lastSongTitle = "";
|
||||||
var current_song = new Object();
|
var current_song = new Object();
|
||||||
|
var MAX_ELEMENTS_PER_PAGE = 512;
|
||||||
|
|
||||||
var app = $.sammy(function() {
|
var app = $.sammy(function() {
|
||||||
this.before('/', function(e, data) {
|
|
||||||
$('#nav_links > li').removeClass('active');
|
|
||||||
});
|
|
||||||
|
|
||||||
this.get('#/', function() {
|
function runBrowse() {
|
||||||
current_app = 'queue';
|
current_app = 'queue';
|
||||||
|
|
||||||
$('#breadcrump').addClass('hide');
|
$('#breadcrump').addClass('hide');
|
||||||
$('#salamisandwich').find("tr:gt(0)").remove();
|
$('#salamisandwich').find("tr:gt(0)").remove();
|
||||||
socket.send('MPD_API_GET_QUEUE');
|
socket.send('MPD_API_GET_QUEUE,'+pagination);
|
||||||
|
|
||||||
$('#panel-heading').text("Queue");
|
$('#panel-heading').text("Queue");
|
||||||
$('#queue').addClass('active');
|
$('#queue').addClass('active');
|
||||||
|
}
|
||||||
|
|
||||||
|
function prepare() {
|
||||||
|
$('#nav_links > li').removeClass('active');
|
||||||
|
$('.page-btn').addClass('hide');
|
||||||
|
pagination = 0;
|
||||||
|
browsepath = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
this.get(/\#\/(\d+)/, function() {
|
||||||
|
prepare();
|
||||||
|
pagination = parseInt(this.params['splat'][0]);
|
||||||
|
runBrowse();
|
||||||
});
|
});
|
||||||
|
|
||||||
this.get(/\#\/browse\/(.*)/, function() {
|
this.get(/\#\/browse\/(\d+)\/(.*)/, function() {
|
||||||
|
prepare();
|
||||||
|
browsepath = this.params['splat'][1];
|
||||||
|
pagination = parseInt(this.params['splat'][0]);
|
||||||
current_app = 'browse';
|
current_app = 'browse';
|
||||||
$('#breadcrump').removeClass('hide').empty().append("<li><a href=\"#/browse/\">root</a></li>");
|
$('#breadcrump').removeClass('hide').empty().append("<li><a href=\"#/browse/0/\">root</a></li>");
|
||||||
$('#salamisandwich').find("tr:gt(0)").remove();
|
$('#salamisandwich').find("tr:gt(0)").remove();
|
||||||
var path = this.params['splat'][0];
|
socket.send('MPD_API_GET_BROWSE,'+pagination+','+(browsepath ? browsepath : "/"));
|
||||||
|
|
||||||
socket.send('MPD_API_GET_BROWSE,' + path);
|
$('#panel-heading').text("Browse database: "+browsepath);
|
||||||
|
var path_array = browsepath.split('/');
|
||||||
$('#panel-heading').text("Browse database: "+path);
|
|
||||||
var path_array = path.split('/');
|
|
||||||
var full_path = "";
|
var full_path = "";
|
||||||
$.each(path_array, function(index, chunk) {
|
$.each(path_array, function(index, chunk) {
|
||||||
if(path_array.length - 1 == index) {
|
if(path_array.length - 1 == index) {
|
||||||
@ -55,7 +70,7 @@ var app = $.sammy(function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
full_path = full_path + chunk;
|
full_path = full_path + chunk;
|
||||||
$('#breadcrump').append("<li><a href=\"#/browse/" + full_path + "\">"+chunk+"</a></li>");
|
$('#breadcrump').append("<li><a href=\"#/browse/0/" + full_path + "\">"+chunk+"</a></li>");
|
||||||
full_path += "/";
|
full_path += "/";
|
||||||
});
|
});
|
||||||
$('#browse').addClass('active');
|
$('#browse').addClass('active');
|
||||||
@ -73,7 +88,7 @@ var app = $.sammy(function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.get("/", function(context) {
|
this.get("/", function(context) {
|
||||||
context.redirect("#/");
|
context.redirect("#/0");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -117,8 +132,8 @@ function webSocketConnect() {
|
|||||||
app.run();
|
app.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
socket.onmessage =function got_packet(msg) {
|
socket.onmessage = function got_packet(msg) {
|
||||||
if(msg.data === last_state)
|
if(msg.data === last_state || msg.data.length == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var obj = JSON.parse(msg.data);
|
var obj = JSON.parse(msg.data);
|
||||||
@ -140,6 +155,11 @@ function webSocketConnect() {
|
|||||||
"</td><td></td></tr>");
|
"</td><td></td></tr>");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(obj.data[obj.data.length-1].id >= pagination + MAX_ELEMENTS_PER_PAGE)
|
||||||
|
$('#next').removeClass('hide');
|
||||||
|
if(pagination > 0)
|
||||||
|
$('#prev').removeClass('hide');
|
||||||
|
|
||||||
$('#salamisandwich > tbody > tr').on({
|
$('#salamisandwich > tbody > tr').on({
|
||||||
mouseover: function(){
|
mouseover: function(){
|
||||||
if($(this).children().last().has("a").length == 0)
|
if($(this).children().last().has("a").length == 0)
|
||||||
@ -160,6 +180,7 @@ function webSocketConnect() {
|
|||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case "search":
|
case "search":
|
||||||
|
$('#wait').modal('hide');
|
||||||
case "browse":
|
case "browse":
|
||||||
if(current_app !== 'browse' && current_app !== 'search')
|
if(current_app !== 'browse' && current_app !== 'search')
|
||||||
break;
|
break;
|
||||||
@ -194,7 +215,22 @@ function webSocketConnect() {
|
|||||||
"</td><td></td></tr>"
|
"</td><td></td></tr>"
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
case "wrap":
|
||||||
|
if(current_app == 'browse') {
|
||||||
|
$('#next').removeClass('hide');
|
||||||
|
} else {
|
||||||
|
$('#salamisandwich > tbody').append(
|
||||||
|
"<tr><td><span class=\"glyphicon glyphicon-remove\"></span></td>" +
|
||||||
|
"<td>Too many results, please refine your search!</td>" +
|
||||||
|
"<td></td><td></td></tr>"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(pagination > 0)
|
||||||
|
$('#prev').removeClass('hide');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function appendClickableIcon(appendTo, onClickAction, glyphicon) {
|
function appendClickableIcon(appendTo, onClickAction, glyphicon) {
|
||||||
@ -219,21 +255,27 @@ function webSocketConnect() {
|
|||||||
appendClickableIcon($(this), 'MPD_API_ADD_PLAY_TRACK', 'play');
|
appendClickableIcon($(this), 'MPD_API_ADD_PLAY_TRACK', 'play');
|
||||||
},
|
},
|
||||||
click: function() {
|
click: function() {
|
||||||
if($(this).is(".dir"))
|
switch($(this).attr('class')) {
|
||||||
app.setLocation("#/browse/"+$(this).attr("uri"));
|
case 'dir':
|
||||||
else {
|
app.setLocation("#/browse/0/"+$(this).attr("uri"));
|
||||||
if($(this).is(".song"))
|
break;
|
||||||
|
case 'song':
|
||||||
socket.send("MPD_API_ADD_TRACK," + $(this).attr("uri"));
|
socket.send("MPD_API_ADD_TRACK," + $(this).attr("uri"));
|
||||||
else
|
$('.top-right').notify({
|
||||||
|
message:{
|
||||||
|
text: $('td:nth-child(2)', this).text() + " added"
|
||||||
|
}
|
||||||
|
}).show();
|
||||||
|
break;
|
||||||
|
case 'plist':
|
||||||
socket.send("MPD_API_ADD_PLAYLIST," + $(this).attr("uri"));
|
socket.send("MPD_API_ADD_PLAYLIST," + $(this).attr("uri"));
|
||||||
|
$('.top-right').notify({
|
||||||
$('.top-right').notify({
|
message:{
|
||||||
message:{
|
text: "Playlist " + $('td:nth-child(2)', this).text() + " added"
|
||||||
text: $('td:nth-child(2)', this).text() + " added"
|
}
|
||||||
}
|
}).show();
|
||||||
}).show();
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
mouseleave: function(){
|
mouseleave: function(){
|
||||||
$(this).children().last().find("a").stop().remove();
|
$(this).children().last().find("a").stop().remove();
|
||||||
@ -300,7 +342,7 @@ function webSocketConnect() {
|
|||||||
break;
|
break;
|
||||||
case "update_queue":
|
case "update_queue":
|
||||||
if(current_app === 'queue')
|
if(current_app === 'queue')
|
||||||
socket.send('MPD_API_GET_QUEUE');
|
socket.send('MPD_API_GET_QUEUE,'+pagination);
|
||||||
break;
|
break;
|
||||||
case "song_change":
|
case "song_change":
|
||||||
$('#currenttrack').text(" " + obj.data.title);
|
$('#currenttrack').text(" " + obj.data.title);
|
||||||
@ -327,10 +369,8 @@ function webSocketConnect() {
|
|||||||
case "mpdhost":
|
case "mpdhost":
|
||||||
$('#mpdhost').val(obj.data.host);
|
$('#mpdhost').val(obj.data.host);
|
||||||
$('#mpdport').val(obj.data.port);
|
$('#mpdport').val(obj.data.port);
|
||||||
if(obj.data.passwort_set) {
|
if(obj.data.passwort_set)
|
||||||
$('#mpd_pw').attr('placeholder', '*******');
|
$('#mpd_password_set').removeClass('hide');
|
||||||
$('#mpd_pw_con').attr('placeholder', '*******');
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case "error":
|
case "error":
|
||||||
$('.top-right').notify({
|
$('.top-right').notify({
|
||||||
@ -481,11 +521,38 @@ function getHost() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$('#search').submit(function () {
|
$('#search').submit(function () {
|
||||||
|
|
||||||
app.setLocation("#/search/"+$('#search > div > input').val());
|
app.setLocation("#/search/"+$('#search > div > input').val());
|
||||||
|
$('#wait').modal('show');
|
||||||
|
setTimeout(function() {
|
||||||
|
$('#wait').modal('hide');
|
||||||
|
}, 10000);
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$('.page-btn').on('click', function (e) {
|
||||||
|
|
||||||
|
switch ($(this).text()) {
|
||||||
|
case "Next":
|
||||||
|
pagination += MAX_ELEMENTS_PER_PAGE;
|
||||||
|
break;
|
||||||
|
case "Previous":
|
||||||
|
pagination -= MAX_ELEMENTS_PER_PAGE;
|
||||||
|
if(pagination <= 0)
|
||||||
|
pagination = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(current_app) {
|
||||||
|
case "queue":
|
||||||
|
app.setLocation('#/'+pagination);
|
||||||
|
break;
|
||||||
|
case "browse":
|
||||||
|
app.setLocation('#/browse/'+pagination+'/'+browsepath);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
e.preventDefault();
|
||||||
|
});
|
||||||
|
|
||||||
function confirmSettings() {
|
function confirmSettings() {
|
||||||
if($('#mpd_pw').val().length + $('#mpd_pw_con').val().length > 0) {
|
if($('#mpd_pw').val().length + $('#mpd_pw_con').val().length > 0) {
|
||||||
if ($('#mpd_pw').val() !== $('#mpd_pw_con').val())
|
if ($('#mpd_pw').val() !== $('#mpd_pw_con').val())
|
||||||
@ -507,16 +574,9 @@ function notificationsSupported() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function songNotify(artist, title) {
|
function songNotify(artist, title) {
|
||||||
if (!notificationsSupported())
|
var notification = window.webkitNotifications.createNotification("assets/favicon.ico", artist, title);
|
||||||
return;
|
notification.show();
|
||||||
|
setTimeout(function(notification) {
|
||||||
if (window.webkitNotifications.checkPermission() == 0) {
|
notification.cancel();
|
||||||
var notification = window.webkitNotifications.createNotification("assets/favicon.ico", artist, title);
|
}, 3000, notification);
|
||||||
notification.show();
|
|
||||||
setTimeout(function(notification) {
|
|
||||||
notification.cancel();
|
|
||||||
}, 3000, notification);
|
|
||||||
} else {
|
|
||||||
window.webkitNotifications.requestPermission();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
58
src/json_encode.c
Normal file
58
src/json_encode.c
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
// Copyright (c) 2004-2013 Sergey Lyubka <valenok@gmail.com>
|
||||||
|
// Copyright (c) 2013 Cesanta Software Limited
|
||||||
|
// All rights reserved
|
||||||
|
//
|
||||||
|
// This library is dual-licensed: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License version 2 as
|
||||||
|
// published by the Free Software Foundation. For the terms of this
|
||||||
|
// license, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// You are free to use this library under the terms of the GNU General
|
||||||
|
// Public License, but WITHOUT ANY WARRANTY; without even the implied
|
||||||
|
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
// See the GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// Alternatively, you can license this library under a commercial
|
||||||
|
// license, as set out in <http://cesanta.com/products.html>.
|
||||||
|
|
||||||
|
// json encoder 'frozen' from https://github.com/cesanta/frozen
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "json_encode.h"
|
||||||
|
|
||||||
|
int json_emit_int(char *buf, int buf_len, long int value) {
|
||||||
|
return buf_len <= 0 ? 0 : snprintf(buf, buf_len, "%ld", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
int json_emit_double(char *buf, int buf_len, double value) {
|
||||||
|
return buf_len <= 0 ? 0 : snprintf(buf, buf_len, "%g", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
int json_emit_quoted_str(char *buf, int buf_len, const char *str) {
|
||||||
|
int i = 0, j = 0, ch;
|
||||||
|
|
||||||
|
#define EMIT(x) do { if (j < buf_len) buf[j++] = x; } while (0)
|
||||||
|
|
||||||
|
EMIT('"');
|
||||||
|
while ((ch = str[i++]) != '\0' && j < buf_len) {
|
||||||
|
switch (ch) {
|
||||||
|
case '"': EMIT('\\'); EMIT('"'); break;
|
||||||
|
case '\\': EMIT('\\'); EMIT('\\'); break;
|
||||||
|
case '\b': EMIT('\\'); EMIT('b'); break;
|
||||||
|
case '\f': EMIT('\\'); EMIT('f'); break;
|
||||||
|
case '\n': EMIT('\\'); EMIT('n'); break;
|
||||||
|
case '\r': EMIT('\\'); EMIT('r'); break;
|
||||||
|
case '\t': EMIT('\\'); EMIT('t'); break;
|
||||||
|
default: EMIT(ch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EMIT('"');
|
||||||
|
EMIT(0);
|
||||||
|
|
||||||
|
return j == 0 ? 0 : j - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int json_emit_raw_str(char *buf, int buf_len, const char *str) {
|
||||||
|
return buf_len <= 0 ? 0 : snprintf(buf, buf_len, "%s", str);
|
||||||
|
}
|
27
src/json_encode.h
Normal file
27
src/json_encode.h
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
/* ympd
|
||||||
|
(c) 2013-2014 Andrew Karpow <andy@ndyk.de>
|
||||||
|
This project's homepage is: http://www.ympd.org
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __JSON_ENCODE_H__
|
||||||
|
#define __JSON_ENCODE_H__
|
||||||
|
|
||||||
|
int json_emit_int(char *buf, int buf_len, long int value);
|
||||||
|
int json_emit_double(char *buf, int buf_len, double value);
|
||||||
|
int json_emit_quoted_str(char *buf, int buf_len, const char *str);
|
||||||
|
int json_emit_raw_str(char *buf, int buf_len, const char *str);
|
||||||
|
|
||||||
|
#endif
|
163
src/mpd_client.c
163
src/mpd_client.c
@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#include "mpd_client.h"
|
#include "mpd_client.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "json_encode.h"
|
||||||
|
|
||||||
const char * mpd_cmd_strs[] = {
|
const char * mpd_cmd_strs[] = {
|
||||||
MPD_CMDS(GEN_STR)
|
MPD_CMDS(GEN_STR)
|
||||||
@ -77,9 +78,6 @@ int callback_mpd(struct mg_connection *c)
|
|||||||
case MPD_API_RM_ALL:
|
case MPD_API_RM_ALL:
|
||||||
mpd_run_clear(mpd.conn);
|
mpd_run_clear(mpd.conn);
|
||||||
break;
|
break;
|
||||||
case MPD_API_GET_QUEUE:
|
|
||||||
n = mpd_put_queue(mpd.buf);
|
|
||||||
break;
|
|
||||||
case MPD_API_RM_TRACK:
|
case MPD_API_RM_TRACK:
|
||||||
if(sscanf(c->content, "MPD_API_RM_TRACK,%u", &uint_buf))
|
if(sscanf(c->content, "MPD_API_RM_TRACK,%u", &uint_buf))
|
||||||
mpd_run_delete_id(mpd.conn, uint_buf);
|
mpd_run_delete_id(mpd.conn, uint_buf);
|
||||||
@ -112,12 +110,16 @@ int callback_mpd(struct mg_connection *c)
|
|||||||
if(sscanf(c->content, "MPD_API_SET_SEEK,%u,%u", &uint_buf, &uint_buf_2))
|
if(sscanf(c->content, "MPD_API_SET_SEEK,%u,%u", &uint_buf, &uint_buf_2))
|
||||||
mpd_run_seek_id(mpd.conn, uint_buf, uint_buf_2);
|
mpd_run_seek_id(mpd.conn, uint_buf, uint_buf_2);
|
||||||
break;
|
break;
|
||||||
|
case MPD_API_GET_QUEUE:
|
||||||
|
if(sscanf(c->content, "MPD_API_GET_QUEUE,%u", &uint_buf))
|
||||||
|
n = mpd_put_queue(mpd.buf, uint_buf);
|
||||||
|
break;
|
||||||
case MPD_API_GET_BROWSE:
|
case MPD_API_GET_BROWSE:
|
||||||
if(sscanf(c->content, "MPD_API_GET_BROWSE,%m[^\t\n]", &p_charbuf) && p_charbuf != NULL)
|
if(sscanf(c->content, "MPD_API_GET_BROWSE,%u,%m[^\t\n]", &uint_buf, &p_charbuf) && p_charbuf != NULL)
|
||||||
n = mpd_put_browse(mpd.buf, p_charbuf);
|
{
|
||||||
else
|
n = mpd_put_browse(mpd.buf, p_charbuf, uint_buf);
|
||||||
n = mpd_put_browse(mpd.buf, "/");
|
free(p_charbuf);
|
||||||
free(p_charbuf);
|
}
|
||||||
break;
|
break;
|
||||||
case MPD_API_ADD_TRACK:
|
case MPD_API_ADD_TRACK:
|
||||||
if(sscanf(c->content, "MPD_API_ADD_TRACK,%m[^\t\n]", &p_charbuf) && p_charbuf != NULL)
|
if(sscanf(c->content, "MPD_API_ADD_TRACK,%m[^\t\n]", &p_charbuf) && p_charbuf != NULL)
|
||||||
@ -177,7 +179,6 @@ int callback_mpd(struct mg_connection *c)
|
|||||||
|
|
||||||
mpd.password = p_charbuf;
|
mpd.password = p_charbuf;
|
||||||
mpd.conn_state = MPD_RECONNECT;
|
mpd.conn_state = MPD_RECONNECT;
|
||||||
printf("Got mpd pw %s\n", mpd.password);
|
|
||||||
return MG_CLIENT_CONTINUE;
|
return MG_CLIENT_CONTINUE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -309,21 +310,13 @@ void mpd_poll(struct mg_server *s)
|
|||||||
|
|
||||||
char* mpd_get_title(struct mpd_song const *song)
|
char* mpd_get_title(struct mpd_song const *song)
|
||||||
{
|
{
|
||||||
char *str, *ptr;
|
char *str;
|
||||||
|
|
||||||
str = (char *)mpd_song_get_tag(song, MPD_TAG_TITLE, 0);
|
str = (char *)mpd_song_get_tag(song, MPD_TAG_TITLE, 0);
|
||||||
if(str == NULL){
|
if(str == NULL){
|
||||||
str = basename((char *)mpd_song_get_uri(song));
|
str = basename((char *)mpd_song_get_uri(song));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(str == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
ptr = str;
|
|
||||||
while(*ptr++ != '\0')
|
|
||||||
if(*ptr=='"')
|
|
||||||
*ptr='\'';
|
|
||||||
|
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -373,106 +366,131 @@ int mpd_put_current_song(char *buffer)
|
|||||||
if(song == NULL)
|
if(song == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
cur += snprintf(cur, end - cur, "{\"type\": \"song_change\", \"data\":"
|
cur += json_emit_raw_str(cur, end - cur, "{\"type\": \"song_change\", \"data\":{\"pos\":");
|
||||||
"{\"pos\":%d, \"title\":\"%s\"",
|
cur += json_emit_int(cur, end - cur, mpd_song_get_pos(song));
|
||||||
mpd_song_get_pos(song),
|
cur += json_emit_raw_str(cur, end - cur, ",\"title\":");
|
||||||
mpd_get_title(song));
|
cur += json_emit_quoted_str(cur, end - cur, mpd_get_title(song));
|
||||||
if(mpd_song_get_tag(song, MPD_TAG_ARTIST, 0) != NULL)
|
|
||||||
cur += snprintf(cur, end - cur, ", \"artist\":\"%s\"",
|
|
||||||
mpd_song_get_tag(song, MPD_TAG_ARTIST, 0));
|
|
||||||
if(mpd_song_get_tag(song, MPD_TAG_ALBUM, 0) != NULL)
|
|
||||||
cur += snprintf(cur, end - cur, ", \"album\":\"%s\"",
|
|
||||||
mpd_song_get_tag(song, MPD_TAG_ALBUM, 0));
|
|
||||||
|
|
||||||
cur += snprintf(cur, end - cur, "}}");
|
if(mpd_song_get_tag(song, MPD_TAG_ARTIST, 0) != NULL)
|
||||||
|
{
|
||||||
|
cur += json_emit_raw_str(cur, end - cur, ",\"artist\":");
|
||||||
|
cur += json_emit_quoted_str(cur, end - cur, mpd_song_get_tag(song, MPD_TAG_ARTIST, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(mpd_song_get_tag(song, MPD_TAG_ALBUM, 0) != NULL)
|
||||||
|
{
|
||||||
|
cur += json_emit_raw_str(cur, end - cur, ",\"album\":");
|
||||||
|
cur += json_emit_quoted_str(cur, end - cur, mpd_song_get_tag(song, MPD_TAG_ALBUM, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
cur += json_emit_raw_str(cur, end - cur, "}}");
|
||||||
mpd_song_free(song);
|
mpd_song_free(song);
|
||||||
mpd_response_finish(mpd.conn);
|
mpd_response_finish(mpd.conn);
|
||||||
|
|
||||||
return cur - buffer;
|
return cur - buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mpd_put_queue(char *buffer)
|
int mpd_put_queue(char *buffer, unsigned int offset)
|
||||||
{
|
{
|
||||||
char *cur = buffer;
|
char *cur = buffer;
|
||||||
const char *end = buffer + MAX_SIZE;
|
const char *end = buffer + MAX_SIZE;
|
||||||
struct mpd_entity *entity;
|
struct mpd_entity *entity;
|
||||||
|
|
||||||
if (!mpd_send_list_queue_meta(mpd.conn))
|
if (!mpd_send_list_queue_range_meta(mpd.conn, offset, offset+MAX_ELEMENTS_PER_PAGE))
|
||||||
RETURN_ERROR_AND_RECOVER("mpd_send_list_queue_meta");
|
RETURN_ERROR_AND_RECOVER("mpd_send_list_queue_meta");
|
||||||
|
|
||||||
cur += snprintf(cur, end - cur, "{\"type\": \"queue\", \"data\": [ ");
|
cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"queue\",\"data\":[ ");
|
||||||
|
|
||||||
while((entity = mpd_recv_entity(mpd.conn)) != NULL) {
|
while((entity = mpd_recv_entity(mpd.conn)) != NULL) {
|
||||||
const struct mpd_song *song;
|
const struct mpd_song *song;
|
||||||
|
|
||||||
if(mpd_entity_get_type(entity) == MPD_ENTITY_TYPE_SONG) {
|
if(mpd_entity_get_type(entity) == MPD_ENTITY_TYPE_SONG) {
|
||||||
song = mpd_entity_get_song(entity);
|
song = mpd_entity_get_song(entity);
|
||||||
cur += snprintf(cur, end - cur,
|
|
||||||
"{\"id\":%d, \"pos\":%d, \"duration\":%d, \"title\":\"%s\"},",
|
cur += json_emit_raw_str(cur, end - cur, "{\"id\":");
|
||||||
mpd_song_get_id(song),
|
cur += json_emit_int(cur, end - cur, mpd_song_get_id(song));
|
||||||
mpd_song_get_pos(song),
|
cur += json_emit_raw_str(cur, end - cur, ",\"pos\":");
|
||||||
mpd_song_get_duration(song),
|
cur += json_emit_int(cur, end - cur, mpd_song_get_pos(song));
|
||||||
mpd_get_title(song)
|
cur += json_emit_raw_str(cur, end - cur, ",\"duration\":");
|
||||||
);
|
cur += json_emit_int(cur, end - cur, mpd_song_get_duration(song));
|
||||||
|
cur += json_emit_raw_str(cur, end - cur, ",\"title\":");
|
||||||
|
cur += json_emit_quoted_str(cur, end - cur, mpd_get_title(song));
|
||||||
|
cur += json_emit_raw_str(cur, end - cur, "},");
|
||||||
}
|
}
|
||||||
mpd_entity_free(entity);
|
mpd_entity_free(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* remove last ',' */
|
/* remove last ',' */
|
||||||
cur--;
|
cur--;
|
||||||
cur += snprintf(cur, end - cur, "] }");
|
|
||||||
|
cur += json_emit_raw_str(cur, end - cur, "]}");
|
||||||
return cur - buffer;
|
return cur - buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mpd_put_browse(char *buffer, char *path)
|
int mpd_put_browse(char *buffer, char *path, unsigned int offset)
|
||||||
{
|
{
|
||||||
char *cur = buffer;
|
char *cur = buffer;
|
||||||
const char *end = buffer + MAX_SIZE;
|
const char *end = buffer + MAX_SIZE;
|
||||||
struct mpd_entity *entity;
|
struct mpd_entity *entity;
|
||||||
|
unsigned int entity_count = 0;
|
||||||
|
|
||||||
if (!mpd_send_list_meta(mpd.conn, path))
|
if (!mpd_send_list_meta(mpd.conn, path))
|
||||||
RETURN_ERROR_AND_RECOVER("mpd_send_list_meta");
|
RETURN_ERROR_AND_RECOVER("mpd_send_list_meta");
|
||||||
|
|
||||||
cur += snprintf(cur, end - cur, "{\"type\":\"browse\",\"data\":[ ");
|
cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"browse\",\"data\":[ ");
|
||||||
|
|
||||||
while((entity = mpd_recv_entity(mpd.conn)) != NULL) {
|
while((entity = mpd_recv_entity(mpd.conn)) != NULL) {
|
||||||
const struct mpd_song *song;
|
const struct mpd_song *song;
|
||||||
const struct mpd_directory *dir;
|
const struct mpd_directory *dir;
|
||||||
const struct mpd_playlist *pl;
|
const struct mpd_playlist *pl;
|
||||||
|
|
||||||
|
if(offset > entity_count)
|
||||||
|
{
|
||||||
|
mpd_entity_free(entity);
|
||||||
|
entity_count++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if(offset + MAX_ELEMENTS_PER_PAGE - 1 < entity_count)
|
||||||
|
{
|
||||||
|
mpd_entity_free(entity);
|
||||||
|
cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"wrap\",\"count\":");
|
||||||
|
cur += json_emit_int(cur, end - cur, entity_count);
|
||||||
|
cur += json_emit_raw_str(cur, end - cur, "} ");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
switch (mpd_entity_get_type(entity)) {
|
switch (mpd_entity_get_type(entity)) {
|
||||||
case MPD_ENTITY_TYPE_UNKNOWN:
|
case MPD_ENTITY_TYPE_UNKNOWN:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MPD_ENTITY_TYPE_SONG:
|
case MPD_ENTITY_TYPE_SONG:
|
||||||
song = mpd_entity_get_song(entity);
|
song = mpd_entity_get_song(entity);
|
||||||
cur += snprintf(cur, end - cur,
|
cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"song\",\"uri\":");
|
||||||
"{\"type\":\"song\",\"uri\":\"%s\",\"duration\":%d,\"title\":\"%s\"},",
|
cur += json_emit_quoted_str(cur, end - cur, mpd_song_get_uri(song));
|
||||||
mpd_song_get_uri(song),
|
cur += json_emit_raw_str(cur, end - cur, ",\"duration\":");
|
||||||
mpd_song_get_duration(song),
|
cur += json_emit_int(cur, end - cur, mpd_song_get_duration(song));
|
||||||
mpd_get_title(song)
|
cur += json_emit_raw_str(cur, end - cur, ",\"title\":");
|
||||||
);
|
cur += json_emit_quoted_str(cur, end - cur, mpd_get_title(song));
|
||||||
|
cur += json_emit_raw_str(cur, end - cur, "},");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MPD_ENTITY_TYPE_DIRECTORY:
|
case MPD_ENTITY_TYPE_DIRECTORY:
|
||||||
dir = mpd_entity_get_directory(entity);
|
dir = mpd_entity_get_directory(entity);
|
||||||
cur += snprintf(cur, end - cur,
|
|
||||||
"{\"type\":\"directory\",\"dir\":\"%s\", \"basename\":\"%s\"},",
|
cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"directory\",\"dir\":");
|
||||||
mpd_directory_get_path(dir),
|
cur += json_emit_quoted_str(cur, end - cur, mpd_directory_get_path(dir));
|
||||||
basename((char *)mpd_directory_get_path(dir))
|
cur += json_emit_raw_str(cur, end - cur, "},");
|
||||||
);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MPD_ENTITY_TYPE_PLAYLIST:
|
case MPD_ENTITY_TYPE_PLAYLIST:
|
||||||
pl = mpd_entity_get_playlist(entity);
|
pl = mpd_entity_get_playlist(entity);
|
||||||
cur += snprintf(cur, end - cur,
|
cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"playlist\",\"plist\":");
|
||||||
"{\"type\":\"playlist\",\"plist\":\"%s\"},",
|
cur += json_emit_quoted_str(cur, end - cur, mpd_playlist_get_path(pl));
|
||||||
mpd_playlist_get_path(pl)
|
cur += json_emit_raw_str(cur, end - cur, "},");
|
||||||
);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
mpd_entity_free(entity);
|
mpd_entity_free(entity);
|
||||||
|
entity_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mpd_connection_get_error(mpd.conn) != MPD_ERROR_SUCCESS || !mpd_response_finish(mpd.conn)) {
|
if (mpd_connection_get_error(mpd.conn) != MPD_ERROR_SUCCESS || !mpd_response_finish(mpd.conn)) {
|
||||||
@ -483,12 +501,14 @@ int mpd_put_browse(char *buffer, char *path)
|
|||||||
|
|
||||||
/* remove last ',' */
|
/* remove last ',' */
|
||||||
cur--;
|
cur--;
|
||||||
cur += snprintf(cur, end - cur, "] }");
|
|
||||||
|
cur += json_emit_raw_str(cur, end - cur, "]}");
|
||||||
return cur - buffer;
|
return cur - buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mpd_search(char *buffer, char *searchstr)
|
int mpd_search(char *buffer, char *searchstr)
|
||||||
{
|
{
|
||||||
|
int i = 0;
|
||||||
char *cur = buffer;
|
char *cur = buffer;
|
||||||
const char *end = buffer + MAX_SIZE;
|
const char *end = buffer + MAX_SIZE;
|
||||||
struct mpd_song *song;
|
struct mpd_song *song;
|
||||||
@ -500,21 +520,30 @@ int mpd_search(char *buffer, char *searchstr)
|
|||||||
else if(mpd_search_commit(mpd.conn) == false)
|
else if(mpd_search_commit(mpd.conn) == false)
|
||||||
RETURN_ERROR_AND_RECOVER("mpd_search_commit");
|
RETURN_ERROR_AND_RECOVER("mpd_search_commit");
|
||||||
else {
|
else {
|
||||||
cur += snprintf(cur, end - cur, "{\"type\": \"search\", \"data\": [ ");
|
cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"search\",\"data\":[ ");
|
||||||
|
|
||||||
while((song = mpd_recv_song(mpd.conn)) != NULL) {
|
while((song = mpd_recv_song(mpd.conn)) != NULL) {
|
||||||
cur += snprintf(cur, end - cur,
|
cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"song\",\"uri\":");
|
||||||
"{\"type\":\"song\",\"uri\":\"%s\",\"duration\":%d,\"title\":\"%s\"},",
|
cur += json_emit_quoted_str(cur, end - cur, mpd_song_get_uri(song));
|
||||||
mpd_song_get_uri(song),
|
cur += json_emit_raw_str(cur, end - cur, ",\"duration\":");
|
||||||
mpd_song_get_duration(song),
|
cur += json_emit_int(cur, end - cur, mpd_song_get_duration(song));
|
||||||
mpd_get_title(song)
|
cur += json_emit_raw_str(cur, end - cur, ",\"title\":");
|
||||||
);
|
cur += json_emit_quoted_str(cur, end - cur, mpd_get_title(song));
|
||||||
|
cur += json_emit_raw_str(cur, end - cur, "},");
|
||||||
mpd_song_free(song);
|
mpd_song_free(song);
|
||||||
|
|
||||||
|
/* Maximum results */
|
||||||
|
if(i++ >= 300)
|
||||||
|
{
|
||||||
|
cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"wrap\"},");
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* remove last ',' */
|
/* remove last ',' */
|
||||||
cur--;
|
cur--;
|
||||||
cur += snprintf(cur, end - cur, "] }");
|
|
||||||
|
cur += json_emit_raw_str(cur, end - cur, "]}");
|
||||||
}
|
}
|
||||||
return cur - buffer;
|
return cur - buffer;
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,8 @@
|
|||||||
|
|
||||||
|
|
||||||
#define MAX_SIZE 1024 * 100
|
#define MAX_SIZE 1024 * 100
|
||||||
|
#define MAX_ELEMENTS_PER_PAGE 512
|
||||||
|
|
||||||
#define GEN_ENUM(X) X,
|
#define GEN_ENUM(X) X,
|
||||||
#define GEN_STR(X) #X,
|
#define GEN_STR(X) #X,
|
||||||
#define MPD_CMDS(X) \
|
#define MPD_CMDS(X) \
|
||||||
@ -98,8 +100,8 @@ int callback_mpd(struct mg_connection *c);
|
|||||||
int mpd_close_handler(struct mg_connection *c);
|
int mpd_close_handler(struct mg_connection *c);
|
||||||
int mpd_put_state(char *buffer, int *current_song_id, unsigned *queue_version);
|
int mpd_put_state(char *buffer, int *current_song_id, unsigned *queue_version);
|
||||||
int mpd_put_current_song(char *buffer);
|
int mpd_put_current_song(char *buffer);
|
||||||
int mpd_put_queue(char *buffer);
|
int mpd_put_queue(char *buffer, unsigned int offset);
|
||||||
int mpd_put_browse(char *buffer, char *path);
|
int mpd_put_browse(char *buffer, char *path, unsigned int offset);
|
||||||
int mpd_search(char *buffer, char *searchstr);
|
int mpd_search(char *buffer, char *searchstr);
|
||||||
void mpd_disconnect();
|
void mpd_disconnect();
|
||||||
#endif
|
#endif
|
||||||
|
19
src/ympd.c
19
src/ympd.c
@ -67,12 +67,12 @@ int main(int argc, char **argv)
|
|||||||
{"port", required_argument, 0, 'p'},
|
{"port", required_argument, 0, 'p'},
|
||||||
{"webport", required_argument, 0, 'w'},
|
{"webport", required_argument, 0, 'w'},
|
||||||
{"user", required_argument, 0, 'u'},
|
{"user", required_argument, 0, 'u'},
|
||||||
{"version", no_argument, 0, 'V'},
|
{"version", no_argument, 0, 'v'},
|
||||||
{"help", no_argument, 0, 0 },
|
{"help", no_argument, 0, 0 },
|
||||||
{0, 0, 0, 0 }
|
{0, 0, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
while((n = getopt_long(argc, argv, "h:p:w:u::V",
|
while((n = getopt_long(argc, argv, "h:p:w:u:v",
|
||||||
long_options, &option_index)) != -1) {
|
long_options, &option_index)) != -1) {
|
||||||
switch (n) {
|
switch (n) {
|
||||||
case 'h':
|
case 'h':
|
||||||
@ -84,9 +84,10 @@ int main(int argc, char **argv)
|
|||||||
mg_set_option(server, "listening_port", optarg);
|
mg_set_option(server, "listening_port", optarg);
|
||||||
break;
|
break;
|
||||||
case 'u':
|
case 'u':
|
||||||
|
printf("Strarg is %s\n", optarg);
|
||||||
mg_set_option(server, "run_as_user", optarg);
|
mg_set_option(server, "run_as_user", optarg);
|
||||||
break;
|
break;
|
||||||
case 'V':
|
case 'v':
|
||||||
fprintf(stdout, "ympd %d.%d.%d\n"
|
fprintf(stdout, "ympd %d.%d.%d\n"
|
||||||
"Copyright (C) 2014 Andrew Karpow <andy@ndyk.de>\n"
|
"Copyright (C) 2014 Andrew Karpow <andy@ndyk.de>\n"
|
||||||
"built " __DATE__ " "__TIME__ " ("__VERSION__")\n",
|
"built " __DATE__ " "__TIME__ " ("__VERSION__")\n",
|
||||||
@ -95,12 +96,12 @@ int main(int argc, char **argv)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "Usage: %s [OPTION]...\n\n"
|
fprintf(stderr, "Usage: %s [OPTION]...\n\n"
|
||||||
"\t-h, --host <host>\t\tconnect to mpd at host [localhost]\n"
|
" -h, --host <host>\t\tconnect to mpd at host [localhost]\n"
|
||||||
"\t-p, --port <port>\t\tconnect to mpd at port [6600]\n"
|
" -p, --port <port>\t\tconnect to mpd at port [6600]\n"
|
||||||
"\t-w, --webport [ip:]<port>\t\tlisten interface/port for webserver [8080]\n"
|
" -w, --webport [ip:]<port>\tlisten interface/port for webserver [8080]\n"
|
||||||
"\t-u, --user <username>\t\t\tdrop priviliges to user after socket bind\n"
|
" -u, --user <username>\t\tdrop priviliges to user after socket bind\n"
|
||||||
"\t-V, --version\t\t\tget version\n"
|
" -V, --version\t\t\tget version\n"
|
||||||
"\t--help\t\t\t\tthis help\n"
|
" --help\t\t\t\tthis help\n"
|
||||||
, argv[0]);
|
, argv[0]);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user