# against the file with absolute path, so to exclude all test directories
# for example use the pattern */test/*
-EXCLUDE_PATTERNS = list.h *.cmdline.* krell.* gui* SFont* write.c gcc-compat.h rc4.h recv.c para.h fade.c config.h sdl_gui.c filter.c slider.c dbadm.c
+EXCLUDE_PATTERNS = list.h *.cmdline.* krell.* gui* SFont* gcc-compat.h rc4.h recv.c para.h fade.c config.h sdl_gui.c filter.c slider.c dbadm.c
# The EXAMPLE_PATH tag can be used to specify one or more files or
# directories that contain example code fragments that are included (see
initialized = 1;
}
cof->fd = fd;
- list_add(&cof->node, &close_on_fork_list);
+ para_list_add(&cof->node, &close_on_fork_list);
}
/** \file command.c does client authentication and executes server commands */
#include <sys/time.h> /* gettimeofday */
-#include "crypt.h"
#include "server.cmdline.h"
#include "db.h"
#include "server.h"
#include "daemon.h"
#include "string.h"
#include "fd.h"
+#include "user_list.h"
static RC4_KEY rc4_recv_key;
static RC4_KEY rc4_send_key;
return (long int) ((max + 0.0) * (random() / (RAND_MAX + 1.0)));
}
-/* Open user_list file, returns pointer to opened file on success,
- * NULL on errors
- */
-static FILE *open_user_list(char *file)
-{
- PARA_DEBUG_LOG("opening user list %s\n", file);
- return fopen(file, "r");
-}
-
-/*
- * lookup user in user_list file. Fills in a user struct containing
- * filename of the user's public key as well as the permissions of that user.
- * Returns 1 on success, 0 if user does not exist and < 0 on errors.
- */
-static int get_user(struct user *user) {
- FILE *file_ptr;
- char *char_ptr;
- char line[MAXLINE];
- /* keyword, user, key, perms */
- char w[MAXLINE], n[MAXLINE], k[MAXLINE], p[MAXLINE], tmp[4][MAXLINE];
- int num, ret;
-
- file_ptr = open_user_list(user_list);
- if (!file_ptr)
- return -E_USERLIST;
- for (;;) {
- ret = para_fgets(line, MAXLINE, file_ptr);
- if (ret < 0)
- PARA_ERROR_LOG("%s\n", PARA_STRERROR(-ret));
- if (ret <= 0)
- break;
- if (sscanf(line,"%200s %200s %200s %200s", w, n, k, p) < 3)
- continue;
- if (strcmp(w, "user") || strcmp(user->name, n))
- continue;
- PARA_DEBUG_LOG("found entry for %s\n", n);
- strcpy(user->name, n);
- strcpy(user->pubkey_file, k);
- user->perms = 0;
- char_ptr = p;
- num = sscanf(char_ptr, "%200[A-Z_],%200[A-Z_],%200[A-Z_],%200[A-Z_]",
- tmp[0], tmp[1], tmp[2], tmp[3]);
- PARA_DEBUG_LOG("found %i perm entries\n", num);
- user->perms = 0;
- while (num > 0) {
- num--;
- if (!strcmp(tmp[num], "AFS_READ"))
- user->perms = user->perms | AFS_READ;
- else if (!strcmp(tmp[num], "AFS_WRITE"))
- user->perms = user->perms | AFS_WRITE;
- else if (!strcmp(tmp[num], "DB_READ"))
- user->perms = user->perms | DB_READ;
- else if (!strcmp(tmp[num], "DB_WRITE"))
- user->perms = user->perms | DB_WRITE;
- else /* unknown permission */
- PARA_WARNING_LOG("unknown permission: %s\n",
- tmp[num]);
- }
- break;
- }
- fclose(file_ptr);
- return ret;
-}
-
static void init_rc4_keys(void)
{
int i;
goto err_out;
if (numbytes < 9 || strncmp(buf, "auth rc4 ", 9))
- strcpy(u.name, buf + 5); /* client version < 0.2.6 */
+ u.name = para_strdup(buf + 5); /* client version < 0.2.6 */
else {
- strcpy(u.name, buf + 9); /* client version >= 0.2.6 */
+ u.name = para_strdup(buf + 9); /* client version >= 0.2.6 */
use_rc4 = 1;
}
-// strcpy(u.name, buf + 5); /* ok, but ugly */
PARA_DEBUG_LOG("received %s request for user %s\n",
use_rc4? "rc4" : "auth", u.name);
- /* lookup user in list file */
- if ((ret = get_user(&u)) < 0)
+ if ((ret = lookup_user(&u)) < 0)
goto err_out;
if (!ret) { /* user not found */
PARA_WARNING_LOG("auth request for unknown user %s\n", u.name);
ret = -E_BAD_USER;
goto err_out;
}
- ret = para_encrypt_challenge(u.pubkey_file, challenge_nr, crypt_buf);
+ ret = para_encrypt_challenge(u.rsa, challenge_nr, crypt_buf);
if (ret <= 0)
goto err_out;
numbytes = ret;
sprintf(buf, "%s", PROCEED_MSG);
if (use_rc4) {
init_rc4_keys();
- ret = para_encrypt_buffer(u.pubkey_file, rc4_buf, 2 * RC4_KEY_LEN,
+ ret = para_encrypt_buffer(u.rsa, rc4_buf, 2 * RC4_KEY_LEN,
(unsigned char *)buf + PROCEED_MSG_LEN + 1);
if (ret <= 0)
goto err_out;
server_cmdline_objs="server.cmdline"
server_errlist_objs="server mp3_afh afs command net string signal random_selector
time daemon stat crypt http_send db close_on_fork playlist_selector
- ipc dccp dccp_send fd"
+ ipc dccp dccp_send fd user_list"
server_ldflags=""
server_audio_formats=" mp3"
/** \file crypt.c openssl-based RSA encryption/decryption routines */
-#include <openssl/pem.h>
#include "para.h"
#include "error.h"
#include "string.h"
-
-/** \cond used to distinguish between loading of private/public key */
-#define LOAD_PUBLIC_KEY 0
-#define LOAD_PRIVATE_KEY 1
-/** \endcond **/
+#include "crypt.h"
static EVP_PKEY *load_key(const char *file, int private)
{
return pkey;
}
-static int get_key(char *key_file, RSA **rsa, int private)
+
+int get_rsa_key(char *key_file, RSA **rsa, int private)
{
EVP_PKEY *key = load_key(key_file, private);
int rsa_inlen)
{
RSA *rsa;
- int ret = get_key(key_file, &rsa, LOAD_PRIVATE_KEY);
+ int ret = get_rsa_key(key_file, &rsa, LOAD_PRIVATE_KEY);
if (ret < 0)
return ret;
/**
* encrypt a buffer using an RSA key
*
- * \param key_file full path of the rsa key
+ * \param rsa: public rsa key
* \param inbuf the input buffer
* \param len the length of \a inbuf
* \param outbuf the output buffer
*
* \sa RSA_public_encrypt(3)
*/
-int para_encrypt_buffer(char *key_file, unsigned char *inbuf,
+int para_encrypt_buffer(RSA *rsa, unsigned char *inbuf,
const unsigned len, unsigned char *outbuf)
{
- RSA *rsa;
- int ret = get_key(key_file, &rsa, LOAD_PUBLIC_KEY);
-
- if (ret < 0)
- return ret;
- ret = RSA_public_encrypt(len, inbuf, outbuf, rsa, RSA_PKCS1_PADDING);
+ int ret = RSA_public_encrypt(len, inbuf, outbuf, rsa,
+ RSA_PKCS1_PADDING);
return ret < 0? -E_ENCRYPT : ret;
}
/**
* encrypt the given challenge number
*
- * \param key_file full path of the rsa key
+ * \param rsa: public rsa key
* \param challenge_nr the number to be encrypted
* \param outbuf the output buffer
*
* \sa para_encrypt_buffer()
*
*/
-int para_encrypt_challenge(char *key_file, long unsigned challenge_nr,
+int para_encrypt_challenge(RSA* rsa, long unsigned challenge_nr,
unsigned char *outbuf)
{
unsigned char *inbuf = (unsigned char*) make_message("%lu", challenge_nr);
- int ret = para_encrypt_buffer(key_file, inbuf, strlen((char *)inbuf), outbuf);
+ int ret = para_encrypt_buffer(rsa, inbuf, strlen((char *)inbuf), outbuf);
free(inbuf);
return ret;
}
+/*
+ * Copyright (C) 2005-2006 Andre Noll <maan@systemlinux.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; 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, USA.
+ */
+
/** \file crypt.h prototypes for the RSA crypt functions */
+
+#include <openssl/pem.h>
int para_decrypt_challenge(char *key_file, long unsigned *challenge_nr,
unsigned char *buf, int rsa_inlen);
-int para_encrypt_challenge(char *key_file, long unsigned challenge_nr,
+int para_encrypt_challenge(RSA* rsa, long unsigned challenge_nr,
unsigned char *outbuf);
-int para_encrypt_buffer(char *key_file, unsigned char *inbuf, const unsigned len,
+int para_encrypt_buffer(RSA* rsa, unsigned char *inbuf, const unsigned len,
unsigned char *outbuf);
int para_decrypt_buffer(char *key_file, unsigned char *outbuf, unsigned char *inbuf,
int rsa_inlen);
+int get_rsa_key(char *key_file, RSA **rsa, int private);
+
+/** \cond used to distinguish between loading of private/public key */
+#define LOAD_PUBLIC_KEY 0
+#define LOAD_PRIVATE_KEY 1
+/** \endcond **/
}
PARA_NOTICE_LOG("connection from %s\n", inet_ntoa(dc->addr.sin_addr));
dc->fd = ret;
- list_add(&dc->node, &clients);
+ para_list_add(&dc->node, &clients);
add_close_on_fork_list(dc->fd);
mark_fd_nonblock(dc->fd);
}
SS_ALSA_WRITE,
SS_FILE_WRITE,
SS_OSX_WRITE,
+ SS_USER_LIST,
NUM_SS
};
extern const char **para_errlist[];
/** \endcond */
+#define USER_LIST_ERRORS \
+ PARA_ERROR(USERLIST, "failed to open user list file"), \
+ PARA_ERROR(BAD_USER, "you don't exist. Go away."), \
+
+
#define OSX_WRITE_ERRORS \
PARA_ERROR(STREAM_FORMAT, "could not set stream format"), \
PARA_ERROR(ADD_CALLBACK, "can not add callback"), \
PARA_ERROR(NO_AUDIO_FILE, "no audio file"), \
PARA_ERROR(BAD_CMD, "invalid command"), \
PARA_ERROR(PERM, "permission denied"), \
- PARA_ERROR(USERLIST, "failed to open user list file"), \
- PARA_ERROR(BAD_USER, "you don't exist. Go away."), \
PARA_ERROR(LOCK, "lock error"), \
PARA_ERROR(SENDER_CMD, "command not supported by this sender"), \
PARA_ERROR(SERVER_CRASH, "para_server crashed -- can not live without it"), \
SS_ENUM(CLIENT);
SS_ENUM(CLIENT_COMMON);
SS_ENUM(AUDIOC);
+SS_ENUM(USER_LIST);
/** \endcond */
#undef PARA_ERROR
/* rest of the world only sees the error text */
#include "error.h"
#include "string.h"
#include "fd.h"
+#include "crypt.h"
/** grab clients that are not yet attached to a filter node */
struct list_head inactive_grab_client_list;
{
PARA_INFO_LOG("adding grab client %p (fd %d) to inactive list\n",
gc, gc->fd);
- list_add(&gc->node, &inactive_grab_client_list);
+ para_list_add(&gc->node, &inactive_grab_client_list);
}
static void gc_free(struct grab_client *gc)
{
PARA_INFO_LOG("activating %p (fd %d, filter node: %p)\n", gc, gc->fd, fn);
list_del(&gc->node);
- list_add(&gc->fcb.node, &fn->callbacks);
+ para_list_add(&gc->fcb.node, &fn->callbacks);
}
/**
PARA_INFO_LOG("accepted client #%d: %s (fd %d)\n", numclients,
CLIENT_ADDR(hc), hc->fd);
numclients++;
- list_add(&hc->node, &clients);
+ para_list_add(&hc->node, &clients);
add_close_on_fork_list(hc->fd);
mark_fd_nonblock(hc->fd);
return;
ai->netmask = scd->netmask;
PARA_INFO_LOG("adding %s/%i to access list\n", inet_ntoa(ai->addr),
ai->netmask);
- list_add(&ai->node, &access_perm_list);
+ para_list_add(&ai->node, &access_perm_list);
}
static int http_com_deny(struct sender_command_data *scd)
}
/**
- * list_add - add a new entry
- * @new: new entry to be added
- * @head: list head to add it after
+ * add a new entry
+ *
+ * \param new: new entry to be added
+ * \param head: list head to add it after
*
* Insert a new entry after the specified head.
* This is good for implementing stacks.
*/
-static inline void list_add(struct list_head *new, struct list_head *head)
+static inline void para_list_add(struct list_head *new, struct list_head *head)
{
__list_add(new, head, head->next);
}
static inline void list_move(struct list_head *list, struct list_head *head)
{
__list_del(list->prev, list->next);
- list_add(list, head);
+ para_list_add(list, head);
}
/**
#include "error.h"
#include "net.h"
#include "string.h"
+#include "user_list.h"
/** pointer to the shared memory area */
extern struct misc_meta_data *mmd;
ot->addr = *addr;
PARA_INFO_LOG("adding to target list (%s:%d)\n",
TARGET_ADDR(ot), ot->port);
- list_add(&ot->node, &targets);
+ para_list_add(&ot->node, &targets);
}
static int ortp_com_add(struct sender_command_data *scd)
#include "net.h"
#include "string.h"
#include "ipc.h"
+#include "user_list.h"
/**
* structure used for transmission of the playlist
PARA_INFO_LOG("registering %s (%p)\n", t->status, t);
if (t->pre_select) {
PARA_DEBUG_LOG("pre_select: %p\n", &t->pre_select);
- list_add(&t->pre_select_node, &pre_select_list);
+ para_list_add(&t->pre_select_node, &pre_select_list);
}
if (t->post_select) {
PARA_DEBUG_LOG("post_select: %p\n", &t->pre_select);
- list_add(&t->post_select_node, &post_select_list);
+ para_list_add(&t->post_select_node, &post_select_list);
}
}
#include "string.h"
#include "ipc.h"
#include "fd.h"
+#include "user_list.h"
/** define the array of error lists needed by para_server */
INIT_SERVER_ERRLISTS;
* senders.
*/
struct server_args_info conf;
-char *user_list = NULL;
+char *user_list_file = NULL;
extern void dccp_send_init(struct sender *);
extern void http_send_init(struct sender *);
extern void ortp_send_init(struct sender *);
cf = conf.config_file_arg;
else
cf = make_message("%s/.paraslash/server.conf", home);
- free(user_list);
+ free(user_list_file);
if (!conf.user_list_given)
- user_list = make_message("%s/.paraslash/server.users", home);
+ user_list_file = make_message("%s/.paraslash/server.users", home);
else
- user_list = para_strdup(conf.user_list_arg);
+ user_list_file = para_strdup(conf.user_list_arg);
ret = stat(cf, &statbuf);
if (ret && conf.config_file_given) {
ret = -1;
free(home);
if (ret > 0)
return;
- free(user_list);
- user_list = NULL;
+ free(user_list_file);
+ user_list_file = NULL;
exit(EXIT_FAILURE);
}
log_welcome("para_server", conf.loglevel_arg);
shm_init(); /* init mmd struct */
server_uptime(UPTIME_SET); /* reset server uptime */
+ init_user_list(user_list_file);
/* become daemon */
if (conf.daemon_given)
daemon_init();
parse_config(1); /* reopens log */
mmd->selector_change = mmd->selector_num; /* do not change selector.. */
change_selector(); /* .. just reload */
+ init_user_list(user_list_file); /* reload user list */
}
static void status_refresh(void)
/** \file server.h common server data structures */
#include "para.h"
-
+#include "list.h"
+#include <openssl/pem.h>
/** size of the selector_info and audio_file info strings of struct misc_meta_data */
#define MMD_INFO_SIZE 16384
-/**
- * permission flags that can be set individually for any server command
- *
- * - DB_READ: command reads from the database
- * - DB_WRITE: command changes the contents of the database
- * - AFS_READ: command reads information about the current audio stream
- * - AFS_WRITE: command changes the current audio stream
- */
-enum {DB_READ = 1, DB_WRITE = 2, AFS_READ = 4, AFS_WRITE = 8};
-
-/**
- * data needed to authenticate the user
- */
-struct user{
-/** the username */
- char name[MAXLINE];
-/** full path to the public RSA key */
- char pubkey_file[_POSIX_PATH_MAX];
-/** the privileges of this user */
- unsigned int perms;
-};
-
/**
* defines one command of para_server
*/
new_client = para_malloc(sizeof(struct stat_client));
new_client->fd = fd;
new_client->item_mask = mask;
- list_add(&new_client->node, &client_list);
+ para_list_add(&new_client->node, &client_list);
dump_stat_client_list();
num_clients++;
return 1;
--- /dev/null
+/*
+ * Copyright (C) 2006 Andre Noll <maan@systemlinux.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; 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, USA.
+ */
+
+/** \file user_list.c user handling for para_server */
+
+#include "para.h"
+#include "error.h"
+#include "fd.h"
+#include "string.h"
+#include "user_list.h"
+
+static struct list_head user_list;
+
+/*
+ * lookup user in user list file. Fills in a user struct containing
+ * filename of the user's public key as well as the permissions of that user.
+ * Returns 1 on success, 0 if user does not exist and < 0 on errors.
+ */
+static void populate_user_list(char *user_list_file)
+{
+ FILE *file_ptr = NULL;
+ char *char_ptr;
+ char line[MAXLINE];
+ /* keyword, user, key, perms */
+ char w[MAXLINE], n[MAXLINE], k[MAXLINE], p[MAXLINE], tmp[4][MAXLINE];
+ int num, ret;
+
+ file_ptr = fopen(user_list_file, "r");
+ ret = -E_USERLIST;
+ if (!file_ptr)
+ goto out;
+ for (;;) {
+ struct user *u;
+ ret = para_fgets(line, MAXLINE, file_ptr);
+ if (ret < 0)
+ PARA_ERROR_LOG("%s\n", PARA_STRERROR(-ret));
+ if (ret <= 0)
+ break;
+ if (sscanf(line,"%200s %200s %200s %200s", w, n, k, p) < 3)
+ continue;
+ if (strcmp(w, "user"))
+ continue;
+ PARA_DEBUG_LOG("found entry for %s\n", n);
+ u = para_malloc(sizeof(struct user));
+ u->name = para_strdup(n);
+ u->rsa = para_malloc(sizeof(RSA));
+ ret = get_rsa_key(k, &u->rsa, LOAD_PUBLIC_KEY);
+ if (ret < 0)
+ break;
+ u->perms = 0;
+ char_ptr = p;
+ num = sscanf(char_ptr, "%200[A-Z_],%200[A-Z_],%200[A-Z_],%200[A-Z_]",
+ tmp[0], tmp[1], tmp[2], tmp[3]);
+ PARA_DEBUG_LOG("found %i perm entries\n", num);
+ u->perms = 0;
+ while (num > 0) {
+ num--;
+ if (!strcmp(tmp[num], "AFS_READ"))
+ u->perms |= AFS_READ;
+ else if (!strcmp(tmp[num], "AFS_WRITE"))
+ u->perms |= AFS_WRITE;
+ else if (!strcmp(tmp[num], "DB_READ"))
+ u->perms |= DB_READ;
+ else if (!strcmp(tmp[num], "DB_WRITE"))
+ u->perms |= DB_WRITE;
+ else /* unknown permission */
+ PARA_WARNING_LOG("unknown permission: %s\n",
+ tmp[num]);
+ }
+ para_list_add(&u->node, &user_list);
+ }
+out:
+ if (file_ptr)
+ fclose(file_ptr);
+ if (ret >= 0)
+ return;
+ PARA_EMERG_LOG("%s\n", PARA_STRERROR(-ret));
+ exit(EXIT_FAILURE);
+}
+
+void init_user_list(char *user_list_file)
+{
+ struct user *u, *tmp;
+ static int initialized;
+
+ if (initialized) {
+ list_for_each_entry_safe(u, tmp, &user_list, node) {
+ list_del(&u->node);
+ free(u->name);
+ free(u->rsa);
+ free(u);
+ }
+ } else
+ INIT_LIST_HEAD(&user_list);
+ initialized = 1;
+ populate_user_list(user_list_file);
+}
+
+/**
+ * lookup user in user_list.
+ *
+ * \param user: must initially contain the name of the user and is filled
+ * in by this function on success.
+ *
+ * \return 1 on success and < 0 on errors.
+ */
+int lookup_user(struct user *user)
+{
+ struct user *u;
+ list_for_each_entry(u, &user_list, node) {
+ if (strcmp(u->name, user->name))
+ continue;
+ *user = *u;
+ return 1;
+ }
+ return -E_BAD_USER;
+}
--- /dev/null
+/*
+ * Copyright (C) 2006 Andre Noll <maan@systemlinux.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; 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, USA.
+ */
+
+/** \file user_list.h exported functions from user_list.c */
+
+#include "list.h"
+#include "crypt.h"
+
+/**
+ * permission flags that can be set individually for any server command
+ *
+ * - DB_READ: command reads from the database
+ * - DB_WRITE: command changes the contents of the database
+ * - AFS_READ: command reads information about the current audio stream
+ * - AFS_WRITE: command changes the current audio stream
+ */
+enum {DB_READ = 1, DB_WRITE = 2, AFS_READ = 4, AFS_WRITE = 8};
+
+/**
+ * data needed to authenticate the user
+ */
+struct user {
+ /** the position of this user in the list of users */
+ struct list_head node;
+ /** the username */
+ char *name;
+ /** the public RSA key */
+ RSA *rsa;
+ /** the privileges that this user has */
+ unsigned int perms;
+};
+
+void init_user_list(char *user_list_file);
+int lookup_user(struct user *user);
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*/
+/** \file write.c Paraslash's standalone wav/raw player */
+
#include "para.h"
#include "string.h"
#include "write.cmdline.h"
INIT_WRITE_ERRLISTS;
+/**
+ * check if given buffer contains a valid wave header
+ */
struct check_wav_task {
+ /** the buffer to check */
char *buf;
+ /** number of bytes loaded in \a buf */
size_t *loaded;
+ /** non-zero if end of file was reached */
int *eof;
+ /** number of channels specified in wav header given by \a buf */
unsigned channels;
+ /** samplerate specified in wav header given by \a buf */
unsigned samplerate;
+ /** the task structure for this task */
struct task task;
};
+/**
+ * delay writing until given time
+ */
struct initial_delay_task {
+ /** the time the first data should be written out */
struct timeval start_time;
+ /** the task structure for this task */
struct task task;
};
static struct write_args_info conf;
-struct stdin_task sit;
-struct check_wav_task cwt;
-struct initial_delay_task idt;
+static struct stdin_task sit;
+static struct check_wav_task cwt;
+static struct initial_delay_task idt;
static struct writer_node_group *wng;
+/** length of a standard wav header */
#define WAV_HEADER_LEN 44
/**
s->timeout = diff;
}
+/**
+ * all log messages are written to stderr
+ *
+ * \param ll: loglevel
+ * \param fmt: format string
+ */
void para_log(int ll, const char* fmt,...)
{
va_list argp;
register_task(&idt.task);
}
+/**
+ * para_write's main function
+ *
+ * It registers the stdin task, the check_wav_task, the task for initial delay
+ * and all tasks for actually writing out the stream.
+ *
+ */
int main(int argc, char *argv[])
{
int ret = -E_WRITE_SYNTAX;