static void rdpdr_send_available(void) { uint8 magic[4] = "rDAD"; uint32 driverlen, printerlen, bloblen; int i; STREAM s; PRINTER *printerinfo; s = channel_init(rdpdr_channel, announcedata_size()); out_uint8a(s, magic, 4); out_uint32_le(s, g_num_devices); for (i = 0; i < g_num_devices; i++) { out_uint32_le(s, g_rdpdr_device[i].device_type); out_uint32_le(s, i); /* RDP Device ID */ /* Is it possible to use share names longer than 8 chars? /astrand */ out_uint8p(s, g_rdpdr_device[i].name, 8); switch (g_rdpdr_device[i].device_type) { case DEVICE_TYPE_PRINTER: printerinfo = (PRINTER *) g_rdpdr_device[i].pdevice_data; driverlen = 2 * strlen(printerinfo->driver) + 2; printerlen = 2 * strlen(printerinfo->printer) + 2; bloblen = printerinfo->bloblen; out_uint32_le(s, 24 + driverlen + printerlen + bloblen); /* length of extra info */ out_uint32_le(s, printerinfo->default_printer ? 2 : 0); out_uint8s(s, 8); /* unknown */ out_uint32_le(s, driverlen); out_uint32_le(s, printerlen); out_uint32_le(s, bloblen); rdp_out_unistr(s, printerinfo->driver, driverlen - 2); rdp_out_unistr(s, printerinfo->printer, printerlen - 2); out_uint8a(s, printerinfo->blob, bloblen); if (printerinfo->blob) xfree(printerinfo->blob); /* Blob is sent twice if reconnecting */ break; default: out_uint32(s, 0); } } #if 0 out_uint32_le(s, 0x20); /* Device type 0x20 - smart card */ out_uint32_le(s, 0); out_uint8p(s, "SCARD", 5); out_uint8s(s, 3); out_uint32(s, 0); #endif s_mark_end(s); channel_send(s, rdpdr_channel); }
static STREAM rdpsnd_init_packet(uint16 type, uint16 size) { STREAM s; s = channel_init(rdpsnd_channel, size + 4); out_uint16_le(s, type); out_uint16_le(s, size); return s; }
static STREAM rdpusb_init_packet(uint32 len, uint8 code) { STREAM s; s = channel_init(rdpusb_channel, len + 5); out_uint32_le (s, len + sizeof (code)); /* The length of data after the 'len' field. */ out_uint8(s, code); return s; }
static STREAM rdpsnd_init_packet(uint8 type, uint16 size) { STREAM s; s = channel_init(rdpsnd_channel, size + 4); out_uint8(s, type); out_uint8(s, 0); /* protocol-mandated padding */ out_uint16_le(s, size); return s; }
int main() { int sockfd, newsockfd; socklen_t clilen; struct sockaddr_in serv_addr, client_addr; channel_init(&defaultChannel); strcpy(defaultChannel.alias, DEFAULT_CHANNEL_ALIAS); channels_init(&channels); channels_insert(&channels, &defaultChannel); if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) printf("ERROR opening socket"); serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(PORT); serv_addr.sin_addr.s_addr = INADDR_ANY; bzero(&(serv_addr.sin_zero), 8); if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) printf("ERROR on binding"); listen(sockfd, MAX_USERS); while(1) { clilen = sizeof(struct sockaddr_in); if((newsockfd = accept(sockfd, (struct sockaddr *)&client_addr, (socklen_t*)&clilen)) == -1) { fprintf(stderr, "accept() failed...\n"); return -1; } else { if(defaultChannel.size == MAX_USERS) { fprintf(stderr, "Connection full, request rejected...\n"); continue; } printf("Connection requested received...\n"); struct USER user; user_init(&user); user.socketfd = newsockfd; strcpy(user.alias, "Anonymous"); strcpy(user.channelAlias, DEFAULT_CHANNEL_ALIAS); channel_insert(&channels.head->channel, &user); pthread_create(&user.threadInfo, NULL, client_handler, (void *)&user); } } return 0; }
int cos_init(void) { int i; lock_static_init(&l); torlib_init(); for (i = 0 ; i < COS_TRANS_SERVICE_MAX ; i++) { channel_init(i); } return 0; }
struct channel *network_add_channel (struct network *net, const char *channel) { struct network_channel_node *tmp_chan; tmp_chan = malloc(sizeof(struct network_channel_node)); channel_init(&tmp_chan->chan); tmp_chan->chan.name = strdup(channel); tmp_chan->chan.net = net; tmp_chan->next = net->first_channel; net->first_channel = tmp_chan; return &tmp_chan->chan; }
/* Create new ICB channel record */ ICB_CHANNEL_REC *icb_channel_create(ICB_SERVER_REC *server, const char *name, const char *visible_name, int automatic) { ICB_CHANNEL_REC *rec; g_return_val_if_fail(server == NULL || IS_ICB_SERVER(server), NULL); g_return_val_if_fail(name != NULL, NULL); rec = g_new0(ICB_CHANNEL_REC, 1); channel_init((CHANNEL_REC *) rec, (SERVER_REC *) server, name, visible_name, automatic); return rec; }
static int msconf_set_sr(MSFilter *f, void *arg){ ConfState *s=(ConfState*)f->data; int i; s->samplerate = *(int*)arg; s->conf_gran = ((16 * s->samplerate) / 800) *2; s->conf_nsamples=s->conf_gran/2; for (i=0;i<CONF_MAX_PINS;i++) channel_uninit(&s->channels[i]); for (i=0;i<CONF_MAX_PINS;i++) channel_init(s, &s->channels[i], i); return 0; }
static int msconf_enable_halfduplex(MSFilter *f, void *arg){ ConfState *s=(ConfState*)f->data; int i; ms_mutex_lock(&s->lock); s->enable_halfduplex = *(int*)arg; for (i=0;i<CONF_MAX_PINS;i++) channel_uninit(&s->channels[i]); for (i=0;i<CONF_MAX_PINS;i++) channel_init(s, &s->channels[i], i); ms_mutex_unlock(&s->lock); return 0; }
static int msconf_set_vad_prob_continue(MSFilter *f, void *arg){ ConfState *s=(ConfState*)f->data; int i; ms_mutex_lock(&s->lock); s->vad_prob_continue = *(int*)arg; for (i=0;i<CONF_MAX_PINS;i++) channel_uninit(&s->channels[i]); for (i=0;i<CONF_MAX_PINS;i++) channel_init(s, &s->channels[i], i); ms_mutex_unlock(&s->lock); return 0; }
static void conf_postprocess(MSFilter *f){ int i; ConfState *s=(ConfState*)f->data; ms_mutex_lock(&s->lock); for (i=0;i<CONF_MAX_PINS;i++) channel_uninit(&s->channels[i]); for (i=0;i<CONF_MAX_PINS;i++) channel_init(s, &s->channels[i], i); ms_mutex_unlock(&s->lock); }
static void rdpdr_send_connect(RDPCLIENT * This) { uint8 magic[4] = "rDCC"; STREAM s; s = channel_init(This, This->rdpdr.channel, 12); out_uint8a(s, magic, 4); out_uint16_le(s, 1); /* unknown */ out_uint16_le(s, 5); out_uint32_be(s, 0x815ed39d); /* IP address (use 127.0.0.1) 0x815ed39d */ s_mark_end(s); channel_send(This, s, This->rdpdr.channel); }
IRC_CHANNEL_REC *irc_channel_create(IRC_SERVER_REC *server, const char *name, const char *visible_name, int automatic) { IRC_CHANNEL_REC *rec; g_return_val_if_fail(server == NULL || IS_IRC_SERVER(server), NULL); g_return_val_if_fail(name != NULL, NULL); rec = g_new0(IRC_CHANNEL_REC, 1); if (*name == '+') rec->no_modes = TRUE; channel_init((CHANNEL_REC *) rec, (SERVER_REC *) server, name, visible_name, automatic); return rec; }
http_server_t * jukebox_init(int port) { http_server_t *server; encoder_init("mp3", "encoded", 4); song_init(); channel_init(); event_init(); server = http_server_new(port); http_node_new(server, "/stream", on_stream, NULL); http_map_directory(server, "/", "html"); http_server_set_auth_cb(server, auth_session); return server; }
static void cliprdr_send_packet(uint16 type, uint16 status, uint8 * data, uint32 length) { STREAM s; DEBUG_CLIPBOARD(("CLIPRDR send: type=%d, status=%d, length=%d\n", type, status, length)); s = channel_init(cliprdr_channel, length + 12); out_uint16_le(s, type); out_uint16_le(s, status); out_uint32_le(s, length); out_uint8p(s, data, length); out_uint32(s, 0); /* pad? */ s_mark_end(s); channel_send(s, cliprdr_channel); }
IRC_CHANNEL_REC *irc_channel_create(IRC_SERVER_REC *server, const char *name, int automatic) { IRC_CHANNEL_REC *rec; g_return_val_if_fail(server == NULL || IS_IRC_SERVER(server), NULL); g_return_val_if_fail(name != NULL, NULL); rec = g_new0(IRC_CHANNEL_REC, 1); rec->chat_type = IRC_PROTOCOL; rec->name = g_strdup(name); rec->server = server; if (*name == '+') rec->no_modes = TRUE; channel_init((CHANNEL_REC *) rec, automatic); return rec; }
static void conf_init(MSFilter *f){ ConfState *s=(ConfState *)ms_new0(ConfState,1); int i; s->samplerate=8000; s->conf_gran=((16 * s->samplerate) / 800) *2; s->conf_nsamples=s->conf_gran/2; for (i=0;i<CONF_MAX_PINS;i++) channel_init(s, &s->channels[i], i); s->enable_directmode=FALSE; s->enable_vad=TRUE; s->agc_level=0; s->max_gain=30; s->mix_mode=TRUE; s->adaptative_msconf_buf=2; ms_mutex_init(&s->lock,NULL); f->data=s; }
/* Send data to channel */ static void lspci_send(const char *output) { STREAM s; size_t len; len = strlen(output); s = channel_init(lspci_channel, len); out_uint8p(s, output, len) s_mark_end(s); #if 0 printf("lspci send:\n"); hexdump(s->channel_hdr + 8, s->end - s->channel_hdr - 8); #endif channel_send(s, lspci_channel); }
channel_t * new_fake_channel(void) { channel_t *chan = tor_malloc_zero(sizeof(channel_t)); channel_init(chan); chan->close = chan_test_close; chan->num_cells_writeable = chan_test_num_cells_writeable; chan->get_remote_descr = chan_test_get_remote_descr; chan->write_packed_cell = chan_test_write_packed_cell; chan->write_var_cell = chan_test_write_var_cell; chan->state = CHANNEL_STATE_OPEN; chan->cmux = circuitmux_alloc(); circuitmux_set_policy(chan->cmux, &ewma_policy); return chan; }
CHANNEL_REC * muc_create(XMPP_SERVER_REC *server, const char *name, const char *visible_name, int automatic, const char *nick) { MUC_REC *rec; g_return_val_if_fail(IS_XMPP_SERVER(server), NULL); g_return_val_if_fail(name != NULL, NULL); rec = g_new0(MUC_REC, 1); rec->chat_type = XMPP_PROTOCOL; rec->nick = g_strdup((nick != NULL) ? nick : (*settings_get_str("nick") != '\0') ? settings_get_str("nick") : server->user); channel_init((CHANNEL_REC *)rec, SERVER(server), name, visible_name, automatic); rec->get_join_data = (char *(*)(CHANNEL_REC *))get_join_data; return (CHANNEL_REC *)rec; }
void event_init() { // Initialize the event queues deferred_events = kl_init(Event); immediate_events = kl_init(Event); // Initialize input events input_init(); // Timer to wake the event loop if a timeout argument is passed to // `event_poll` // Signals signal_init(); // Jobs job_init(); // Channels channel_init(); // Servers server_init(); }
void event_init(void) { // Initialize the event queues deferred_events = kl_init(Event); immediate_events = kl_init(Event); // early msgpack-rpc initialization msgpack_rpc_init_method_table(); msgpack_rpc_helpers_init(); // Initialize input events input_init(); // Timer to wake the event loop if a timeout argument is passed to // `event_poll` // Signals signal_init(); // Jobs job_init(); // finish mspgack-rpc initialization channel_init(); server_init(); terminal_init(); }
static void rdpdr_send_clientcapabilty(RDPCLIENT * This) { uint8 magic[4] = "rDPC"; STREAM s; s = channel_init(This, This->rdpdr.channel, 0x50); out_uint8a(s, magic, 4); out_uint32_le(s, 5); /* count */ out_uint16_le(s, 1); /* first */ out_uint16_le(s, 0x28); /* length */ out_uint32_le(s, 1); out_uint32_le(s, 2); out_uint16_le(s, 2); out_uint16_le(s, 5); out_uint16_le(s, 1); out_uint16_le(s, 5); out_uint16_le(s, 0xFFFF); out_uint16_le(s, 0); out_uint32_le(s, 0); out_uint32_le(s, 3); out_uint32_le(s, 0); out_uint32_le(s, 0); out_uint16_le(s, 2); /* second */ out_uint16_le(s, 8); /* length */ out_uint32_le(s, 1); out_uint16_le(s, 3); /* third */ out_uint16_le(s, 8); /* length */ out_uint32_le(s, 1); out_uint16_le(s, 4); /* fourth */ out_uint16_le(s, 8); /* length */ out_uint32_le(s, 1); out_uint16_le(s, 5); /* fifth */ out_uint16_le(s, 8); /* length */ out_uint32_le(s, 1); s_mark_end(s); channel_send(This, s, This->rdpdr.channel); }
static void rdpdr_send_completion(RDPCLIENT * This, uint32 device, uint32 id, uint32 status, uint32 result, uint8 * buffer, uint32 length) { uint8 magic[4] = "rDCI"; STREAM s; s = channel_init(This, This->rdpdr.channel, 20 + length); out_uint8a(s, magic, 4); out_uint32_le(s, device); out_uint32_le(s, id); out_uint32_le(s, status); out_uint32_le(s, result); out_uint8p(s, buffer, length); s_mark_end(s); /* JIF */ #ifdef WITH_DEBUG_RDP5 printf("--> rdpdr_send_completion\n"); /* hexdump(s->channel_hdr + 8, s->end - s->channel_hdr - 8); */ #endif channel_send(This, s, This->rdpdr.channel); }
void initialise_sigyn(char *nick, char *ident, char *gecos, char *uplink, char * port, bool use_ssl, char *vhost) { me.client = mowgli_alloc(sizeof(irc_user_t)); me.stats.start = time(NULL); me.stats.inB = 0; me.stats.outB = 0; me.client->nick = nick; me.client->user = ident; me.client->gecos = gecos; me.uplink.port = port; me.uplink.hostname = uplink; me.uplink.ssl = use_ssl; me.uplink.vhost = vhost; me.uplink.connected = false; me.maxfd = 3; modules_init(); queue_init(); command_init(); channel_init(); isupport_table = mowgli_patricia_create(strcasecanon); }
static void rdpdr_send_name(RDPCLIENT * This) { uint8 magic[4] = "rDNC"; STREAM s; uint32 hostlen; if (NULL == This->rdpdr_clientname) { This->rdpdr_clientname = This->hostname; } hostlen = (strlen(This->rdpdr_clientname) + 1) * 2; s = channel_init(This, This->rdpdr.channel, 16 + hostlen); out_uint8a(s, magic, 4); out_uint16_le(s, 0x63); /* unknown */ out_uint16_le(s, 0x72); out_uint32(s, 0); out_uint32_le(s, hostlen); rdp_out_unistr(This, s, This->rdpdr_clientname, hostlen - 2); s_mark_end(s); channel_send(This, s, This->rdpdr.channel); }
static void rdpdr_send_name(void) { uint8 magic[4] = "rDNC"; STREAM s; uint32 hostlen; if (NULL == g_rdpdr_clientname) { g_rdpdr_clientname = g_hostname; } hostlen = (strlen(g_rdpdr_clientname) + 1) * 2; s = channel_init(rdpdr_channel, 16 + hostlen); out_uint8a(s, magic, 4); out_uint16_le(s, 0x63); /* unknown */ out_uint16_le(s, 0x72); out_uint32(s, 0); out_uint32_le(s, hostlen); rdp_out_unistr(s, g_rdpdr_clientname, hostlen - 2); s_mark_end(s); channel_send(s, rdpdr_channel); }
int main(int argc, char **argv) { int i; sigset_t set; #if ENABLE_MPEGTS uint32_t adapter_mask = 0; #endif int log_level = LOG_INFO; int log_options = TVHLOG_OPT_MILLIS | TVHLOG_OPT_STDERR | TVHLOG_OPT_SYSLOG; const char *log_debug = NULL, *log_trace = NULL; gid_t gid = -1; uid_t uid = -1; char buf[512]; FILE *pidfile = NULL; extern int dvb_bouquets_parse; main_tid = pthread_self(); /* Setup global mutexes */ pthread_mutex_init(&fork_lock, NULL); pthread_mutex_init(&global_lock, NULL); pthread_mutex_init(&tasklet_lock, NULL); pthread_mutex_init(&atomic_lock, NULL); pthread_cond_init(>imer_cond, NULL); pthread_cond_init(&tasklet_cond, NULL); TAILQ_INIT(&tasklets); /* Defaults */ tvheadend_webui_port = 9981; tvheadend_webroot = NULL; tvheadend_htsp_port = 9982; tvheadend_htsp_port_extra = 0; time(&dispatch_clock); /* Command line options */ int opt_help = 0, opt_version = 0, opt_fork = 0, opt_firstrun = 0, opt_stderr = 0, opt_syslog = 0, opt_nosyslog = 0, opt_uidebug = 0, opt_abort = 0, opt_noacl = 0, opt_fileline = 0, opt_threadid = 0, opt_libav = 0, opt_ipv6 = 0, opt_satip_rtsp = 0, #if ENABLE_TSFILE opt_tsfile_tuner = 0, #endif opt_dump = 0, opt_xspf = 0, opt_dbus = 0, opt_dbus_session = 0, opt_nobackup = 0, opt_nobat = 0; const char *opt_config = NULL, *opt_user = NULL, *opt_group = NULL, *opt_logpath = NULL, *opt_log_debug = NULL, *opt_log_trace = NULL, *opt_pidpath = "/var/run/tvheadend.pid", #if ENABLE_LINUXDVB *opt_dvb_adapters = NULL, #endif *opt_bindaddr = NULL, *opt_subscribe = NULL, *opt_user_agent = NULL; str_list_t opt_satip_xml = { .max = 10, .num = 0, .str = calloc(10, sizeof(char*)) }; str_list_t opt_tsfile = { .max = 10, .num = 0, .str = calloc(10, sizeof(char*)) }; cmdline_opt_t cmdline_opts[] = { { 0, NULL, N_("Generic Options"), OPT_BOOL, NULL }, { 'h', "help", N_("Show this page"), OPT_BOOL, &opt_help }, { 'v', "version", N_("Show version information"),OPT_BOOL, &opt_version }, { 0, NULL, N_("Service Configuration"), OPT_BOOL, NULL }, { 'c', "config", N_("Alternate config path"), OPT_STR, &opt_config }, { 'B', "nobackup", N_("Don't backup config tree at upgrade"), OPT_BOOL, &opt_nobackup }, { 'f', "fork", N_("Fork and run as daemon"), OPT_BOOL, &opt_fork }, { 'u', "user", N_("Run as user"), OPT_STR, &opt_user }, { 'g', "group", N_("Run as group"), OPT_STR, &opt_group }, { 'p', "pid", N_("Alternate pid path"), OPT_STR, &opt_pidpath }, { 'C', "firstrun", N_("If no user account exists then create one with\n" "no username and no password. Use with care as\n" "it will allow world-wide administrative access\n" "to your Tvheadend installation until you edit/create\n" "access-control from within the Tvheadend UI"), OPT_BOOL, &opt_firstrun }, #if ENABLE_DBUS_1 { 'U', "dbus", N_("Enable DBus"), OPT_BOOL, &opt_dbus }, { 'e', "dbus_session", N_("DBus - use the session message bus instead system one"), OPT_BOOL, &opt_dbus_session }, #endif #if ENABLE_LINUXDVB { 'a', "adapters", N_("Only use specified DVB adapters (comma separated)"), OPT_STR, &opt_dvb_adapters }, #endif #if ENABLE_SATIP_SERVER { 0, "satip_rtsp", N_("SAT>IP RTSP port number for server\n" "(default: -1 = disable, 0 = webconfig, standard port is 554)"), OPT_INT, &opt_satip_rtsp }, #endif #if ENABLE_SATIP_CLIENT { 0, "satip_xml", N_("URL with the SAT>IP server XML location"), OPT_STR_LIST, &opt_satip_xml }, #endif { 0, NULL, N_("Server Connectivity"), OPT_BOOL, NULL }, { '6', "ipv6", N_("Listen on IPv6"), OPT_BOOL, &opt_ipv6 }, { 'b', "bindaddr", N_("Specify bind address"), OPT_STR, &opt_bindaddr}, { 0, "http_port", N_("Specify alternative http port"), OPT_INT, &tvheadend_webui_port }, { 0, "http_root", N_("Specify alternative http webroot"), OPT_STR, &tvheadend_webroot }, { 0, "htsp_port", N_("Specify alternative htsp port"), OPT_INT, &tvheadend_htsp_port }, { 0, "htsp_port2", N_("Specify extra htsp port"), OPT_INT, &tvheadend_htsp_port_extra }, { 0, "useragent", N_("Specify User-Agent header for the http client"), OPT_STR, &opt_user_agent }, { 0, "xspf", N_("Use XSPF playlist instead of M3U"), OPT_BOOL, &opt_xspf }, { 0, NULL, N_("Debug Options"), OPT_BOOL, NULL }, { 'd', "stderr", N_("Enable debug on stderr"), OPT_BOOL, &opt_stderr }, { 's', "syslog", N_("Enable debug to syslog"), OPT_BOOL, &opt_syslog }, { 'S', "nosyslog", N_("Disable syslog (all msgs)"), OPT_BOOL, &opt_nosyslog }, { 'l', "logfile", N_("Enable debug to file"), OPT_STR, &opt_logpath }, { 0, "debug", N_("Enable debug subsystems"), OPT_STR, &opt_log_debug }, #if ENABLE_TRACE { 0, "trace", N_("Enable trace subsystems"), OPT_STR, &opt_log_trace }, #endif { 0, "fileline", N_("Add file and line numbers to debug"), OPT_BOOL, &opt_fileline }, { 0, "threadid", N_("Add the thread ID to debug"), OPT_BOOL, &opt_threadid }, #if ENABLE_LIBAV { 0, "libav", N_("More verbose libav log"), OPT_BOOL, &opt_libav }, #endif { 0, "uidebug", N_("Enable webUI debug (non-minified JS)"), OPT_BOOL, &opt_uidebug }, { 'A', "abort", N_("Immediately abort"), OPT_BOOL, &opt_abort }, { 'D', "dump", N_("Enable coredumps for daemon"), OPT_BOOL, &opt_dump }, { 0, "noacl", N_("Disable all access control checks"), OPT_BOOL, &opt_noacl }, { 0, "nobat", N_("Disable DVB bouquets"), OPT_BOOL, &opt_nobat }, { 'j', "join", N_("Subscribe to a service permanently"), OPT_STR, &opt_subscribe }, #if ENABLE_TSFILE || ENABLE_TSDEBUG { 0, NULL, N_("Testing options"), OPT_BOOL, NULL }, { 0, "tsfile_tuners", N_("Number of tsfile tuners"), OPT_INT, &opt_tsfile_tuner }, { 0, "tsfile", N_("tsfile input (mux file)"), OPT_STR_LIST, &opt_tsfile }, #endif #if ENABLE_TSDEBUG { 0, "tsdebug", N_("Output directory for tsdebug"), OPT_STR, &tvheadend_tsdebug }, #endif }; /* Get current directory */ tvheadend_cwd0 = dirname(tvh_strdupa(argv[0])); tvheadend_cwd = dirname(tvh_strdupa(tvheadend_cwd0)); /* Set locale */ setlocale(LC_ALL, ""); setlocale(LC_NUMERIC, "C"); /* make sure the timezone is set */ tzset(); /* Process command line */ for (i = 1; i < argc; i++) { /* Find option */ cmdline_opt_t *opt = cmdline_opt_find(cmdline_opts, ARRAY_SIZE(cmdline_opts), argv[i]); if (!opt) show_usage(argv[0], cmdline_opts, ARRAY_SIZE(cmdline_opts), _("invalid option specified [%s]"), argv[i]); /* Process */ if (opt->type == OPT_BOOL) *((int*)opt->param) = 1; else if (++i == argc) show_usage(argv[0], cmdline_opts, ARRAY_SIZE(cmdline_opts), _("option %s requires a value"), opt->lopt); else if (opt->type == OPT_INT) *((int*)opt->param) = atoi(argv[i]); else if (opt->type == OPT_STR_LIST) { str_list_t *strl = opt->param; if (strl->num < strl->max) strl->str[strl->num++] = argv[i]; } else *((char**)opt->param) = argv[i]; /* Stop processing */ if (opt_help) show_usage(argv[0], cmdline_opts, ARRAY_SIZE(cmdline_opts), NULL); if (opt_version) show_version(argv[0]); } /* Additional cmdline processing */ if (opt_nobat) dvb_bouquets_parse = 0; #if ENABLE_LINUXDVB if (!opt_dvb_adapters) { adapter_mask = ~0; } else { char *p, *e; char *r = NULL; char *dvb_adapters = strdup(opt_dvb_adapters); adapter_mask = 0x0; p = strtok_r(dvb_adapters, ",", &r); while (p) { int a = strtol(p, &e, 10); if (*e != 0 || a < 0 || a > 31) { fprintf(stderr, _("Invalid adapter number '%s'\n"), p); free(dvb_adapters); return 1; } adapter_mask |= (1 << a); p = strtok_r(NULL, ",", &r); } free(dvb_adapters); if (!adapter_mask) { fprintf(stderr, "%s", _("No adapters specified!\n")); return 1; } } #endif if (tvheadend_webroot) { char *tmp; if (*tvheadend_webroot == '/') tmp = strdup(tvheadend_webroot); else { tmp = malloc(strlen(tvheadend_webroot)+2); *tmp = '/'; strcpy(tmp+1, tvheadend_webroot); } if (tmp[strlen(tmp)-1] == '/') tmp[strlen(tmp)-1] = '\0'; tvheadend_webroot = tmp; } tvheadend_webui_debug = opt_uidebug; /* Setup logging */ if (isatty(2)) log_options |= TVHLOG_OPT_DECORATE; if (opt_stderr || opt_syslog || opt_logpath) { if (!opt_log_trace && !opt_log_debug) log_debug = "all"; log_level = LOG_DEBUG; if (opt_stderr) log_options |= TVHLOG_OPT_DBG_STDERR; if (opt_syslog) log_options |= TVHLOG_OPT_DBG_SYSLOG; if (opt_logpath) log_options |= TVHLOG_OPT_DBG_FILE; } if (opt_nosyslog) log_options &= ~(TVHLOG_OPT_SYSLOG|TVHLOG_OPT_DBG_SYSLOG); if (opt_fileline) log_options |= TVHLOG_OPT_FILELINE; if (opt_threadid) log_options |= TVHLOG_OPT_THREAD; if (opt_libav) log_options |= TVHLOG_OPT_LIBAV; if (opt_log_trace) { log_level = LOG_TRACE; log_trace = opt_log_trace; } if (opt_log_debug) log_debug = opt_log_debug; tvhlog_init(log_level, log_options, opt_logpath); tvhlog_set_debug(log_debug); tvhlog_set_trace(log_trace); tvhinfo("main", "Log started"); signal(SIGPIPE, handle_sigpipe); // will be redundant later signal(SIGILL, handle_sigill); // see handler.. /* Set priviledges */ if(opt_fork || opt_group || opt_user) { const char *homedir; struct group *grp = getgrnam(opt_group ?: "video"); struct passwd *pw = opt_user ? getpwnam(opt_user) : NULL; if(grp != NULL) { gid = grp->gr_gid; } else { gid = 1; } if (pw != NULL) { if (getuid() != pw->pw_uid) { gid_t glist[16]; int gnum; gnum = get_user_groups(pw, glist, ARRAY_SIZE(glist)); if (gnum > 0 && setgroups(gnum, glist)) { char buf[256] = ""; int i; for (i = 0; i < gnum; i++) snprintf(buf + strlen(buf), sizeof(buf) - 1 - strlen(buf), ",%d", glist[i]); tvhlog(LOG_ALERT, "START", "setgroups(%s) failed, do you have permission?", buf+1); return 1; } } uid = pw->pw_uid; homedir = pw->pw_dir; setenv("HOME", homedir, 1); } else { uid = 1; } } uuid_init(); config_boot(opt_config, gid, uid); tcp_server_preinit(opt_ipv6); http_server_init(opt_bindaddr); // bind to ports only htsp_init(opt_bindaddr); // bind to ports only satip_server_init(opt_satip_rtsp); // bind to ports only if (opt_fork) pidfile = tvh_fopen(opt_pidpath, "w+"); if (gid != -1 && (getgid() != gid) && setgid(gid)) { tvhlog(LOG_ALERT, "START", "setgid(%d) failed, do you have permission?", gid); return 1; } if (uid != -1 && (getuid() != uid) && setuid(uid)) { tvhlog(LOG_ALERT, "START", "setuid(%d) failed, do you have permission?", uid); return 1; } /* Daemonise */ if(opt_fork) { if(daemon(0, 0)) { exit(2); } if(pidfile != NULL) { fprintf(pidfile, "%d\n", getpid()); fclose(pidfile); } /* Make dumpable */ if (opt_dump) { #ifdef PLATFORM_LINUX if (chdir("/tmp")) tvhwarn("START", "failed to change cwd to /tmp"); prctl(PR_SET_DUMPABLE, 1); #else tvhwarn("START", "Coredumps not implemented on your platform"); #endif } umask(0); } tvheadend_running = 1; /* Start log thread (must be done post fork) */ tvhlog_start(); /* Alter logging */ if (opt_fork) tvhlog_options &= ~TVHLOG_OPT_STDERR; if (!isatty(2)) tvhlog_options &= ~TVHLOG_OPT_DECORATE; /* Initialise clock */ pthread_mutex_lock(&global_lock); time(&dispatch_clock); /* Signal handling */ sigfillset(&set); sigprocmask(SIG_BLOCK, &set, NULL); trap_init(argv[0]); /* SSL library init */ OPENSSL_config(NULL); SSL_load_error_strings(); SSL_library_init(); /* Initialise configuration */ notify_init(); idnode_init(); spawn_init(); config_init(opt_nobackup == 0); /** * Initialize subsystems */ epg_in_load = 1; tvhthread_create(&tasklet_tid, NULL, tasklet_thread, NULL); dbus_server_init(opt_dbus, opt_dbus_session); intlconv_init(); api_init(); fsmonitor_init(); libav_init(); tvhtime_init(); profile_init(); imagecache_init(); http_client_init(opt_user_agent); esfilter_init(); bouquet_init(); service_init(); dvb_init(); #if ENABLE_MPEGTS mpegts_init(adapter_mask, &opt_satip_xml, &opt_tsfile, opt_tsfile_tuner); #endif channel_init(); bouquet_service_resolve(); subscription_init(); dvr_config_init(); access_init(opt_firstrun, opt_noacl); #if ENABLE_TIMESHIFT timeshift_init(); #endif tcp_server_init(); webui_init(opt_xspf); #if ENABLE_UPNP upnp_server_init(opt_bindaddr); #endif service_mapper_init(); descrambler_init(); epggrab_init(); epg_init(); dvr_init(); dbus_server_start(); http_server_register(); satip_server_register(); htsp_register(); if(opt_subscribe != NULL) subscription_dummy_join(opt_subscribe, 1); avahi_init(); bonjour_init(); epg_updated(); // cleanup now all prev ref's should have been created epg_in_load = 0; pthread_mutex_unlock(&global_lock); /** * Wait for SIGTERM / SIGINT, but only in this thread */ sigemptyset(&set); sigaddset(&set, SIGTERM); sigaddset(&set, SIGINT); signal(SIGTERM, doexit); signal(SIGINT, doexit); pthread_sigmask(SIG_UNBLOCK, &set, NULL); tvhlog(LOG_NOTICE, "START", "HTS Tvheadend version %s started, " "running as PID:%d UID:%d GID:%d, CWD:%s CNF:%s", tvheadend_version, getpid(), getuid(), getgid(), getcwd(buf, sizeof(buf)), hts_settings_get_root()); if(opt_abort) abort(); mainloop(); #if ENABLE_DBUS_1 tvhftrace("main", dbus_server_done); #endif #if ENABLE_UPNP tvhftrace("main", upnp_server_done); #endif tvhftrace("main", satip_server_done); tvhftrace("main", htsp_done); tvhftrace("main", http_server_done); tvhftrace("main", webui_done); tvhftrace("main", fsmonitor_done); tvhftrace("main", http_client_done); tvhftrace("main", tcp_server_done); // Note: the locking is obviously a bit redundant, but without // we need to disable the gtimer_arm call in epg_save() pthread_mutex_lock(&global_lock); tvhftrace("main", epg_save); #if ENABLE_TIMESHIFT tvhftrace("main", timeshift_term); #endif pthread_mutex_unlock(&global_lock); tvhftrace("main", epggrab_done); #if ENABLE_MPEGTS tvhftrace("main", mpegts_done); #endif tvhftrace("main", descrambler_done); tvhftrace("main", service_mapper_done); tvhftrace("main", service_done); tvhftrace("main", channel_done); tvhftrace("main", bouquet_done); tvhftrace("main", dvr_done); tvhftrace("main", subscription_done); tvhftrace("main", access_done); tvhftrace("main", epg_done); tvhftrace("main", avahi_done); tvhftrace("main", bonjour_done); tvhftrace("main", imagecache_done); tvhftrace("main", lang_code_done); tvhftrace("main", api_done); tvhtrace("main", "tasklet enter"); pthread_cond_signal(&tasklet_cond); pthread_join(tasklet_tid, NULL); tvhtrace("main", "tasklet thread end"); tasklet_flush(); tvhtrace("main", "tasklet leave"); tvhftrace("main", hts_settings_done); tvhftrace("main", dvb_done); tvhftrace("main", lang_str_done); tvhftrace("main", esfilter_done); tvhftrace("main", profile_done); tvhftrace("main", intlconv_done); tvhftrace("main", urlparse_done); tvhftrace("main", idnode_done); tvhftrace("main", notify_done); tvhftrace("main", spawn_done); tvhlog(LOG_NOTICE, "STOP", "Exiting HTS Tvheadend"); tvhlog_end(); tvhftrace("main", config_done); if(opt_fork) unlink(opt_pidpath); #if ENABLE_TSFILE free(opt_tsfile.str); #endif free(opt_satip_xml.str); /* OpenSSL - welcome to the "cleanup" hell */ ENGINE_cleanup(); RAND_cleanup(); CRYPTO_cleanup_all_ex_data(); EVP_cleanup(); CONF_modules_free(); #ifndef OPENSSL_NO_COMP COMP_zlib_cleanup(); #endif ERR_remove_state(0); ERR_free_strings(); #ifndef OPENSSL_NO_COMP sk_SSL_COMP_free(SSL_COMP_get_compression_methods()); #endif /* end of OpenSSL cleanup code */ #if ENABLE_DBUS_1 extern void dbus_shutdown(void); if (opt_dbus) dbus_shutdown(); #endif return 0; } /** * */ void tvh_str_set(char **strp, const char *src) { free(*strp); *strp = src ? strdup(src) : NULL; } /** * */ int tvh_str_update(char **strp, const char *src) { if(src == NULL) return 0; free(*strp); *strp = strdup(src); return 1; } /** * */ void scopedunlock(pthread_mutex_t **mtxp) { pthread_mutex_unlock(*mtxp); }
/* * Create a new peer session in assigned state (connect will start automatically) */ static struct session *peer_session_create(struct peer *peer, struct peer_session *ps) { struct listener *l = ((struct proxy *)peer->peers->peers_fe)->listen; struct proxy *p = (struct proxy *)l->frontend; /* attached frontend */ struct session *s; struct http_txn *txn; struct task *t; if ((s = pool_alloc2(pool2_session)) == NULL) { /* disable this proxy for a while */ Alert("out of memory in event_accept().\n"); goto out_close; } LIST_ADDQ(&sessions, &s->list); LIST_INIT(&s->back_refs); s->flags = SN_ASSIGNED|SN_ADDR_SET; s->term_trace = 0; /* if this session comes from a known monitoring system, we want to ignore * it as soon as possible, which means closing it immediately for TCP. */ if ((t = task_new()) == NULL) { /* disable this proxy for a while */ Alert("out of memory in event_accept().\n"); goto out_free_session; } ps->reconnect = tick_add(now_ms, MS_TO_TICKS(5000)); ps->statuscode = PEER_SESSION_CONNECTCODE; t->process = l->handler; t->context = s; t->nice = l->nice; memcpy(&s->si[1].conn.addr.to, &peer->addr, sizeof(s->si[1].conn.addr.to)); s->task = t; s->listener = l; /* Note: initially, the session's backend points to the frontend. * This changes later when switching rules are executed or * when the default backend is assigned. */ s->be = s->fe = p; s->req = s->rep = NULL; /* will be allocated later */ s->si[0].conn.t.sock.fd = -1; s->si[0].conn.flags = CO_FL_NONE; s->si[0].owner = t; s->si[0].state = s->si[0].prev_state = SI_ST_EST; s->si[0].err_type = SI_ET_NONE; s->si[0].err_loc = NULL; s->si[0].release = NULL; s->si[0].send_proxy_ofs = 0; set_target_client(&s->si[0].conn.target, l); s->si[0].exp = TICK_ETERNITY; s->si[0].flags = SI_FL_NONE; if (s->fe->options2 & PR_O2_INDEPSTR) s->si[0].flags |= SI_FL_INDEP_STR; stream_int_register_handler(&s->si[0], &peer_applet); s->si[0].applet.st0 = PEER_SESSION_CONNECT; s->si[0].conn.data_ctx = (void *)ps; s->si[1].conn.t.sock.fd = -1; /* just to help with debugging */ s->si[1].conn.flags = CO_FL_NONE; s->si[1].owner = t; s->si[1].state = s->si[1].prev_state = SI_ST_ASS; s->si[1].conn_retries = p->conn_retries; s->si[1].err_type = SI_ET_NONE; s->si[1].err_loc = NULL; s->si[1].release = NULL; s->si[1].send_proxy_ofs = 0; set_target_proxy(&s->si[1].conn.target, s->be); si_prepare_conn(&s->si[1], peer->proto, peer->data); s->si[1].exp = TICK_ETERNITY; s->si[1].flags = SI_FL_NONE; if (s->be->options2 & PR_O2_INDEPSTR) s->si[1].flags |= SI_FL_INDEP_STR; session_init_srv_conn(s); set_target_proxy(&s->target, s->be); s->pend_pos = NULL; /* init store persistence */ s->store_count = 0; s->stkctr1_entry = NULL; s->stkctr2_entry = NULL; /* FIXME: the logs are horribly complicated now, because they are * defined in <p>, <p>, and later <be> and <be>. */ s->logs.logwait = 0; s->do_log = NULL; /* default error reporting function, may be changed by analysers */ s->srv_error = default_srv_error; s->uniq_id = 0; s->unique_id = NULL; txn = &s->txn; /* Those variables will be checked and freed if non-NULL in * session.c:session_free(). It is important that they are * properly initialized. */ txn->sessid = NULL; txn->srv_cookie = NULL; txn->cli_cookie = NULL; txn->uri = NULL; txn->req.cap = NULL; txn->rsp.cap = NULL; txn->hdr_idx.v = NULL; txn->hdr_idx.size = txn->hdr_idx.used = 0; if ((s->req = pool_alloc2(pool2_channel)) == NULL) goto out_fail_req; /* no memory */ s->req->buf.size = global.tune.bufsize; channel_init(s->req); s->req->prod = &s->si[0]; s->req->cons = &s->si[1]; s->si[0].ib = s->si[1].ob = s->req; s->req->flags |= CF_READ_ATTACHED; /* the producer is already connected */ /* activate default analysers enabled for this listener */ s->req->analysers = l->analysers; /* note: this should not happen anymore since there's always at least the switching rules */ if (!s->req->analysers) { channel_auto_connect(s->req);/* don't wait to establish connection */ channel_auto_close(s->req);/* let the producer forward close requests */ } s->req->rto = s->fe->timeout.client; s->req->wto = s->be->timeout.server; if ((s->rep = pool_alloc2(pool2_channel)) == NULL) goto out_fail_rep; /* no memory */ s->rep->buf.size = global.tune.bufsize; channel_init(s->rep); s->rep->prod = &s->si[1]; s->rep->cons = &s->si[0]; s->si[0].ob = s->si[1].ib = s->rep; s->rep->rto = s->be->timeout.server; s->rep->wto = s->fe->timeout.client; s->req->rex = TICK_ETERNITY; s->req->wex = TICK_ETERNITY; s->req->analyse_exp = TICK_ETERNITY; s->rep->rex = TICK_ETERNITY; s->rep->wex = TICK_ETERNITY; s->rep->analyse_exp = TICK_ETERNITY; t->expire = TICK_ETERNITY; s->rep->flags |= CF_READ_DONTWAIT; /* it is important not to call the wakeup function directly but to * pass through task_wakeup(), because this one knows how to apply * priorities to tasks. */ task_wakeup(t, TASK_WOKEN_INIT); l->nbconn++; /* warning! right now, it's up to the handler to decrease this */ p->feconn++;/* beconn will be increased later */ jobs++; if (!(s->listener->options & LI_O_UNLIMITED)) actconn++; totalconn++; return s; /* Error unrolling */ out_fail_rep: pool_free2(pool2_channel, s->req); out_fail_req: task_free(t); out_free_session: LIST_DEL(&s->list); pool_free2(pool2_session, s); out_close: return s; }