gcc -Wall -g -o lv3_example -pthread example.c -lventrilo3
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <strings.h>
#include <sys/types.h>
#include <string.h>
#include <getopt.h>
#include <pthread.h>
#include <ventrilo3.h>
void usage(char *argv[]);
void ctrl_c(int signum);
void *jukebox_connection(void *connptr);
void *jukebox_player(void *connptr);
int debug = 0;
int should_exit = 0;
struct _conninfo {
char *server;
char *username;
char *password;
char *channelid;
char *path;
};
void ctrl_c (int signum) {
printf("disconnecting... ");
v3_logout();
printf("done\n");
exit(0);
}
void usage(char *argv[]) {
fprintf(stderr, "usage: %s -s hostname:port -u username -c channelid /path/to/music\n", argv[0]);
exit(1);
}
void *jukebox_connection(void *connptr) {
struct _conninfo *conninfo;
_v3_net_message *msg;
conninfo = connptr;
if (debug >= 2) {
v3_debuglevel(V3_DEBUG_ALL);
}
if (! v3_login(conninfo->server, conninfo->username, conninfo->password, "")) {
fprintf(stderr, "could not log in to server: %s\n", _v3_error(NULL));
}
while ((msg = _v3_recv(V3_BLOCK)) != NULL) {
switch (_v3_process_message(msg)) {
case V3_MALFORMED:
_v3_debug(V3_DEBUG_INFO, "received malformed packet");
break;
case V3_NOTIMPL:
_v3_debug(V3_DEBUG_INFO, "packet type not implemented");
break;
case V3_OK:
_v3_debug(V3_DEBUG_INFO, "packet processed");
break;
}
}
should_exit = 1;
pthread_exit(NULL);
}
void *jukebox_player(void *connptr) {
struct _conninfo *conninfo;
v3_event *ev;
conninfo = connptr;
while ((ev = v3_get_event(V3_BLOCK))) {
if (debug) {
fprintf(stderr, "jukebox: got event type %d\n", ev->type);
}
switch (ev->type) {
case V3_EVENT_DISCONNECT:
should_exit = 1;
free(ev);
pthread_exit(NULL);
break;
case V3_EVENT_LOGIN_COMPLETE:
v3_change_channel(atoi(conninfo->channelid), "");
v3_join_chat();
break;
}
free(ev);
}
pthread_exit(NULL);
}
int main(int argc, char *argv[]) {
int opt;
int rc;
pthread_t network;
pthread_t player;
struct _conninfo conninfo;
while ((opt = getopt(argc, argv, "dh:p:u:c:")) != -1) {
switch (opt) {
case 'd':
debug++;
break;
case 'h':
conninfo.server = strdup(optarg);
break;
case 'u':
conninfo.username = strdup(optarg);
break;
case 'c':
conninfo.channelid = strdup(optarg);
break;
case 'p':
conninfo.password = strdup(optarg);
break;
}
}
if (! conninfo.server) {
fprintf(stderr, "error: server hostname (-h) was not specified\n");
usage(argv);
}
if (! conninfo.username) {
fprintf(stderr, "error: username (-u) was not specified\n");
usage(argv);
}
if (! conninfo.channelid) {
fprintf(stderr, "error: channel id (-c) was not specified\n");
usage(argv);
}
if (! conninfo.password) {
conninfo.password = "";
}
if (optind >= argc) {
fprintf(stderr, "error: path to music library not specified\n");
usage(argv);
}
conninfo.path = strdup(argv[argc-1]);
fprintf(stderr, "server: %s\nusername: %s\nmedia path: %s\n", conninfo.server, conninfo.username, conninfo.path);
rc = pthread_create(&network, NULL, jukebox_connection, (void *)&conninfo);
rc = pthread_create(&player, NULL, jukebox_player, (void *)&conninfo);
signal (SIGINT, ctrl_c);
while (! should_exit) {
sleep(1);
}
return(0);
}