* Add configuration option to specify the user to run as.
This commit is contained in:
parent
ccc32409c5
commit
1de4ef8bc1
15
NEWS
15
NEWS
@ -1,7 +1,20 @@
|
|||||||
1.1.0 - Released 00-Month-0000
|
1.1.0 - Released 00-Month-0000
|
||||||
--------------------------------
|
--------------------------------
|
||||||
- Add support for other operating systems.
|
- Add support for other operating systems.
|
||||||
- Switch to autoconf from our little genconfig.sh.
|
- Switch to autoconf from our handcrafted genconfig.sh.
|
||||||
|
- Add configuration option for UUID.
|
||||||
|
- Add configuration option to specify the user to run as.
|
||||||
|
|
||||||
|
1.0.25 - Released 13-July-2012
|
||||||
|
--------------------------------
|
||||||
|
- Fix a couple crash bugs on malformed WAV files.
|
||||||
|
- Forcibly tweak the model number for Xbox360 clients, or they might ignore us.
|
||||||
|
- Enable all network interfaces by default if none were specified.
|
||||||
|
- Add flag to force downscaled thumbnails rather than using embedded ones.
|
||||||
|
- Add DirecTV client detection, and fix image resolution issue.
|
||||||
|
- Add support for the latest ffmpeg/libav library versions.
|
||||||
|
- Fix a potential crash on requests for a resize of a non-existent image.
|
||||||
|
- Make DeviceID checking more permissive for Sagem Radio.
|
||||||
|
|
||||||
1.0.24 - Released 14-Feb-2012
|
1.0.24 - Released 14-Feb-2012
|
||||||
--------------------------------
|
--------------------------------
|
||||||
|
35
daemonize.c
35
daemonize.c
@ -86,41 +86,6 @@ daemonize(void)
|
|||||||
return pid;
|
return pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
writepidfile(const char * fname, int pid)
|
|
||||||
{
|
|
||||||
char pidstring[16];
|
|
||||||
int pidstringlen;
|
|
||||||
int pidfile;
|
|
||||||
|
|
||||||
if(!fname || *fname == '\0')
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if( (pidfile = open(fname, O_WRONLY|O_CREAT, 0644)) < 0)
|
|
||||||
{
|
|
||||||
DPRINTF(E_ERROR, L_GENERAL, "Unable to open pidfile for writing %s: %s\n", fname, strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
pidstringlen = snprintf(pidstring, sizeof(pidstring), "%d\n", pid);
|
|
||||||
if(pidstringlen <= 0)
|
|
||||||
{
|
|
||||||
DPRINTF(E_ERROR, L_GENERAL,
|
|
||||||
"Unable to write to pidfile %s: snprintf(): FAILED\n", fname);
|
|
||||||
close(pidfile);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(write(pidfile, pidstring, pidstringlen) < 0)
|
|
||||||
DPRINTF(E_ERROR, L_GENERAL, "Unable to write to pidfile %s: %s\n", fname, strerror(errno));
|
|
||||||
}
|
|
||||||
|
|
||||||
close(pidfile);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
checkforrunning(const char * fname)
|
checkforrunning(const char * fname)
|
||||||
{
|
{
|
||||||
|
@ -37,11 +37,6 @@
|
|||||||
int
|
int
|
||||||
daemonize(void);
|
daemonize(void);
|
||||||
|
|
||||||
/* writepidfile()
|
|
||||||
* write the pid to a file */
|
|
||||||
int
|
|
||||||
writepidfile(const char * fname, int pid);
|
|
||||||
|
|
||||||
/* checkforrunning()
|
/* checkforrunning()
|
||||||
* check for another instance running
|
* check for another instance running
|
||||||
* returns: 0 only instance
|
* returns: 0 only instance
|
||||||
|
105
minidlna.c
105
minidlna.c
@ -65,6 +65,7 @@
|
|||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
#include <libgen.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
@ -409,6 +410,71 @@ check_db(sqlite3 *db, int new_db, pid_t *scanner_pid)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
writepidfile(const char *fname, int pid, uid_t uid)
|
||||||
|
{
|
||||||
|
FILE *pidfile;
|
||||||
|
struct stat st;
|
||||||
|
char path[PATH_MAX], *dir;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if(!fname || *fname == '\0')
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* Create parent directory if it doesn't already exist */
|
||||||
|
strncpyt(path, fname, sizeof(path));
|
||||||
|
dir = dirname(path);
|
||||||
|
if (stat(dir, &st) == 0)
|
||||||
|
{
|
||||||
|
if (!S_ISDIR(st.st_mode))
|
||||||
|
{
|
||||||
|
DPRINTF(E_ERROR, L_GENERAL, "Pidfile path is not a directory: %s\n",
|
||||||
|
fname);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (make_dir(dir, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) != 0)
|
||||||
|
{
|
||||||
|
DPRINTF(E_ERROR, L_GENERAL, "Unable to create pidfile directory: %s\n",
|
||||||
|
fname);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (uid >= 0)
|
||||||
|
{
|
||||||
|
if (chown(dir, uid, -1) != 0)
|
||||||
|
DPRINTF(E_WARN, L_GENERAL, "Unable to change pidfile ownership: %s\n",
|
||||||
|
dir, strerror(errno));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pidfile = fopen(fname, "w");
|
||||||
|
if (!pidfile)
|
||||||
|
{
|
||||||
|
DPRINTF(E_ERROR, L_GENERAL, "Unable to open pidfile for writing %s: %s\n",
|
||||||
|
fname, strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fprintf(pidfile, "%d\n", pid) <= 0)
|
||||||
|
{
|
||||||
|
DPRINTF(E_ERROR, L_GENERAL,
|
||||||
|
"Unable to write to pidfile %s: %s\n", fname);
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
|
if (uid >= 0)
|
||||||
|
{
|
||||||
|
if (fchown(fileno(pidfile), uid, -1) != 0)
|
||||||
|
DPRINTF(E_WARN, L_GENERAL, "Unable to change pidfile ownership: %s\n",
|
||||||
|
pidfile, strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(pidfile);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/* init phase :
|
/* init phase :
|
||||||
* 1) read configuration file
|
* 1) read configuration file
|
||||||
* 2) read command line arguments
|
* 2) read command line arguments
|
||||||
@ -429,13 +495,14 @@ init(int argc, char * * argv)
|
|||||||
const char * presurl = NULL;
|
const char * presurl = NULL;
|
||||||
const char * optionsfile = "/etc/minidlna.conf";
|
const char * optionsfile = "/etc/minidlna.conf";
|
||||||
char mac_str[13];
|
char mac_str[13];
|
||||||
char * string, * word;
|
char *string, *word;
|
||||||
enum media_types type;
|
enum media_types type;
|
||||||
char * path;
|
char *path;
|
||||||
char buf[PATH_MAX];
|
char buf[PATH_MAX];
|
||||||
char ip_addr[INET_ADDRSTRLEN + 3] = {'\0'};
|
char ip_addr[INET_ADDRSTRLEN + 3] = {'\0'};
|
||||||
char log_str[75] = "general,artwork,database,inotify,scanner,metadata,http,ssdp,tivo=warn";
|
char log_str[75] = "general,artwork,database,inotify,scanner,metadata,http,ssdp,tivo=warn";
|
||||||
char *log_level = NULL;
|
char *log_level = NULL;
|
||||||
|
uid_t uid = -1;
|
||||||
|
|
||||||
/* first check if "-f" option is used */
|
/* first check if "-f" option is used */
|
||||||
for(i=2; i<argc; i++)
|
for(i=2; i<argc; i++)
|
||||||
@ -675,6 +742,16 @@ init(int argc, char * * argv)
|
|||||||
case UPNPUUID:
|
case UPNPUUID:
|
||||||
strcpy(uuidvalue+5, ary_options[i].value);
|
strcpy(uuidvalue+5, ary_options[i].value);
|
||||||
break;
|
break;
|
||||||
|
case USER_ACCOUNT:
|
||||||
|
uid = strtol(ary_options[i].value, &string, 0);
|
||||||
|
if (*string) {
|
||||||
|
/* Symbolic username given, not UID. */
|
||||||
|
struct passwd *entry = getpwnam(ary_options[i].value);
|
||||||
|
if (!entry)
|
||||||
|
DPRINTF(E_FATAL, L_GENERAL, "Bad user '%s'.\n", argv[i]);
|
||||||
|
uid = entry->pw_uid;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
DPRINTF(E_ERROR, L_GENERAL, "Unknown option in file %s\n",
|
DPRINTF(E_ERROR, L_GENERAL, "Unknown option in file %s\n",
|
||||||
optionsfile);
|
optionsfile);
|
||||||
@ -828,6 +905,21 @@ init(int argc, char * * argv)
|
|||||||
if( system(buf) != 0 )
|
if( system(buf) != 0 )
|
||||||
DPRINTF(E_FATAL, L_GENERAL, "Failed to clean old file cache. EXITING\n");
|
DPRINTF(E_FATAL, L_GENERAL, "Failed to clean old file cache. EXITING\n");
|
||||||
break;
|
break;
|
||||||
|
case 'u':
|
||||||
|
if(i+1 == argc)
|
||||||
|
DPRINTF(E_FATAL, L_GENERAL, "Option -%c takes one argument.\n", argv[i][1]);
|
||||||
|
else {
|
||||||
|
i++;
|
||||||
|
uid = strtol(argv[i], &string, 0);
|
||||||
|
if (*string) {
|
||||||
|
/* Symbolic username given, not UID. */
|
||||||
|
struct passwd *entry = getpwnam(argv[i]);
|
||||||
|
if (!entry)
|
||||||
|
DPRINTF(E_FATAL, L_GENERAL, "Bad user '%s'.\n", argv[i]);
|
||||||
|
uid = entry->pw_uid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 'V':
|
case 'V':
|
||||||
printf("Version " MINIDLNA_VERSION "\n");
|
printf("Version " MINIDLNA_VERSION "\n");
|
||||||
exit(0);
|
exit(0);
|
||||||
@ -859,6 +951,7 @@ init(int argc, char * * argv)
|
|||||||
/*"[-l logfile] " not functionnal */
|
/*"[-l logfile] " not functionnal */
|
||||||
"\t\t[-s serial] [-m model_number] \n"
|
"\t\t[-s serial] [-m model_number] \n"
|
||||||
"\t\t[-t notify_interval] [-P pid_filename]\n"
|
"\t\t[-t notify_interval] [-P pid_filename]\n"
|
||||||
|
"\t\t[-u uid_to_run_as]\n"
|
||||||
"\t\t[-w url] [-R] [-V] [-h]\n"
|
"\t\t[-w url] [-R] [-V] [-h]\n"
|
||||||
"\nNotes:\n\tNotify interval is in seconds. Default is 895 seconds.\n"
|
"\nNotes:\n\tNotify interval is in seconds. Default is 895 seconds.\n"
|
||||||
"\tDefault pid file is %s.\n"
|
"\tDefault pid file is %s.\n"
|
||||||
@ -926,9 +1019,13 @@ init(int argc, char * * argv)
|
|||||||
if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
|
if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
|
||||||
DPRINTF(E_FATAL, L_GENERAL, "Failed to set %s handler. EXITING.\n", SIGPIPE);
|
DPRINTF(E_FATAL, L_GENERAL, "Failed to set %s handler. EXITING.\n", SIGPIPE);
|
||||||
|
|
||||||
if (writepidfile(pidfilename, pid) != 0)
|
if (writepidfile(pidfilename, pid, uid) != 0)
|
||||||
pidfilename = NULL;
|
pidfilename = NULL;
|
||||||
|
|
||||||
|
if (uid != -1 && setuid(uid) == -1)
|
||||||
|
DPRINTF(E_FATAL, L_GENERAL, "Failed to switch to uid '%d'. [%s] EXITING.\n",
|
||||||
|
uid, strerror(errno));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1000,7 +1097,7 @@ main(int argc, char * * argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
sudp = OpenAndConfSSDPReceiveSocket(n_lan_addr, lan_addr);
|
sudp = OpenAndConfSSDPReceiveSocket();
|
||||||
if(sudp < 0)
|
if(sudp < 0)
|
||||||
{
|
{
|
||||||
DPRINTF(E_INFO, L_GENERAL, "Failed to open socket for receiving SSDP. Trying to use MiniSSDPd\n");
|
DPRINTF(E_INFO, L_GENERAL, "Failed to open socket for receiving SSDP. Trying to use MiniSSDPd\n");
|
||||||
|
@ -4,6 +4,9 @@ port=8200
|
|||||||
# network interfaces to serve, comma delimited
|
# network interfaces to serve, comma delimited
|
||||||
#network_interface=eth0
|
#network_interface=eth0
|
||||||
|
|
||||||
|
# specify the user account name or uid to run as
|
||||||
|
#user=jmaggard
|
||||||
|
|
||||||
# set this to the directory you want scanned.
|
# set this to the directory you want scanned.
|
||||||
# * if have multiple directories, you can have multiple media_dir= lines
|
# * if have multiple directories, you can have multiple media_dir= lines
|
||||||
# * if you want to restrict a media_dir to a specific content type, you
|
# * if you want to restrict a media_dir to a specific content type, you
|
||||||
|
@ -63,8 +63,7 @@ AddMulticastMembership(int s, in_addr_t ifaddr)
|
|||||||
|
|
||||||
/* setting up imr structure */
|
/* setting up imr structure */
|
||||||
imr.imr_multiaddr.s_addr = inet_addr(SSDP_MCAST_ADDR);
|
imr.imr_multiaddr.s_addr = inet_addr(SSDP_MCAST_ADDR);
|
||||||
/*imr.imr_interface.s_addr = htonl(INADDR_ANY);*/
|
imr.imr_interface.s_addr = ifaddr;
|
||||||
imr.imr_interface.s_addr = ifaddr; /*inet_addr(ifaddr);*/
|
|
||||||
|
|
||||||
if (setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *)&imr, sizeof(struct ip_mreq)) < 0)
|
if (setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *)&imr, sizeof(struct ip_mreq)) < 0)
|
||||||
{
|
{
|
||||||
@ -78,7 +77,7 @@ AddMulticastMembership(int s, in_addr_t ifaddr)
|
|||||||
/* Open and configure the socket listening for
|
/* Open and configure the socket listening for
|
||||||
* SSDP udp packets sent on 239.255.255.250 port 1900 */
|
* SSDP udp packets sent on 239.255.255.250 port 1900 */
|
||||||
int
|
int
|
||||||
OpenAndConfSSDPReceiveSocket()
|
OpenAndConfSSDPReceiveSocket(void)
|
||||||
{
|
{
|
||||||
int s;
|
int s;
|
||||||
int i = 1;
|
int i = 1;
|
||||||
@ -99,9 +98,7 @@ OpenAndConfSSDPReceiveSocket()
|
|||||||
sockname.sin_family = AF_INET;
|
sockname.sin_family = AF_INET;
|
||||||
sockname.sin_port = htons(SSDP_PORT);
|
sockname.sin_port = htons(SSDP_PORT);
|
||||||
/* NOTE : it seems it doesnt work when binding on the specific address */
|
/* NOTE : it seems it doesnt work when binding on the specific address */
|
||||||
/*sockname.sin_addr.s_addr = inet_addr(UPNP_MCAST_ADDR);*/
|
|
||||||
sockname.sin_addr.s_addr = htonl(INADDR_ANY);
|
sockname.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||||
/*sockname.sin_addr.s_addr = inet_addr(ifaddr);*/
|
|
||||||
|
|
||||||
if(bind(s, (struct sockaddr *)&sockname, sizeof(struct sockaddr_in)) < 0)
|
if(bind(s, (struct sockaddr *)&sockname, sizeof(struct sockaddr_in)) < 0)
|
||||||
{
|
{
|
||||||
|
16
minissdp.h
16
minissdp.h
@ -29,35 +29,19 @@
|
|||||||
#ifndef __MINISSDP_H__
|
#ifndef __MINISSDP_H__
|
||||||
#define __MINISSDP_H__
|
#define __MINISSDP_H__
|
||||||
|
|
||||||
/*#include "minidlnatypes.h"*/
|
|
||||||
|
|
||||||
int
|
int
|
||||||
OpenAndConfSSDPReceiveSocket();
|
OpenAndConfSSDPReceiveSocket();
|
||||||
/* OpenAndConfSSDPReceiveSocket(int n_lan_addr, struct lan_addr_s * lan_addr);*/
|
|
||||||
|
|
||||||
/*int
|
|
||||||
OpenAndConfSSDPNotifySocket(const char * addr);*/
|
|
||||||
|
|
||||||
int
|
int
|
||||||
OpenAndConfSSDPNotifySockets(int * sockets);
|
OpenAndConfSSDPNotifySockets(int * sockets);
|
||||||
/*OpenAndConfSSDPNotifySockets(int * sockets,
|
|
||||||
struct lan_addr_s * lan_addr, int n_lan_addr);*/
|
|
||||||
|
|
||||||
/*void
|
|
||||||
SendSSDPNotifies(int s, const char * host, unsigned short port,
|
|
||||||
unsigned int lifetime);*/
|
|
||||||
void
|
void
|
||||||
SendSSDPNotifies2(int * sockets,
|
SendSSDPNotifies2(int * sockets,
|
||||||
unsigned short port,
|
unsigned short port,
|
||||||
unsigned int lifetime);
|
unsigned int lifetime);
|
||||||
/*SendSSDPNotifies2(int * sockets, struct lan_addr_s * lan_addr, int n_lan_addr,
|
|
||||||
unsigned short port,
|
|
||||||
unsigned int lifetime);*/
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ProcessSSDPRequest(int s, unsigned short port);
|
ProcessSSDPRequest(int s, unsigned short port);
|
||||||
/*ProcessSSDPRequest(int s, struct lan_addr_s * lan_addr, int n_lan_addr,
|
|
||||||
unsigned short port);*/
|
|
||||||
|
|
||||||
int
|
int
|
||||||
SendSSDPGoodbye(int * sockets, int n);
|
SendSSDPGoodbye(int * sockets, int n);
|
||||||
|
@ -61,7 +61,8 @@ static const struct {
|
|||||||
{ UPNPMINISSDPDSOCKET, "minissdpdsocket"},
|
{ UPNPMINISSDPDSOCKET, "minissdpdsocket"},
|
||||||
{ ENABLE_TIVO, "enable_tivo" },
|
{ ENABLE_TIVO, "enable_tivo" },
|
||||||
{ ENABLE_DLNA_STRICT, "strict_dlna" },
|
{ ENABLE_DLNA_STRICT, "strict_dlna" },
|
||||||
{ ROOT_CONTAINER, "root_container" }
|
{ ROOT_CONTAINER, "root_container" },
|
||||||
|
{ USER_ACCOUNT, "user" }
|
||||||
};
|
};
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -54,7 +54,8 @@ enum upnpconfigoptions {
|
|||||||
UPNPMINISSDPDSOCKET, /* minissdpdsocket */
|
UPNPMINISSDPDSOCKET, /* minissdpdsocket */
|
||||||
ENABLE_TIVO, /* enable support for streaming images and music to TiVo */
|
ENABLE_TIVO, /* enable support for streaming images and music to TiVo */
|
||||||
ENABLE_DLNA_STRICT, /* strictly adhere to DLNA specs */
|
ENABLE_DLNA_STRICT, /* strictly adhere to DLNA specs */
|
||||||
ROOT_CONTAINER /* root ObjectID (instead of "0") */
|
ROOT_CONTAINER, /* root ObjectID (instead of "0") */
|
||||||
|
USER_ACCOUNT /* user account to run as */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* readoptionsfile()
|
/* readoptionsfile()
|
||||||
|
@ -62,7 +62,7 @@ time_t startup_time = 0;
|
|||||||
struct runtime_vars_s runtime_vars;
|
struct runtime_vars_s runtime_vars;
|
||||||
uint32_t runtime_flags = INOTIFY_MASK;
|
uint32_t runtime_flags = INOTIFY_MASK;
|
||||||
|
|
||||||
const char * pidfilename = "/var/run/minidlna.pid";
|
const char * pidfilename = "/var/run/minidlna/minidlna.pid";
|
||||||
|
|
||||||
char uuidvalue[] = "uuid:00000000-0000-0000-0000-000000000000";
|
char uuidvalue[] = "uuid:00000000-0000-0000-0000-000000000000";
|
||||||
char modelname[MODELNAME_MAX_LEN] = ROOTDEV_MODELNAME;
|
char modelname[MODELNAME_MAX_LEN] = ROOTDEV_MODELNAME;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user