summaryrefslogtreecommitdiff
path: root/src/stmpdup.c
blob: b724157e5973be1b87dd6c10500ac541067c7f85 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/* Copyright (C) 2025 awy <awy@awy.one>

   stmpdup 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 3 of the License, or (at your option) any later version.

   stmpdup 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 stmpdup. If not, see
   <https://www.gnu.org/licenses/>. */

/* cmd_idle and cmd_idleloop functions are taken from the
   MPC <https://github.com/MusicPlayerDaemon/mpc> */

#define _POSIX_C_SOURCE 200112L
#include <ctype.h>
#include <mpd/client.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <dirent.h>
#include <stdlib.h>
#include <string.h>

#include "../lib/util.h"

int
find_pid_by_name(const char *process_name)
{
  DIR *dir = opendir("/proc");
  if (!dir) return -1;

  struct dirent *entry;
  while ((entry = readdir(dir)) != NULL) {
    if (!isdigit(entry->d_name[0])) continue;

    char path[256], name[256];
    snprintf(path, sizeof(path), "/proc/%s/comm", entry->d_name);

    FILE *fp = fopen(path, "r");
    if (!fp) continue;

    if (fgets(name, sizeof(name), fp)) {
      name[strcspn(name, "\n")] = 0;
      if (strcmp(name, process_name) == 0) {
        fclose(fp);
        closedir(dir);
        return atoi(entry->d_name);
      }
    }
    fclose(fp);
  }
  closedir(dir);
  return -1;
}


int cmd_idle(struct mpd_connection *connection)
{
  enum mpd_idle idle = 0;
  pid_t wbarpid;

  idle = idle == 0 ? mpd_run_idle(connection)
    : mpd_run_idle_mask(connection, idle);
  if (idle == 0 &&
    mpd_connection_get_error(connection) != MPD_ERROR_SUCCESS)
    printf("error");

  for (unsigned j = 0;; ++j) {
    enum mpd_idle i = 1 << j;
    const char *name = mpd_idle_name(i);

    if (name == NULL)
      break;

    if (idle & i) {
      wbarpid = find_pid_by_name("waybar");
      if (wbarpid == -1)
        die("no waybar running");

      kill(wbarpid, SIGRTMIN+11);
    }

  }

  return 0;
}

int
cmd_idleloop(struct mpd_connection *connection)
{
  while (true) {
    int ret = cmd_idle(connection);
    fflush(stdout);
    if (ret != 0)
      return ret;
  }
}

int
main(void)
{
  struct mpd_connection *conn;

  conn = mpd_connection_new(NULL, 0, 30000);
  if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS) {
    fprintf(stderr, "MPD connection error: %s\n",
            mpd_connection_get_error_message(conn));
    return 1;
  }

  cmd_idleloop(conn);
  return 0;
}