]> code.delx.au - pulseaudio/blob - src/util.c
esound protocol
[pulseaudio] / src / util.c
1 #include <errno.h>
2 #include <assert.h>
3 #include <string.h>
4 #include <stdio.h>
5 #include <sys/un.h>
6 #include <netinet/in.h>
7 #include <fcntl.h>
8 #include <unistd.h>
9 #include <sys/types.h>
10
11 #include "util.h"
12
13 void make_nonblock_fd(int fd) {
14 int v;
15
16 if ((v = fcntl(fd, F_GETFL)) >= 0)
17 if (!(v & O_NONBLOCK))
18 fcntl(fd, F_SETFL, v|O_NONBLOCK);
19 }
20
21 void peer_to_string(char *c, size_t l, int fd) {
22 struct stat st;
23
24 assert(c && l && fd >= 0);
25
26 if (fstat(fd, &st) < 0) {
27 snprintf(c, l, "Invalid client fd");
28 return;
29 }
30
31 if (S_ISSOCK(st.st_mode)) {
32 union {
33 struct sockaddr sa;
34 struct sockaddr_in in;
35 struct sockaddr_un un;
36 } sa;
37 socklen_t sa_len = sizeof(sa);
38
39 if (getpeername(fd, &sa.sa, &sa_len) >= 0) {
40
41 if (sa.sa.sa_family == AF_INET) {
42 uint32_t ip = ntohl(sa.in.sin_addr.s_addr);
43
44 snprintf(c, l, "TCP/IP client from %i.%i.%i.%i:%u",
45 ip >> 24,
46 (ip >> 16) & 0xFF,
47 (ip >> 8) & 0xFF,
48 ip & 0xFF,
49 ntohs(sa.in.sin_port));
50 return;
51 } else if (sa.sa.sa_family == AF_LOCAL) {
52 snprintf(c, l, "UNIX client for %s", sa.un.sun_path);
53 return;
54 }
55
56 }
57 snprintf(c, l, "Unknown network client");
58 return;
59 } else if (S_ISCHR(st.st_mode) && (fd == 0 || fd == 1)) {
60 snprintf(c, l, "STDIN/STDOUT client");
61 return;
62 }
63
64 snprintf(c, l, "Unknown client");
65 }
66
67 int make_secure_dir(const char* dir) {
68 struct stat st;
69
70 if (mkdir(dir, 0700) < 0)
71 if (errno != EEXIST)
72 return -1;
73
74 if (lstat(dir, &st) < 0)
75 goto fail;
76
77 if (!S_ISDIR(st.st_mode) || (st.st_uid != getuid()) || ((st.st_mode & 0777) != 0700))
78 goto fail;
79
80 return 0;
81
82 fail:
83 rmdir(dir);
84 return -1;
85 }