kdldap_servers *kdldap_servers_new(apr_pool_t *pool, int use_sasl) { apr_pool_t *obj_pool; kdldap_servers *self; const char *ldap_dom, *ldap_ad_site; apr_pool_create(&obj_pool, pool); self = apr_pcalloc(obj_pool, sizeof(kdldap_servers)); self->use_sasl = use_sasl; /* Get the AD forest to query. */ ldap_dom = options_get_str("ldap.domain"); if (ldap_dom == NULL || strlen(ldap_dom) == 0) self->ad_forest = NULL; else self->ad_forest = apr_pstrdup(obj_pool, ldap_dom); ldap_ad_site = options_get_str("ldap.ad_site"); if (ldap_ad_site == NULL || strlen(ldap_ad_site) == 0) self->ad_site = NULL; else self->ad_site = apr_pstrdup(obj_pool, ldap_ad_site); /* Check if we were told to search in the DNS. */ if (!self->ad_forest || options_get_bool("ldap.domain_search") <= 0) { WARN(_log_ldap_, "LDAP server search will use static server list."); self->use_dns = 0; } else self->use_dns = 1; if (self->use_dns) { if ((self->ad_forest && self->use_dns) && !self->ad_site) WARN(_log_ldap_, "No AD site defined. LDAP server queries will be done forest-wide."); else INFO(_log_ldap_, "AD site: %s.", self->ad_site); } /* Parse the static server list. */ if (!self->use_dns) { if (kdldap_servers_load_static_servers(self, obj_pool, &self->static_ldap_servers) < 0) { KERROR_PUSH(_ldap_, 0, "error loading static LDAP server list"); apr_pool_destroy(obj_pool); return NULL; } } else { /* ADNS initialization. */ if (adns_init(&self->adns_state, adns_if_noenv, 0)) { self->adns_init = 0; KERROR_SET(_ldap_, 0, "cannot initialize adns"); apr_pool_destroy(obj_pool); return NULL; } else self->adns_init = 1; } apr_pool_cleanup_register(obj_pool, self, kdldap_servers_cleanup, kdldap_servers_cleanup); return self; }
/* Handle running external command on Stop event. */ static void on_stop () { char *command; command = xstrdup (options_get_str("OnStop")); if (command) { char *args[2], *err; args[0] = xstrdup (command); args[1] = NULL; switch (fork()) { case 0: execve (command, args, environ); exit (EXIT_FAILURE); case -1: err = xstrerror (errno); logit ("Error when running OnStop command '%s': %s", command, err); free (err); break; } free (command); free (args[0]); } }
/** Initialize the logging drivers and options. */ static void kd_init_logging() { int i; int is_filtered; char buf[256]; char *ce, *channel, *last; const char *log_chan_enabled; const char *log_driver; const char log_driver_fmt[] = "log_%s.driver"; const char log_filtered_fmt[] = "log_%s.filter"; /* Order matters here. This is the order of the LOG_* constants found in /usr/include/sys/syslog.h. */ const char *log_levels[] = {"emergency", "alert", "critical", "error", "warning", "notice", "info", "debug", NULL}; /* Configure the basic log levels. */ for (i = 0; log_levels[i] != NULL; i++) { /* Read the log driver. If none was provided, we use the null driver. */ sprintf(buf, log_driver_fmt, log_levels[i]); log_driver = options_get_str(buf); /* Check if the level needs to be filtered. If the value was not provided we default to no. */ sprintf(buf, log_filtered_fmt, log_levels[i]); is_filtered = options_get_bool(buf); log_set_level(i, log_driver, is_filtered); } /* Configure the enabled channels. */ log_chan_enabled = options_get_str("log_channel.enabled"); if (strcmp(log_chan_enabled, "") == 0) return; ce = strdup(log_chan_enabled); for (channel = apr_strtok(ce, " ", &last); channel != NULL; channel = apr_strtok(NULL, " ", &last)) log_enable_channel(channel); free(ce); }
/** Connect a single database. */ static kdsql *kddb_connect_db(apr_pool_t *pool, enum kddb_auth_mode auth_mode) { kdsql *conn; /* Connect to the database. */ conn = kdsql_new(pool); conn->db_host = options_get_str("db.host"); switch (auth_mode) { case DB_AUTH_CURRENT_CREDS_MODE: { apr_uid_t uid; apr_gid_t gid; char *username; DEBUG(_log_db_, "Connecting using current username."); apr_uid_current(&uid, &gid, pool); apr_uid_name_get(&username, uid, pool); conn->db_username = username; conn->db_password = ""; break; } case DB_AUTH_ADMIN_MODE: DEBUG(_log_db_, "Connecting to %s using administrator username/password.", conn->db_host); conn->db_username = options_get_str("db.admin_username"); conn->db_password = options_get_str("db.admin_password"); break; case DB_AUTH_NORMAL_MODE: DEBUG(_log_db_, "Connecting to %s using normal username/password.", conn->db_host); conn->db_username = options_get_str("db.username"); conn->db_password = options_get_str("db.password"); break; } conn->db_name = "tbxsosd_db"; conn->db_port = options_get_uint16("db.port"); conn->db_timeout = options_get_uint32("db.timeout"); if (kdsql_connect(conn) < 0) return NULL; return conn; }
/** Load the statically defined list of servers in the LDAP config. */ static int kdldap_servers_load_static_servers(kdldap_servers *self, apr_pool_t *pool, kdldap_servers_list **srv_lst) { size_t i, max; char *hosts, *host = NULL, *port_str = NULL; apr_pool_t *lst_pool; const char *cfg_hosts; apr_pool_create(&lst_pool, pool); self->static_ldap_servers = kdldap_servers_list_new(lst_pool); cfg_hosts = options_get_str("ldap.host"); hosts = apr_pstrdup(lst_pool, cfg_hosts); max = strlen(hosts); for (i = 0; i <= max; i++) { int is_whitespace = (hosts[i] == ' ' || hosts[i] == '\n' || hosts[i] == '\0'); /* Start of new host. */ if (host == NULL && port_str == NULL && !is_whitespace) host = &hosts[i]; /* Start of port. */ else if (host != NULL && port_str == NULL && hosts[i - 1] == ':') { port_str = &hosts[i]; hosts[i - 1] = '\0'; } /* End of host:port. */ if (host != NULL && port_str != NULL && is_whitespace) { int port; hosts[i] = '\0'; port = strtoimax(port_str, NULL, 10); if (port == 0) { KERROR_SET(_ldap_, 0, "invalid port: %s", port_str); apr_pool_destroy(lst_pool); *srv_lst = NULL; return -1; } kdldap_servers_list_add(*srv_lst, host, port); host = NULL; port_str = NULL; } } return 0; }
static void kd_spawn_save_pid_file(pid_t child_pid) { FILE *pidf; const char *config_pid_file; /* Get the run data path. */ config_pid_file = options_get_str("server.pid_file"); /* Create the PID if the option specifiying the path to the PID file was provided. */ if ((pidf = fopen(config_pid_file, "w")) != NULL) { fprintf(pidf, "%u", child_pid); fclose(pidf); } else ERROR(_log_server_, "Failed to open PID file."); }
/* Return path to a file in MOC config directory. NOT THREAD SAFE */ char *create_file_name (const char *file) { char *home_dir; static char fname[PATH_MAX]; char *moc_dir = options_get_str ("MOCDir"); if (moc_dir[0] == '~') { if (!(home_dir = getenv("HOME"))) fatal ("No HOME environmential variable."); if (snprintf(fname, sizeof(fname), "%s/%s/%s", home_dir, (moc_dir[1] == '/') ? moc_dir + 2 : moc_dir + 1, file) >= (int)sizeof(fname)) fatal ("Path too long."); } else if (snprintf(fname, sizeof(fname), "%s/%s", moc_dir, file) >= (int)sizeof(fname)) fatal ("Path too long."); return fname; }
void theme_init (bool has_xterm) { reset_colors_table (); if (has_colors()) { if (options_get_str("ForceTheme")) load_color_theme (options_get_str("ForceTheme"), 1); else if (has_xterm && options_get_str("XTermTheme")) load_color_theme (options_get_str("XTermTheme"), 1); else if (options_get_str("Theme")) load_color_theme (options_get_str("Theme"), 1); set_default_colors (); } else set_bw_colors (); }
/** Displays command line options. */ static void kd_options_print() { int p, v; const char *d; p = options_get_uint16("server.port"); v = options_get_uint32("server.log_verbosity"); d = options_get_str("server.log_driver"); printf("Usage: tbxsosd [OPTIONS] \n\n" \ "Options: \n" \ " -V Print version information \n"); printf(" -D Debug mode, don't fork nor detach, and log to stderr.\n"); printf(" -p Listen on this port (defaults to: %d) \n", p); printf(" -v Output verbosity level (defaults to: %d) \n", v); printf(" -d Fork the server in the background."); if (strlen(d) != 0) printf(" (enabled) \n"); else printf(" (disabled) \n"); }
/** Initialize common data for the kdkey object. */ int kdkey_static_init() { kbuffer buf, mk_buf, lk_buf; kstr str; int err; master_pkey_info.data = master_pkey_str; master_pkey_info.data_s = strlen(master_pkey_str); license_pkey_info.data = license_pkey_str; license_pkey_info.data_s = strlen(license_pkey_str); do { /* Load the master public key. */ kstr_init_cstr(&str, master_pkey_str); kbuffer_init_b64(&mk_buf, &str); kstr_clean(&str); master_pkey_info.key = tagcrypt_pkey_new(&mk_buf, KEY_TYPE_MASTER); /* Load the license public key. */ kstr_init_cstr(&str, license_pkey_str); kbuffer_init_b64(&lk_buf, &str); kstr_clean(&str); license_pkey_info.key = tagcrypt_pkey_new(&lk_buf, KEY_TYPE_MASTER); kbuffer_clean(&lk_buf); kbuffer_clean(&mk_buf); #ifdef REQUEST_GETSIG tm_pkey_str = options_get_str("keysign.public"); tm_skey_str = options_get_str("keysign.private"); tm_pkey_info.data = tm_pkey_str; tm_pkey_info.data_s = strlen(tm_pkey_str); tm_skey_info.data = tm_skey_str; tm_skey_info.data_s = strlen(tm_skey_str); kstr_init_buf(&str, tm_skey_info.data, tm_skey_info.data_s); err = kbuffer_init_b64(&buf, &str); kstr_clean(&str); if (err) { KERROR_SET(_keys_, 0, "cannot convert the secret key from base64 to binary"); break; } else /* FIXME: I believe this is actually a bug in libktools. Errors are pushed by libktools even where there is no returned errors. */ kerror_reset(); tm_skey_info.key = tagcrypt_skey_new(&buf); kbuffer_clean(&buf); if (tm_skey_info.key == NULL) { KERROR_SET(_keys_, 0, "cannot create internal timestamp key object"); err = -1; break; } #endif // REQUEST_GETSIG /* Cleans libktools error. */ kerror_reset(); err = 0; } while (0); return err ? -1 : 0; }
/* Fill caps with the device capabilities. Return 0 on error. */ static int fill_capabilities (struct output_driver_caps *caps) { snd_pcm_hw_params_t *hw_params; snd_pcm_format_mask_t *format_mask; int err; unsigned val; if ((err = snd_pcm_open(&handle, options_get_str("AlsaDevice"), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK)) < 0) { error ("Can't open audio: %s", snd_strerror(err)); return 0; } if ((err = snd_pcm_hw_params_malloc(&hw_params)) < 0) { error ("Can't allocate alsa hardware parameters structure: %s", snd_strerror(err)); snd_pcm_close (handle); return 0; } if ((err = snd_pcm_hw_params_any (handle, hw_params)) < 0) { error ("Can't initialize hardware parameters structure: %s", snd_strerror(err)); snd_pcm_hw_params_free (hw_params); snd_pcm_close (handle); return 0; } if ((err = snd_pcm_hw_params_get_channels_min (hw_params, &val)) < 0) { error ("Can't get the minimum number of channels: %s", snd_strerror(err)); snd_pcm_hw_params_free (hw_params); snd_pcm_close (handle); return 0; } caps->min_channels = val; if ((err = snd_pcm_hw_params_get_channels_max (hw_params, &val)) < 0) { error ("Can't get the maximum number of channels: %s", snd_strerror(err)); snd_pcm_hw_params_free (hw_params); snd_pcm_close (handle); return 0; } caps->max_channels = val; if ((err = snd_pcm_format_mask_malloc(&format_mask)) < 0) { error ("Can't allocate format mask: %s", snd_strerror(err)); snd_pcm_hw_params_free (hw_params); snd_pcm_close (handle); return 0; } snd_pcm_hw_params_get_format_mask (hw_params, format_mask); caps->formats = SFMT_NE; if (snd_pcm_format_mask_test(format_mask, SND_PCM_FORMAT_S8)) caps->formats |= SFMT_S8; if (snd_pcm_format_mask_test(format_mask, SND_PCM_FORMAT_U8)) caps->formats |= SFMT_U8; if (snd_pcm_format_mask_test(format_mask, SND_PCM_FORMAT_S16)) caps->formats |= SFMT_S16; if (snd_pcm_format_mask_test(format_mask, SND_PCM_FORMAT_U16)) caps->formats |= SFMT_U16; #if 0 if (snd_pcm_format_mask_test(format_mask, SND_PCM_FORMAT_S24)) caps->formats |= SFMT_S32; /* conversion needed */ #endif if (snd_pcm_format_mask_test(format_mask, SND_PCM_FORMAT_S32)) caps->formats |= SFMT_S32; if (snd_pcm_format_mask_test(format_mask, SND_PCM_FORMAT_U32)) caps->formats |= SFMT_U32; snd_pcm_format_mask_free (format_mask); snd_pcm_hw_params_free (hw_params); snd_pcm_close (handle); handle = NULL; return 1; }
static char *alsa_get_mixer_channel_name () { if (mixer_elem_curr == mixer_elem1) return xstrdup (options_get_str("AlsaMixer")); return xstrdup (options_get_str("AlsaMixer2")); }
static int alsa_open (struct sound_params *sound_params) { snd_pcm_hw_params_t *hw_params; int err; unsigned int period_time; unsigned int buffer_time; snd_pcm_uframes_t chunk_frames; snd_pcm_uframes_t buffer_frames; char fmt_name[128]; switch (sound_params->fmt & SFMT_MASK_FORMAT) { case SFMT_S8: params.format = SND_PCM_FORMAT_S8; break; case SFMT_U8: params.format = SND_PCM_FORMAT_U8; break; case SFMT_S16: params.format = SND_PCM_FORMAT_S16; break; case SFMT_U16: params.format = SND_PCM_FORMAT_U16; break; case SFMT_S32: params.format = SND_PCM_FORMAT_S32; break; case SFMT_U32: params.format = SND_PCM_FORMAT_U32; break; default: error ("Unknown sample format: %s", sfmt_str(sound_params->fmt, fmt_name, sizeof(fmt_name))); params.format = SND_PCM_FORMAT_UNKNOWN; return 0; } if ((err = snd_pcm_open(&handle, options_get_str("AlsaDevice"), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK)) < 0) { error ("Can't open audio: %s", snd_strerror(err)); return 0; } if ((err = snd_pcm_hw_params_malloc(&hw_params)) < 0) { error ("Can't allocate alsa hardware parameters structure: %s", snd_strerror(err)); return 0; } if ((err = snd_pcm_hw_params_any (handle, hw_params)) < 0) { error ("Can't initialize hardware parameters structure: %s", snd_strerror(err)); snd_pcm_hw_params_free (hw_params); return 0; } if ((err = snd_pcm_hw_params_set_access (handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) { error ("Can't set alsa access type: %s", snd_strerror(err)); snd_pcm_hw_params_free (hw_params); return 0; } if ((err = snd_pcm_hw_params_set_format (handle, hw_params, params.format)) < 0) { error ("Can't set sample format: %s", snd_strerror(err)); snd_pcm_hw_params_free (hw_params); return 0; } params.rate = sound_params->rate; if ((err = snd_pcm_hw_params_set_rate_near (handle, hw_params, ¶ms.rate, 0)) < 0) { error ("Can't set sample rate: %s", snd_strerror(err)); snd_pcm_hw_params_free (hw_params); return 0; } logit ("Set rate to %d", params.rate); if ((err = snd_pcm_hw_params_set_channels (handle, hw_params, sound_params->channels)) < 0) { error ("Can't set number of channels: %s", snd_strerror(err)); snd_pcm_hw_params_free (hw_params); return 0; } if ((err = snd_pcm_hw_params_get_buffer_time_max(hw_params, &buffer_time, 0)) < 0) { error ("Can't get maximum buffer time: %s", snd_strerror(err)); snd_pcm_hw_params_free (hw_params); return 0; } if (buffer_time > BUFFER_MAX_USEC) buffer_time = BUFFER_MAX_USEC; period_time = buffer_time / 4; if ((err = snd_pcm_hw_params_set_period_time_near(handle, hw_params, &period_time, 0)) < 0) { error ("Can't set period time: %s", snd_strerror(err)); snd_pcm_hw_params_free (hw_params); return 0; } if ((err = snd_pcm_hw_params_set_buffer_time_near(handle, hw_params, &buffer_time, 0)) < 0) { error ("Can't set buffer time: %s", snd_strerror(err)); snd_pcm_hw_params_free (hw_params); return 0; } if ((err = snd_pcm_hw_params (handle, hw_params)) < 0) { error ("Can't set audio parameters: %s", snd_strerror(err)); snd_pcm_hw_params_free (hw_params); return 0; } snd_pcm_hw_params_get_period_size (hw_params, &chunk_frames, 0); snd_pcm_hw_params_get_buffer_size (hw_params, &buffer_frames); bytes_per_frame = sound_params->channels * sfmt_Bps(sound_params->fmt); logit ("Buffer time: %ldus", buffer_frames * bytes_per_frame); if (chunk_frames == buffer_frames) { error ("Can't use period equal to buffer size (%lu == %lu)", chunk_frames, buffer_frames); snd_pcm_hw_params_free (hw_params); return 0; } chunk_size = chunk_frames * bytes_per_frame; debug ("Chunk size: %d", chunk_size); snd_pcm_hw_params_free (hw_params); if ((err = snd_pcm_prepare(handle)) < 0) { error ("Can't prepare audio interface for use: %s", snd_strerror(err)); return 0; } debug ("ALSA device initialized"); params.channels = sound_params->channels; alsa_buf_fill = 0; return 1; }
static int alsa_init (struct output_driver_caps *caps) { int err; if ((err = snd_mixer_open(&mixer_handle, 0)) < 0) { error ("Can't open ALSA mixer: %s", snd_strerror(err)); mixer_handle = NULL; } else if ((err = snd_mixer_attach(mixer_handle, options_get_str("AlsaDevice"))) < 0) { snd_mixer_close (mixer_handle); mixer_handle = NULL; error ("Can't attach mixer: %s", snd_strerror(err)); } else if ((err = snd_mixer_selem_register(mixer_handle, NULL, NULL)) < 0) { snd_mixer_close (mixer_handle); mixer_handle = NULL; error ("Can't register mixer: %s", snd_strerror(err)); } else if ((err = snd_mixer_load(mixer_handle)) < 0) { snd_mixer_close (mixer_handle); mixer_handle = NULL; error ("Can't load mixer: %s", snd_strerror(err)); } if (mixer_handle) { mixer_elem1 = alsa_init_mixer_channel ( options_get_str("AlsaMixer"), &mixer1_min, &mixer1_max); mixer_elem2 = alsa_init_mixer_channel ( options_get_str("AlsaMixer2"), &mixer2_min, &mixer2_max); } mixer_elem_curr = mixer_elem1 ? mixer_elem1 : mixer_elem2; if (mixer_elem_curr) { if (mixer_elem1 && (real_volume1 = alsa_read_mixer_raw(mixer_elem1)) != -1) volume1 = scale_volume1 (real_volume1); else { mixer_elem1 = NULL; mixer_elem_curr = mixer_elem2; } if (mixer_elem2 && (real_volume2 = alsa_read_mixer_raw(mixer_elem2)) != -1) volume2 = scale_volume2 (real_volume2); else { mixer_elem2 = NULL; mixer_elem_curr = mixer_elem1; } if (!mixer_elem_curr) { snd_mixer_close (mixer_handle); mixer_handle = NULL; } } else if (mixer_handle) { snd_mixer_close (mixer_handle); mixer_handle = NULL; } return fill_capabilities (caps); }
static void on_song_change () { static char *last_file = NULL; static lists_t_strs *on_song_change = NULL; int ix; bool same_file, unpaused; char *curr_file, **args; struct file_tags *curr_tags; lists_t_strs *arg_list; /* We only need to do OnSongChange tokenisation once. */ if (on_song_change == NULL) { char *command; on_song_change = lists_strs_new (4); command = options_get_str ("OnSongChange"); if (command) lists_strs_tokenise (on_song_change, command); } if (lists_strs_empty (on_song_change)) return; curr_file = audio_get_sname (); if (curr_file == NULL) return; same_file = (last_file && !strcmp (last_file, curr_file)); unpaused = (audio_get_prev_state () == STATE_PAUSE); if (same_file && (unpaused || !options_get_bool ("RepeatSongChange"))) { free (curr_file); return; } curr_tags = tags_cache_get_immediate (tags_cache, curr_file, TAGS_COMMENTS | TAGS_TIME); arg_list = lists_strs_new (lists_strs_size (on_song_change)); for (ix = 0; ix < lists_strs_size (on_song_change); ix += 1) { char *arg, *str; arg = lists_strs_at (on_song_change, ix); if (arg[0] != '%') lists_strs_append (arg_list, arg); else if (!curr_tags) lists_strs_append (arg_list, ""); else { switch (arg[1]) { case 'a': str = curr_tags->artist ? curr_tags->artist : ""; lists_strs_append (arg_list, str); break; case 'r': str = curr_tags->album ? curr_tags->album : ""; lists_strs_append (arg_list, str); break; case 't': str = curr_tags->title ? curr_tags->title : ""; lists_strs_append (arg_list, str); break; case 'n': if (curr_tags->track >= 0) { str = (char *) xmalloc (sizeof (char) * 4); snprintf (str, 4, "%d", curr_tags->track); lists_strs_push (arg_list, str); } else lists_strs_append (arg_list, ""); break; case 'f': lists_strs_append (arg_list, curr_file); break; case 'D': if (curr_tags->time >= 0) { str = (char *) xmalloc (sizeof (char) * 10); snprintf (str, 10, "%d", curr_tags->time); lists_strs_push (arg_list, str); } else lists_strs_append (arg_list, ""); break; case 'd': if (curr_tags->time >= 0) { str = (char *) xmalloc (sizeof (char) * 12); sec_to_min (str, curr_tags->time); lists_strs_push (arg_list, str); } else lists_strs_append (arg_list, ""); break; default: lists_strs_append (arg_list, arg); } } } tags_free (curr_tags); #ifndef NDEBUG { char *cmd; cmd = lists_strs_fmt (arg_list, " %s"); debug ("Running command: %s", cmd); free (cmd); } #endif switch (fork ()) { case 0: args = lists_strs_save (arg_list); execve (args[0], args, environ); exit (EXIT_FAILURE); case -1: log_errno ("Failed to fork()", errno); } lists_strs_free (arg_list); free (last_file); last_file = curr_file; }
/* Build file title from struct file_tags. Returned memory is malloc()ed. */ char *build_title (const struct file_tags *tags) { return build_title_with_format (tags, options_get_str ("FormatString")); }