merge new-rend-branch
This commit is contained in:
parent
41021a3a94
commit
10f7ca1790
|
@ -29,7 +29,7 @@ endif
|
|||
mt_daapd_SOURCES = main.c daapd.h rend.h uici.c uici.h webserver.c \
|
||||
webserver.h configfile.c configfile.h err.c err.h restart.c restart.h \
|
||||
daap-proto.c daap-proto.h daap.c daap.h db-memory.c db-memory.h \
|
||||
mp3-scanner.h mp3-scanner.c playlist.c playlist.h \
|
||||
mp3-scanner.h mp3-scanner.c playlist.c playlist.h rend-unix.c rend-unix.h \
|
||||
lexer.l parser.y $(RENDSRC) $(STRCASESTR) $(STRSEP)
|
||||
|
||||
EXTRA_DIST = mdns/mDNS.c mdns/mDNSClientAPI.h mdns/mDNSDebug.h mdns/mDNSPosix.c \
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
|
@ -51,7 +52,9 @@ void config_emit_ispage(WS_CONNINFO *pwsc, void *value, char *arg);
|
|||
void config_emit_session_count(WS_CONNINFO *pwsc, void *value, char *arg);
|
||||
void config_emit_service_status(WS_CONNINFO *pwsc, void *value, char *arg);
|
||||
void config_emit_user(WS_CONNINFO *pwsc, void *value, char *arg);
|
||||
void config_emit_readonly(WS_CONNINFO *pwsc, void *value, char *arg);
|
||||
void config_subst_stream(WS_CONNINFO *pwsc, int fd_src);
|
||||
int config_file_is_readonly(void);
|
||||
int config_mutex_lock(void);
|
||||
int config_mutex_unlock(void);
|
||||
|
||||
|
@ -89,6 +92,7 @@ CONFIGELEMENT config_elements[] = {
|
|||
{ 0,0,0,CONFIG_TYPE_SPECIAL,"session-count",(void*)NULL,config_emit_session_count },
|
||||
{ 0,0,0,CONFIG_TYPE_SPECIAL,"service-status",(void*)NULL,config_emit_service_status },
|
||||
{ 0,0,0,CONFIG_TYPE_SPECIAL,"user",(void*)NULL,config_emit_user },
|
||||
{ 0,0,0,CONFIG_TYPE_SPECIAL,"readonly",(void*)NULL,config_emit_readonly },
|
||||
{ -1,1,0,CONFIG_TYPE_STRING,NULL,NULL,NULL }
|
||||
};
|
||||
|
||||
|
@ -240,7 +244,7 @@ void config_close(void) {
|
|||
pce=config_elements;
|
||||
err=0;
|
||||
while((pce->config_element != -1)) {
|
||||
if((pce->config_element) && (pce->type == CONFIG_TYPE_STRING))
|
||||
if((pce->config_element) && (pce->type == CONFIG_TYPE_STRING) && (*((char**)pce->var)))
|
||||
free(*((char**)pce->var));
|
||||
pce++;
|
||||
}
|
||||
|
@ -250,7 +254,32 @@ void config_close(void) {
|
|||
* config_write
|
||||
*
|
||||
*/
|
||||
int config_write(CONFIG *pconfig) {
|
||||
int config_write(WS_CONNINFO *pwsc) {
|
||||
FILE *configfile;
|
||||
char ctime_buf[27];
|
||||
time_t now;
|
||||
|
||||
configfile=fopen(config.configfile,"w");
|
||||
if(!configfile)
|
||||
return -1;
|
||||
|
||||
now=time(NULL);
|
||||
ctime_r(&now,ctime_buf);
|
||||
fprintf(configfile,"#\n# mt-daapd.conf\n#\n");
|
||||
fprintf(configfile,"# Edited: %s",ctime_buf);
|
||||
fprintf(configfile,"# By: %s\n",ws_getvar(pwsc,"HTTP_USER"));
|
||||
fprintf(configfile,"#\n");
|
||||
|
||||
fprintf(configfile,"web_root\t%s\n",ws_getvar(pwsc,"web_root"));
|
||||
fprintf(configfile,"port\t\t%s\n",ws_getvar(pwsc,"port"));
|
||||
fprintf(configfile,"admin_pw\t%s\n",ws_getvar(pwsc,"admin_pw"));
|
||||
fprintf(configfile,"mp3_dir\t\t%s\n",ws_getvar(pwsc,"mp3_dir"));
|
||||
fprintf(configfile,"servername\t%s\n",ws_getvar(pwsc,"servername"));
|
||||
fprintf(configfile,"runas\t\t%s\n",ws_getvar(pwsc,"runas"));
|
||||
fprintf(configfile,"playlist\t%s\n",ws_getvar(pwsc,"playlist"));
|
||||
fprintf(configfile,"password\t%s\n",ws_getvar(pwsc,"password"));
|
||||
|
||||
fclose(configfile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -377,22 +406,30 @@ void config_handler(WS_CONNINFO *pwsc) {
|
|||
|
||||
if(strcasecmp(pwsc->uri,"/config-update.html")==0) {
|
||||
/* we need to update stuff */
|
||||
pw=ws_getvar(pwsc,"adminpw");
|
||||
pw=ws_getvar(pwsc,"admin_pw");
|
||||
if(pw) {
|
||||
if(config.adminpassword)
|
||||
free(config.adminpassword);
|
||||
config.adminpassword=strdup(pw);
|
||||
}
|
||||
|
||||
pw=ws_getvar(pwsc,"password");
|
||||
if(pw) {
|
||||
if(config.readpassword)
|
||||
free(config.readpassword);
|
||||
config.readpassword=strdup(pw);
|
||||
}
|
||||
|
||||
if(!config_file_is_readonly()) {
|
||||
DPRINTF(ERR_INFO,"Updating config file\n");
|
||||
config_write(pwsc);
|
||||
}
|
||||
|
||||
|
||||
pw=ws_getvar(pwsc,"action");
|
||||
if(pw) {
|
||||
if(strcasecmp(pw,"stopmdns")==0) {
|
||||
DPRINTF(ERR_INFO,"Stopping rendezvous daemon\n");
|
||||
kill(config.rend_pid,SIGINT);
|
||||
wait(&status);
|
||||
} else if (strcasecmp(pw,"startmdns")==0) {
|
||||
rend_init(&config.rend_pid,config.servername, config.port);
|
||||
} else if (strcasecmp(pw,"stopdaap")==0) {
|
||||
/* ignore stopmdns and startmdns */
|
||||
if (strcasecmp(pw,"stopdaap")==0) {
|
||||
config.stop=1;
|
||||
}
|
||||
}
|
||||
|
@ -426,7 +463,8 @@ int config_auth(char *user, char *password) {
|
|||
* write a simple string value to the connection
|
||||
*/
|
||||
void config_emit_string(WS_CONNINFO *pwsc, void *value, char *arg) {
|
||||
ws_writefd(pwsc,"%s",*((char**)value));
|
||||
if(*((char**)value))
|
||||
ws_writefd(pwsc,"%s",*((char**)value));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -464,10 +502,8 @@ void config_emit_service_status(WS_CONNINFO *pwsc, void *value, char *arg) {
|
|||
|
||||
ws_writefd(pwsc,"<TR><TD>Rendezvous</TD>");
|
||||
if(config.use_mdns) {
|
||||
mdns_running=1;
|
||||
err=waitpid(config.rend_pid,&status,WNOHANG);
|
||||
if(err == -1)
|
||||
mdns_running=0;
|
||||
mdns_running=!rend_running();
|
||||
|
||||
if(mdns_running) {
|
||||
html="<a href=\"config-update.html?action=stopmdns\">Stop MDNS responder</a>";
|
||||
} else {
|
||||
|
@ -622,6 +658,33 @@ void config_emit_user(WS_CONNINFO *pwsc, void *value, char *arg) {
|
|||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* config_file_is_readonly
|
||||
*
|
||||
* See if the configfile is writable or not
|
||||
*/
|
||||
int config_file_is_readonly(void) {
|
||||
FILE *fin;
|
||||
|
||||
fin=fopen(config.configfile,"r+");
|
||||
if(!fin) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
fclose(fin);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* config_emit_readonly
|
||||
*
|
||||
*/
|
||||
void config_emit_readonly(WS_CONNINFO *pwsc, void *value, char *arg) {
|
||||
if(config_file_is_readonly()) {
|
||||
ws_writefd(pwsc,"READONLY");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* config_emit_include
|
||||
*
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#include "webserver.h"
|
||||
|
||||
extern int config_read(char *file);
|
||||
extern int config_write(CONFIG *pconfig);
|
||||
extern int config_write(WS_CONNINFO *pwsc);
|
||||
extern int config_auth(char *user, char *password);
|
||||
extern void config_handler(WS_CONNINFO *pwsc);
|
||||
extern void config_set_status(WS_CONNINFO *pwsc, int session, char *fmt, ...);
|
||||
|
|
|
@ -30,7 +30,6 @@ typedef struct tag_songentry {
|
|||
} SONGENTRY;
|
||||
|
||||
typedef struct tag_config {
|
||||
pid_t rend_pid;
|
||||
int use_mdns;
|
||||
int stop;
|
||||
char *configfile;
|
||||
|
@ -48,4 +47,7 @@ typedef struct tag_config {
|
|||
|
||||
extern CONFIG config;
|
||||
|
||||
/* Forwards */
|
||||
extern drop_privs(char *user);
|
||||
|
||||
#endif /* _DAAPD_H_ */
|
||||
|
|
67
src/main.c
67
src/main.c
|
@ -373,6 +373,39 @@ void usage(char *program) {
|
|||
printf("\n\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* drop_privs
|
||||
*
|
||||
* drop privs to a specific user
|
||||
*/
|
||||
int drop_privs(char *user) {
|
||||
int err;
|
||||
struct passwd *pw=NULL;
|
||||
|
||||
/* drop privs */
|
||||
if(getuid() == (uid_t)0) {
|
||||
pw=getpwnam(config.runas);
|
||||
if(pw) {
|
||||
if(initgroups(user,pw->pw_gid) != 0 ||
|
||||
setgid(pw->pw_gid) != 0 ||
|
||||
setuid(pw->pw_uid) != 0) {
|
||||
err=errno;
|
||||
fprintf(stderr,"Couldn't change to %s, gid=%d, uid=%d\n",
|
||||
user,pw->pw_gid, pw->pw_uid);
|
||||
errno=err;
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
err=errno;
|
||||
fprintf(stderr,"Couldn't lookup user %s\n",user);
|
||||
errno=err;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int option;
|
||||
char *configfile=DEFAULT_CONFIGFILE;
|
||||
|
@ -384,7 +417,6 @@ int main(int argc, char *argv[]) {
|
|||
int parseonly=0;
|
||||
int foreground=0;
|
||||
config.use_mdns=1;
|
||||
struct passwd *pw=NULL;
|
||||
|
||||
#ifdef DEBUG
|
||||
char *optval="d:c:mpf";
|
||||
|
@ -443,26 +475,18 @@ int main(int argc, char *argv[]) {
|
|||
|
||||
if((config.use_mdns) && (!parseonly)) {
|
||||
fprintf(stderr,"Starting rendezvous daemon\n");
|
||||
rend_init(&config.rend_pid,config.servername, config.port, config.runas);
|
||||
}
|
||||
|
||||
/* drop privs */
|
||||
if(getuid() == (uid_t)0) {
|
||||
pw=getpwnam(config.runas);
|
||||
if(pw) {
|
||||
if(initgroups(config.runas,pw->pw_gid) != 0 ||
|
||||
setgid(pw->pw_gid) != 0 ||
|
||||
setuid(pw->pw_uid) != 0) {
|
||||
fprintf(stderr,"Couldn't change to %s, gid=%d, uid=%d\n",
|
||||
config.runas,pw->pw_gid, pw->pw_uid);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr,"Couldn't lookup user %s\n",config.runas);
|
||||
if(rend_init(config.runas)) {
|
||||
perror("rend_init");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
// Drop privs here
|
||||
if(drop_privs(config.runas)) {
|
||||
perror("drop_privs");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
DPRINTF(ERR_DEBUG,"Initializing database\n");
|
||||
|
||||
/* Initialize the database before starting */
|
||||
|
@ -512,6 +536,12 @@ int main(int argc, char *argv[]) {
|
|||
ws_registerhandler(server,"^/logout$",daap_handler,daap_auth,0);
|
||||
ws_registerhandler(server,"^/databases/.*",daap_handler,daap_auth,0);
|
||||
|
||||
if(config.use_mdns) { /* register services */
|
||||
DPRINTF(ERR_DEBUG,"Registering rendezvous names\n");
|
||||
rend_register(config.servername,"_daap._tcp",config.port);
|
||||
rend_register(config.servername,"_http._tcp",config.port);
|
||||
}
|
||||
|
||||
config.stop=0;
|
||||
|
||||
while(!config.stop)
|
||||
|
@ -519,8 +549,7 @@ int main(int argc, char *argv[]) {
|
|||
|
||||
if(config.use_mdns) {
|
||||
if(foreground) fprintf(stderr,"Killing rendezvous daemon\n");
|
||||
kill(config.rend_pid,SIGINT);
|
||||
wait(&status);
|
||||
rend_stop();
|
||||
}
|
||||
|
||||
if(foreground) fprintf(stderr,"Stopping webserver\n");
|
||||
|
|
|
@ -261,7 +261,7 @@ int scan_init(char *path) {
|
|||
int scan_foreground(char *path) {
|
||||
MP3FILE mp3file;
|
||||
DIR *current_dir;
|
||||
struct dirent de;
|
||||
char de[sizeof(struct dirent) + MAXNAMLEN + 1]; /* overcommit for solaris */
|
||||
struct dirent *pde;
|
||||
int err;
|
||||
char mp3_path[PATH_MAX];
|
||||
|
@ -276,9 +276,9 @@ int scan_foreground(char *path) {
|
|||
}
|
||||
|
||||
while(1) {
|
||||
pde=&de;
|
||||
pde=(struct dirent *)&de;
|
||||
|
||||
err=readdir_r(current_dir,&de,&pde);
|
||||
err=readdir_r(current_dir,(struct dirent *)de,&pde);
|
||||
if(err == -1) {
|
||||
DPRINTF(ERR_DEBUG,"Error on readdir_r: %s\n",strerror(errno));
|
||||
err=errno;
|
||||
|
@ -290,28 +290,28 @@ int scan_foreground(char *path) {
|
|||
if(!pde)
|
||||
break;
|
||||
|
||||
if(de.d_name[0] == '.') /* skip hidden and directories */
|
||||
if(pde->d_name[0] == '.') /* skip hidden and directories */
|
||||
continue;
|
||||
|
||||
sprintf(mp3_path,"%s/%s",path,de.d_name);
|
||||
sprintf(mp3_path,"%s/%s",path,pde->d_name);
|
||||
DPRINTF(ERR_DEBUG,"Found %s\n",mp3_path);
|
||||
if(stat(mp3_path,&sb)) {
|
||||
DPRINTF(ERR_WARN,"Error statting: %s\n",strerror(errno));
|
||||
}
|
||||
|
||||
if(sb.st_mode & S_IFDIR) { /* dir -- recurse */
|
||||
DPRINTF(ERR_DEBUG,"Found dir %s... recursing\n",de.d_name);
|
||||
DPRINTF(ERR_DEBUG,"Found dir %s... recursing\n",pde->d_name);
|
||||
scan_foreground(mp3_path);
|
||||
} else {
|
||||
DPRINTF(ERR_DEBUG,"Processing file\n");
|
||||
/* process the file */
|
||||
if(strlen(de.d_name) > 4) {
|
||||
if(strcasecmp(".m3u",(char*)&de.d_name[strlen(de.d_name) - 4]) == 0) {
|
||||
if(strlen(pde->d_name) > 4) {
|
||||
if(strcasecmp(".m3u",(char*)&pde->d_name[strlen(pde->d_name) - 4]) == 0) {
|
||||
/* we found an m3u file */
|
||||
|
||||
DPRINTF(ERR_DEBUG,"Found m3u: %s\n",de.d_name);
|
||||
strcpy(m3u_path,de.d_name);
|
||||
m3u_path[strlen(de.d_name) - 4] = '\0';
|
||||
DPRINTF(ERR_DEBUG,"Found m3u: %s\n",pde->d_name);
|
||||
strcpy(m3u_path,pde->d_name);
|
||||
m3u_path[strlen(pde->d_name) - 4] = '\0';
|
||||
playlistid=sb.st_ino;
|
||||
fd=open(mp3_path,O_RDONLY);
|
||||
if(fd != -1) {
|
||||
|
@ -344,13 +344,13 @@ int scan_foreground(char *path) {
|
|||
}
|
||||
close(fd);
|
||||
}
|
||||
} else if(strcasecmp(".mp3",(char*)&de.d_name[strlen(de.d_name) - 4]) == 0) {
|
||||
} else if(strcasecmp(".mp3",(char*)&pde->d_name[strlen(pde->d_name) - 4]) == 0) {
|
||||
/* we found an mp3 file */
|
||||
DPRINTF(ERR_DEBUG,"Found mp3: %s\n",de.d_name);
|
||||
DPRINTF(ERR_DEBUG,"Found mp3: %s\n",pde->d_name);
|
||||
|
||||
memset((void*)&mp3file,0,sizeof(mp3file));
|
||||
mp3file.path=mp3_path;
|
||||
mp3file.fname=de.d_name;
|
||||
mp3file.fname=pde->d_name;
|
||||
|
||||
#ifdef MAC /* wtf is this about? */
|
||||
mp3file.mtime=sb.st_mtimespec.tv_sec;
|
||||
|
@ -371,7 +371,7 @@ int scan_foreground(char *path) {
|
|||
db_add(&mp3file);
|
||||
pl_eval(&mp3file);
|
||||
} else {
|
||||
DPRINTF(ERR_INFO,"Skipping %s\n",de.d_name);
|
||||
DPRINTF(ERR_INFO,"Skipping %s\n",pde->d_name);
|
||||
}
|
||||
|
||||
scan_freetags(&mp3file);
|
||||
|
|
144
src/rend-howl.c
144
src/rend-howl.c
|
@ -26,9 +26,17 @@
|
|||
#include <sys/types.h>
|
||||
#include <rendezvous/rendezvous.h>
|
||||
#include <salt/log.h>
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#include "err.h"
|
||||
#include "rend-unix.h"
|
||||
|
||||
pthread_t rend_tid;
|
||||
sw_rendezvous rend_handle;
|
||||
|
||||
/* Forwards */
|
||||
void *rend_pipe_monitor(void* arg);
|
||||
void rend_callback(void);
|
||||
|
||||
/*
|
||||
* rend_howl_reply
|
||||
|
@ -53,57 +61,113 @@ static sw_result rend_howl_reply(sw_rendezvous_publish_handler handler,
|
|||
|
||||
|
||||
/*
|
||||
* public interface
|
||||
* rend_private_init
|
||||
*
|
||||
* Initialize howl and start runloop
|
||||
*/
|
||||
int rend_init(pid_t *pid, char *name, int port, char *user) {
|
||||
sw_rendezvous rendezvous;
|
||||
int rend_private_init(char *user) {
|
||||
sw_result result;
|
||||
sw_rendezvous_publish_id daap_id;
|
||||
sw_rendezvous_publish_id http_id;
|
||||
struct passwd *pw=NULL;
|
||||
|
||||
/* drop privs */
|
||||
if(getuid() == (uid_t)0) {
|
||||
pw=getpwnam(user);
|
||||
if(pw) {
|
||||
if(initgroups(user,pw->pw_gid) != 0 ||
|
||||
setgid(pw->pw_gid) != 0 ||
|
||||
setuid(pw->pw_uid) != 0) {
|
||||
fprintf(stderr,"Couldn't change to %s, gid=%d, uid=%d\n",
|
||||
user,pw->pw_gid, pw->pw_uid);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr,"Couldn't lookup user %s\n",user);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(sw_rendezvous_init(&rendezvous) != SW_OKAY) {
|
||||
DPRINTF(ERR_DEBUG,"Starting rendezvous services\n");
|
||||
|
||||
if(sw_rendezvous_init(&rend_handle) != SW_OKAY) {
|
||||
DPRINTF(ERR_WARN,"Error initializing rendezvous\n");
|
||||
errno=EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((result=sw_rendezvous_publish(rendezvous,name,"_daap._tcp",NULL,NULL,port,NULL,NULL,
|
||||
rend_howl_reply,NULL,&daap_id)) != SW_OKAY) {
|
||||
DPRINTF(ERR_WARN,"Error registering DAAP server via mDNS: %d\n",result);
|
||||
if(drop_privs(user))
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((result=sw_rendezvous_publish(rendezvous,name,"_http._tcp",NULL,NULL,port,NULL,NULL,
|
||||
rend_howl_reply,NULL,&http_id)) != SW_OKAY) {
|
||||
DPRINTF(ERR_WARN,"Error registering HTTP server via mDNS: %d\n",result);
|
||||
return -1;
|
||||
}
|
||||
DPRINTF(ERR_DEBUG,"Starting polling thread\n");
|
||||
|
||||
*pid=fork();
|
||||
if(*pid) {
|
||||
return 0;
|
||||
if(pthread_create(&rend_tid,NULL,rend_pipe_monitor,NULL)) {
|
||||
DPRINTF(ERR_FATAL,"Could not start thread. Terminating\n");
|
||||
/* should kill parent, too */
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
DPRINTF(ERR_DEBUG,"Registered rendezvous services\n");
|
||||
sw_rendezvous_run(rendezvous);
|
||||
DPRINTF(ERR_DEBUG,"Entering runloop\n");
|
||||
|
||||
sw_rendezvous_run(rend_handle);
|
||||
|
||||
DPRINTF(ERR_DEBUG,"Exiting runloop\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* rend_pipe_monitor
|
||||
*/
|
||||
void *rend_pipe_monitor(void* arg) {
|
||||
fd_set rset;
|
||||
struct timeval tv;
|
||||
int result;
|
||||
|
||||
while(1) {
|
||||
DPRINTF(ERR_DEBUG,"Waiting for data\n");
|
||||
FD_ZERO(&rset);
|
||||
FD_SET(rend_pipe_to[RD_SIDE],&rset);
|
||||
|
||||
/* sit in a select spin until there is data on the to fd */
|
||||
while(((result=select(rend_pipe_to[RD_SIDE] + 1,&rset,NULL,NULL,NULL)) != -1) &&
|
||||
errno != EINTR) {
|
||||
if(FD_ISSET(rend_pipe_to[RD_SIDE],&rset)) {
|
||||
DPRINTF(ERR_DEBUG,"Received a message from daap server\n");
|
||||
rend_callback();
|
||||
}
|
||||
}
|
||||
|
||||
DPRINTF(ERR_DEBUG,"Select error!\n");
|
||||
/* should really bail here */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* rend_callback
|
||||
*
|
||||
* This gets called from the main thread when there is a
|
||||
* message waiting to be processed.
|
||||
*/
|
||||
void rend_callback(void) {
|
||||
REND_MESSAGE msg;
|
||||
sw_rendezvous_publish_id rend_id;
|
||||
sw_result result;
|
||||
|
||||
/* here, we've seen the message, now we have to process it */
|
||||
|
||||
if(rend_read_message(&msg) != sizeof(msg)) {
|
||||
DPRINTF(ERR_FATAL,"Error reading rendezvous message\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
switch(msg.cmd) {
|
||||
case REND_MSG_TYPE_REGISTER:
|
||||
DPRINTF(ERR_DEBUG,"Registering %s.%s (%d)\n",msg.type,msg.name,msg.port);
|
||||
if((result=sw_rendezvous_publish(rend_handle,msg.name,msg.type,NULL,NULL,msg.port,NULL,0,
|
||||
NULL,rend_howl_reply,NULL,&rend_id)) != SW_OKAY) {
|
||||
DPRINTF(ERR_WARN,"Error registering name\n");
|
||||
rend_send_response(-1);
|
||||
} else {
|
||||
rend_send_response(0); /* success */
|
||||
}
|
||||
break;
|
||||
case REND_MSG_TYPE_UNREGISTER:
|
||||
DPRINTF(ERR_WARN,"Unsupported function: UNREGISTER\n");
|
||||
rend_send_response(-1); /* error */
|
||||
break;
|
||||
case REND_MSG_TYPE_STOP:
|
||||
DPRINTF(ERR_DEBUG,"Stopping mDNS\n");
|
||||
rend_send_response(0);
|
||||
//sw_rendezvous_stop_publish(rend_handle);
|
||||
sw_rendezvous_fina(rend_handle);
|
||||
break;
|
||||
case REND_MSG_TYPE_STATUS:
|
||||
DPRINTF(ERR_DEBUG,"Status inquiry -- returning 0\n");
|
||||
rend_send_response(0); /* success */
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
160
src/rend-osx.c
160
src/rend-osx.c
|
@ -28,24 +28,42 @@
|
|||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#include <DNSServiceDiscovery/DNSServiceDiscovery.h>
|
||||
|
||||
#include "daapd.h"
|
||||
#include "err.h"
|
||||
#include "rend-unix.h"
|
||||
|
||||
CFRunLoopRef rend_runloop;
|
||||
CFRunLoopSourceRef rend_rls;
|
||||
pthread_t rend_tid;
|
||||
|
||||
/* Forwards */
|
||||
void *rend_pipe_monitor(void* arg);
|
||||
|
||||
/*
|
||||
* rend_stoprunloop
|
||||
*/
|
||||
static void rend_stoprunloop(void) {
|
||||
CFRunLoopStop(rend_runloop);
|
||||
}
|
||||
|
||||
/*
|
||||
* rend_sigint
|
||||
*/
|
||||
static void rend_sigint(int sigraised) {
|
||||
DPRINTF(ERR_INFO,"SIGINT\n");
|
||||
rend_stoprunloop();
|
||||
}
|
||||
|
||||
/*
|
||||
* rend_handler
|
||||
*/
|
||||
static void rend_handler(CFMachPortRef port, void *msg, CFIndex size, void *info) {
|
||||
DNSServiceDiscovery_handleReply(msg);
|
||||
}
|
||||
|
||||
/*
|
||||
* rend_addtorunloop
|
||||
*/
|
||||
static int rend_addtorunloop(dns_service_discovery_ref client) {
|
||||
mach_port_t port=DNSServiceDiscoveryMachPort(client);
|
||||
|
||||
|
@ -66,6 +84,9 @@ static int rend_addtorunloop(dns_service_discovery_ref client) {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* rend_reply
|
||||
*/
|
||||
static void rend_reply(DNSServiceRegistrationReplyErrorType errorCode, void *context) {
|
||||
switch(errorCode) {
|
||||
case kDNSServiceDiscoveryNoError:
|
||||
|
@ -81,62 +102,123 @@ static void rend_reply(DNSServiceRegistrationReplyErrorType errorCode, void *con
|
|||
}
|
||||
|
||||
/*
|
||||
* public interface
|
||||
* rend_pipe_monitor
|
||||
*/
|
||||
int rend_init(pid_t *pid, char *name, int port, char *user) {
|
||||
dns_service_discovery_ref daap_ref=NULL;
|
||||
dns_service_discovery_ref http_ref=NULL;
|
||||
unsigned short usPort=port;
|
||||
struct passwd *pw=NULL;
|
||||
|
||||
*pid=fork();
|
||||
if(*pid) {
|
||||
return 0;
|
||||
}
|
||||
void *rend_pipe_monitor(void* arg) {
|
||||
fd_set rset;
|
||||
struct timeval tv;
|
||||
int result;
|
||||
|
||||
|
||||
/* drop privs */
|
||||
if(getuid() == (uid_t)0) {
|
||||
pw=getpwnam(user);
|
||||
if(pw) {
|
||||
if(initgroups(user,pw->pw_gid) != 0 ||
|
||||
setgid(pw->pw_gid) != 0 ||
|
||||
setuid(pw->pw_uid) != 0) {
|
||||
fprintf(stderr,"Couldn't change to %s, gid=%d, uid=%d\n",
|
||||
user,pw->pw_gid, pw->pw_uid);
|
||||
exit(EXIT_FAILURE);
|
||||
while(1) {
|
||||
DPRINTF(ERR_DEBUG,"Waiting for data\n");
|
||||
FD_ZERO(&rset);
|
||||
FD_SET(rend_pipe_to[RD_SIDE],&rset);
|
||||
|
||||
/* sit in a select spin until there is data on the to fd */
|
||||
while(((result=select(rend_pipe_to[RD_SIDE] + 1,&rset,NULL,NULL,NULL)) != -1) &&
|
||||
errno != EINTR) {
|
||||
if(FD_ISSET(rend_pipe_to[RD_SIDE],&rset)) {
|
||||
DPRINTF(ERR_DEBUG,"Received a message from daap server\n");
|
||||
CFRunLoopSourceSignal(rend_rls);
|
||||
CFRunLoopWakeUp(rend_runloop);
|
||||
sleep(1); /* force a reschedule, hopefully */
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr,"Couldn't lookup user %s\n",user);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
DPRINTF(ERR_DEBUG,"Select error!\n");
|
||||
/* should really bail here */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* rend_callback
|
||||
*
|
||||
* This gets called from the main thread when there is a
|
||||
* message waiting to be processed.
|
||||
*/
|
||||
void rend_callback(void *info) {
|
||||
REND_MESSAGE msg;
|
||||
unsigned short usPort;
|
||||
dns_service_discovery_ref dns_ref=NULL;
|
||||
|
||||
/* here, we've seen the message, now we have to process it */
|
||||
|
||||
if(rend_read_message(&msg) != sizeof(msg)) {
|
||||
DPRINTF(ERR_FATAL,"Error reading rendezvous message\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
switch(msg.cmd) {
|
||||
case REND_MSG_TYPE_REGISTER:
|
||||
DPRINTF(ERR_DEBUG,"Registering %s.%s (%d)\n",msg.type,msg.name,msg.port);
|
||||
usPort=msg.port;
|
||||
dns_ref=DNSServiceRegistrationCreate(msg.name,msg.type,"",usPort,"",rend_reply,nil);
|
||||
if(rend_addtorunloop(dns_ref)) {
|
||||
DPRINTF(ERR_WARN,"Add to runloop failed\n");
|
||||
rend_send_response(-1);
|
||||
} else {
|
||||
rend_send_response(0); /* success */
|
||||
}
|
||||
break;
|
||||
case REND_MSG_TYPE_UNREGISTER:
|
||||
DPRINTF(ERR_WARN,"Unsupported function: UNREGISTER\n");
|
||||
rend_send_response(-1); /* error */
|
||||
break;
|
||||
case REND_MSG_TYPE_STOP:
|
||||
DPRINTF(ERR_DEBUG,"Stopping mDNS\n");
|
||||
rend_send_response(0);
|
||||
rend_stoprunloop();
|
||||
break;
|
||||
case REND_MSG_TYPE_STATUS:
|
||||
DPRINTF(ERR_DEBUG,"Status inquiry -- returning 0\n");
|
||||
rend_send_response(0); /* success */
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
signal(SIGINT, rend_sigint); // SIGINT is what you get for a Ctrl-C
|
||||
/*
|
||||
* rend_private_init
|
||||
*
|
||||
* start up the rendezvous services
|
||||
*/
|
||||
int rend_private_init(char *user) {
|
||||
CFRunLoopSourceContext context;
|
||||
|
||||
|
||||
DPRINTF(ERR_DEBUG,"Registering services\n");
|
||||
|
||||
daap_ref=DNSServiceRegistrationCreate(name,"_daap._tcp","",usPort,"",rend_reply,nil);
|
||||
http_ref=DNSServiceRegistrationCreate(name,"_http._tcp","",port,"",rend_reply,nil);
|
||||
|
||||
if(rend_addtorunloop(daap_ref)|| rend_addtorunloop(http_ref)) {
|
||||
DPRINTF(ERR_WARN,"Add to runloop failed\n");
|
||||
if(drop_privs(user)) /* shouldn't be running as root anyway */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* need a sigint handler */
|
||||
DPRINTF(ERR_DEBUG,"Starting rendezvous services\n");
|
||||
|
||||
memset((void*)&context,0,sizeof(context));
|
||||
context.perform = rend_callback;
|
||||
|
||||
rend_runloop = CFRunLoopGetCurrent();
|
||||
rend_rls = CFRunLoopSourceCreate(NULL,0,&context);
|
||||
CFRunLoopAddSource(CFRunLoopGetCurrent(),rend_rls,kCFRunLoopDefaultMode);
|
||||
|
||||
DPRINTF(ERR_DEBUG,"Starting polling thread\n");
|
||||
|
||||
if(pthread_create(&rend_tid,NULL,rend_pipe_monitor,NULL)) {
|
||||
DPRINTF(ERR_FATAL,"Could not start thread. Terminating\n");
|
||||
/* should kill parent, too */
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
DPRINTF(ERR_DEBUG,"Registered rendezvous services\n");
|
||||
DPRINTF(ERR_DEBUG,"Starting runloop\n");
|
||||
|
||||
CFRunLoopRun();
|
||||
|
||||
DPRINTF(ERR_DEBUG,"Exiting runloop\n");
|
||||
|
||||
DNSServiceDiscoveryDeallocate(daap_ref);
|
||||
DNSServiceDiscoveryDeallocate(http_ref);
|
||||
|
||||
exit(0);
|
||||
CFRelease(rend_rls);
|
||||
pthread_cancel(rend_tid);
|
||||
close(rend_pipe_to[RD_SIDE]);
|
||||
close(rend_pipe_from[WR_SIDE]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -89,6 +89,12 @@
|
|||
Change History (most recent first):
|
||||
|
||||
$Log$
|
||||
Revision 1.10 2004/01/20 04:41:20 rpedde
|
||||
merge new-rend-branch
|
||||
|
||||
Revision 1.9.2.1 2004/01/16 20:51:01 rpedde
|
||||
Convert rend-posix to message-based system
|
||||
|
||||
Revision 1.9 2004/01/04 05:02:23 rpedde
|
||||
fix segfault on dropping privs
|
||||
|
||||
|
@ -143,6 +149,8 @@
|
|||
|
||||
#define __IN_ERR__
|
||||
#include "err.h"
|
||||
#include "rend.h"
|
||||
#include "rend-unix.h"
|
||||
|
||||
#pragma mark ***** Globals
|
||||
|
||||
|
@ -549,55 +557,73 @@ static void DeregisterOurServices(void)
|
|||
}
|
||||
}
|
||||
|
||||
#pragma mark **** Main
|
||||
/*
|
||||
* rend_callback
|
||||
*
|
||||
* This is borrowed from the OSX rend client
|
||||
*/
|
||||
void rend_callback(void) {
|
||||
REND_MESSAGE msg;
|
||||
int result;
|
||||
|
||||
int rend_init(pid_t *pid,char *name, int port, char *user) {
|
||||
DPRINTF(ERR_DEBUG,"Processing rendezvous message\n");
|
||||
|
||||
/* here, we've seen the message, now we have to process it */
|
||||
|
||||
if((result=rend_read_message(&msg)) != sizeof(msg)) {
|
||||
DPRINTF(ERR_DEBUG,"Expected %d, got %d\n",sizeof(msg),result);
|
||||
DPRINTF(ERR_FATAL,"Error reading rendezvous message: %s\n",
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
switch(msg.cmd) {
|
||||
case REND_MSG_TYPE_REGISTER:
|
||||
DPRINTF(ERR_DEBUG,"Registering %s.%s (%d)\n",msg.type,msg.name,msg.port);
|
||||
RegisterOneService(msg.name,msg.type,NULL,0,msg.port);
|
||||
rend_send_response(0); /* success */
|
||||
break;
|
||||
case REND_MSG_TYPE_UNREGISTER:
|
||||
rend_send_response(1); /* error */
|
||||
break;
|
||||
case REND_MSG_TYPE_STOP:
|
||||
DPRINTF(ERR_INFO,"Stopping mDNS\n");
|
||||
gStopNow = mDNStrue;
|
||||
rend_send_response(0);
|
||||
break;
|
||||
case REND_MSG_TYPE_STATUS:
|
||||
rend_send_response(1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#pragma mark **** rend_private_init
|
||||
|
||||
int rend_private_init(char *user) {
|
||||
mStatus status;
|
||||
mDNSBool result;
|
||||
struct passwd *pw=NULL;
|
||||
|
||||
status = mDNS_Init(&mDNSStorage, &PlatformStorage,
|
||||
mDNS_Init_NoCache, mDNS_Init_ZeroCacheSize,
|
||||
mDNS_Init_AdvertiseLocalAddresses,
|
||||
mDNS_Init_NoInitCallback, mDNS_Init_NoInitCallbackContext);
|
||||
|
||||
|
||||
if (status != mStatus_NoError) {
|
||||
DPRINTF(ERR_FATAL,"mDNS Error %d\n",status);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
*pid=fork();
|
||||
if(*pid) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* drop privs */
|
||||
if(getuid() == (uid_t)0) {
|
||||
pw=getpwnam(user);
|
||||
if(pw) {
|
||||
if(initgroups(user,pw->pw_gid) != 0 ||
|
||||
setgid(pw->pw_gid) != 0 ||
|
||||
setuid(pw->pw_uid) != 0) {
|
||||
fprintf(stderr,"Couldn't change to %s, gid=%d, uid=%d\n",
|
||||
user,pw->pw_gid, pw->pw_uid);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr,"Couldn't lookup user %s\n",user);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DPRINTF(ERR_DEBUG,"Registering tcp service\n");
|
||||
RegisterOneService(name,"_http._tcp",NULL,0,port);
|
||||
RegisterOneService(name,"_daap._tcp",NULL,0,port);
|
||||
if(drop_privs(user))
|
||||
return -1;
|
||||
|
||||
signal(SIGINT, HandleSigInt); // SIGINT is what you get for a Ctrl-C
|
||||
signal(SIGQUIT, HandleSigQuit); // SIGQUIT is what you get for a Ctrl-\ (indeed)
|
||||
|
||||
|
||||
while (!gStopNow) {
|
||||
int nfds = 0;
|
||||
int nfds = 1;
|
||||
fd_set readfds;
|
||||
struct timeval timeout;
|
||||
int result;
|
||||
|
@ -606,6 +632,7 @@ int rend_init(pid_t *pid,char *name, int port, char *user) {
|
|||
// This example client has no file descriptors of its own,
|
||||
// but a real application would call FD_SET to add them to the set here
|
||||
FD_ZERO(&readfds);
|
||||
FD_SET(rend_pipe_to[RD_SIDE],&readfds);
|
||||
|
||||
// 2. Set up the timeout.
|
||||
// This example client has no other work it needs to be doing,
|
||||
|
@ -632,6 +659,9 @@ int rend_init(pid_t *pid,char *name, int port, char *user) {
|
|||
// 6. This example client has no other work it needs to be doing,
|
||||
// but a real client would do its work here
|
||||
// ... (do work) ...
|
||||
if(FD_ISSET(rend_pipe_to[RD_SIDE],&readfds)) {
|
||||
rend_callback();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -651,3 +681,4 @@ int rend_init(pid_t *pid,char *name, int port, char *user) {
|
|||
exit(result);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,179 @@
|
|||
/*
|
||||
* $Id$
|
||||
* General unix rendezvous routines
|
||||
*
|
||||
* Copyright (C) 2003 Ron Pedde (ron@pedde.com)
|
||||
*
|
||||
* 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "daapd.h"
|
||||
#include "err.h"
|
||||
#include "rend-unix.h"
|
||||
|
||||
int rend_pipe_to[2];
|
||||
int rend_pipe_from[2];
|
||||
int rend_pid;
|
||||
|
||||
#define RD_SIDE 0
|
||||
#define WR_SIDE 1
|
||||
|
||||
/*
|
||||
* rend_init
|
||||
*
|
||||
* Fork and set up message passing system
|
||||
*/
|
||||
int rend_init(char *user) {
|
||||
int err;
|
||||
|
||||
if(pipe((int*)&rend_pipe_to) == -1)
|
||||
return -1;
|
||||
|
||||
if(pipe((int*)&rend_pipe_from) == -1) {
|
||||
err=errno;
|
||||
close(rend_pipe_to[RD_SIDE]);
|
||||
close(rend_pipe_to[WR_SIDE]);
|
||||
errno=err;
|
||||
return -1;
|
||||
}
|
||||
|
||||
rend_pid=fork();
|
||||
if(rend_pid==-1) {
|
||||
err=errno;
|
||||
close(rend_pipe_to[RD_SIDE]);
|
||||
close(rend_pipe_to[WR_SIDE]);
|
||||
close(rend_pipe_from[RD_SIDE]);
|
||||
close(rend_pipe_from[WR_SIDE]);
|
||||
errno=err;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(rend_pid) { /* parent */
|
||||
close(rend_pipe_to[RD_SIDE]);
|
||||
close(rend_pipe_from[WR_SIDE]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* child */
|
||||
close(rend_pipe_to[WR_SIDE]);
|
||||
close(rend_pipe_from[RD_SIDE]);
|
||||
|
||||
/* something bad here... should really signal the parent, rather
|
||||
* than just zombieizing
|
||||
*/
|
||||
rend_private_init(user); /* should only return when terminated */
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* rend_running
|
||||
*
|
||||
* See if the rendezvous daemon is runnig
|
||||
*/
|
||||
int rend_running(void) {
|
||||
REND_MESSAGE msg;
|
||||
int result;
|
||||
|
||||
DPRINTF(ERR_DEBUG,"Status inquiry\n");
|
||||
msg.cmd=REND_MSG_TYPE_STATUS;
|
||||
result=rend_send_message(&msg);
|
||||
DPRINTF(ERR_DEBUG,"Returning status %d\n",result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
*rend_stop
|
||||
*
|
||||
* Stop the rendezvous server
|
||||
*/
|
||||
int rend_stop(void) {
|
||||
REND_MESSAGE msg;
|
||||
|
||||
msg.cmd=REND_MSG_TYPE_STOP;
|
||||
return rend_send_message(&msg);
|
||||
}
|
||||
|
||||
/*
|
||||
* rend_register
|
||||
*
|
||||
* register a rendezvous name
|
||||
*/
|
||||
int rend_register(char *name, char *type, int port) {
|
||||
REND_MESSAGE msg;
|
||||
|
||||
if((strlen(name)+1 > MAX_NAME_LEN) || (strlen(type)+1 > MAX_NAME_LEN)) {
|
||||
DPRINTF(ERR_FATAL,"Registration failed: name or type too long\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
msg.cmd=REND_MSG_TYPE_REGISTER;
|
||||
strcpy(msg.name,name);
|
||||
strcpy(msg.type,type);
|
||||
msg.port=port;
|
||||
|
||||
return rend_send_message(&msg);
|
||||
}
|
||||
|
||||
/*
|
||||
* rend_unregister
|
||||
*
|
||||
* Stop advertising a rendezvous name
|
||||
*/
|
||||
int rend_unregister(char *name, char *type, int port) {
|
||||
return -1; /* not implemented */
|
||||
}
|
||||
|
||||
/*
|
||||
* rend_send_message
|
||||
*
|
||||
* Send a rendezvous message
|
||||
*/
|
||||
int rend_send_message(REND_MESSAGE *pmsg) {
|
||||
int retval;
|
||||
|
||||
if(r_write(rend_pipe_to[WR_SIDE],pmsg,sizeof(REND_MESSAGE)) == -1)
|
||||
return -1;
|
||||
|
||||
if((retval=r_read(rend_pipe_from[RD_SIDE],&retval,sizeof(int)) == -1))
|
||||
return -1;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* rend_read_message
|
||||
*
|
||||
* read the message passed to the rend daemon
|
||||
*/
|
||||
int rend_read_message(REND_MESSAGE *pmsg) {
|
||||
return r_read(rend_pipe_to[RD_SIDE],pmsg,sizeof(REND_MESSAGE));
|
||||
}
|
||||
|
||||
/*
|
||||
* rend_send_response
|
||||
*
|
||||
* Let the rendezvous daemon return a result
|
||||
*/
|
||||
int rend_send_response(int value) {
|
||||
return r_write(rend_pipe_from[WR_SIDE],&value,sizeof(int));
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* $Id$
|
||||
* General unix rendezvous routines
|
||||
*
|
||||
* Copyright (C) 2003 Ron Pedde (ron@pedde.com)
|
||||
*
|
||||
* 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _REND_UNIX_H_
|
||||
#define _REND_UNIX_H_
|
||||
|
||||
#define MAX_NAME_LEN 256
|
||||
|
||||
typedef struct tag_rend_message {
|
||||
int cmd;
|
||||
int port;
|
||||
char name[MAX_NAME_LEN];
|
||||
char type[MAX_NAME_LEN];
|
||||
} REND_MESSAGE;
|
||||
|
||||
#define REND_MSG_TYPE_REGISTER 0
|
||||
#define REND_MSG_TYPE_UNREGISTER 1
|
||||
#define REND_MSG_TYPE_STOP 2
|
||||
#define REND_MSG_TYPE_STATUS 3
|
||||
|
||||
#define RD_SIDE 0
|
||||
#define WR_SIDE 1
|
||||
|
||||
extern int rend_pipe_to[2];
|
||||
extern int rend_pipe_from[2];
|
||||
|
||||
extern int rend_send_message(REND_MESSAGE *pmsg);
|
||||
extern int rend_send_response(int value);
|
||||
extern int rend_private_init(char *user);
|
||||
extern int rend_read_message(REND_MESSAGE *pmsg);
|
||||
|
||||
#endif /* _REND_UNIX_H_ */
|
||||
|
|
@ -22,6 +22,10 @@
|
|||
#ifndef _REND_H_
|
||||
#define _REND_H_
|
||||
|
||||
int rend_init(pid_t *pid, char *name, int port, char *user);
|
||||
extern int rend_init(char *user);
|
||||
extern int rend_running(void);
|
||||
extern int rend_stop(void);
|
||||
extern int rend_register(char *name, char *type, int port);
|
||||
extern int rend_unregister(char *name, char *type, int port);
|
||||
|
||||
#endif /* _REND_H_ */
|
||||
|
|
Loading…
Reference in New Issue