+/* smprintf function */
+char *
+smprintf(char *fmt, ...)
+{
+ va_list fmtargs;
+ char *ret;
+ int len;
+
+ va_start(fmtargs, fmt);
+ len = vsnprintf(NULL, 0, fmt, fmtargs);
+ va_end(fmtargs);
+
+ ret = malloc(++len);
+ if (ret == NULL) {
+ fprintf(stderr, "Malloc error.");
+ exit(1);
+ }
+
+ va_start(fmtargs, fmt);
+ vsnprintf(ret, len, fmt, fmtargs);
+ va_end(fmtargs);
+
+ return ret;
+}
+
+/* alsa volume percentage */
+char *
+volume()
+{
+ int mute = 0;
+ long vol = 0, max = 0, min = 0;
+
+ /* get volume from alsa */
+ snd_mixer_t *handle;
+ snd_mixer_elem_t *pcm_mixer, *mas_mixer;
+ snd_mixer_selem_id_t *vol_info, *mute_info;
+ snd_mixer_open(&handle, 0);
+ snd_mixer_attach(handle, soundcard);
+ snd_mixer_selem_register(handle, NULL, NULL);
+ snd_mixer_load(handle);
+ snd_mixer_selem_id_malloc(&vol_info);
+ snd_mixer_selem_id_malloc(&mute_info);
+ snd_mixer_selem_id_set_name(vol_info, channel);
+ snd_mixer_selem_id_set_name(mute_info, channel);
+ pcm_mixer = snd_mixer_find_selem(handle, vol_info);
+ mas_mixer = snd_mixer_find_selem(handle, mute_info);
+ snd_mixer_selem_get_playback_volume_range((snd_mixer_elem_t *)pcm_mixer, &min, &max);
+ snd_mixer_selem_get_playback_volume((snd_mixer_elem_t *)pcm_mixer, SND_MIXER_SCHN_MONO, &vol);
+ snd_mixer_selem_get_playback_switch(mas_mixer, SND_MIXER_SCHN_MONO, &mute);
+ if (vol_info)
+ snd_mixer_selem_id_free(vol_info);
+ if (mute_info)
+ snd_mixer_selem_id_free(mute_info);
+ if (handle)
+ snd_mixer_close(handle);
+
+ /* return the string (mute) */
+ if (!mute)
+ return smprintf("mute");
+ else
+ return smprintf("%d%%", (vol * 100) / max);
+}
+
+/* wifi percentage */
+char *
+wifi_signal()
+{
+ int bufsize = 255;
+ int strength;
+ char buf[bufsize];
+ char *datastart;
+ char path_start[16] = "/sys/class/net/";
+ char path_end[11] = "/operstate";
+ char path[32];
+ char status[5];
+ char needle[sizeof wificard + 1];
+ FILE *fp;
+
+ /* generate the path name */
+
+ memset(path, 0, sizeof path);
+ strcat(path, path_start);
+ strcat(path, wificard);
+ strcat(path, path_end);
+
+ /* open wifi file */
+ if(!(fp = fopen(path, "r"))) {
+ fprintf(stderr, "Error opening wifi operstate file.");
+ exit(1);
+ }
+
+ /* read the status */
+ fgets(status, 5, fp);
+
+ /* close wifi file */
+ fclose(fp);
+
+ /* check if interface down */
+ if(strcmp(status, "up\n") != 0){
+ return "n/a";
+ }
+
+ /* open wifi file */
+ if (!(fp = fopen("/proc/net/wireless", "r"))) {
+ fprintf(stderr, "Error opening wireless file.");
+ exit(1);
+ }
+
+ /* extract the signal strength */
+ strcpy(needle, wificard);
+ strcat(needle, ":");
+ fgets(buf, bufsize, fp);
+ fgets(buf, bufsize, fp);
+ fgets(buf, bufsize, fp);
+ if ((datastart = strstr(buf, needle)) != NULL) {
+ datastart = strstr(buf, ":");
+ sscanf(datastart + 1, " %*d %d %*d %*d %*d %*d %*d %*d %*d %*d", &strength);
+ }
+
+ /* close wifi file */
+ fclose(fp);
+
+ /* return strength in percent */
+ return smprintf("%d%%", strength);
+}
+
+/* main function */