new tool
[hband-tools.git] / compiled-tools / xdpys.c
blobf1bcf911855154eaa4e0de253ea4868573e52f07
2 #include <X11/Xlib.h>
3 #include <X11/Xos.h>
4 #include <stdlib.h>
5 #include <stdio.h>
6 #include <string.h>
7 #include <signal.h>
8 #include <setjmp.h>
9 #include <err.h>
10 #include <dirent.h>
11 #include <sys/types.h>
13 #define LISTSIZE(x) (sizeof(x)/sizeof(*x)-1)
14 #define DPYNAME_MAXLEN 255
17 static jmp_buf xopendpy;
18 unsigned int timeout = 2;
19 unsigned int verbose = 0;
20 unsigned int found_a_valid_display = 0;
23 void alarm_handler(int sig)
25 siglongjmp(xopendpy, 1);
28 unsigned int is_valid_xdisplay(char* dpyname)
30 Display* dpy;
32 if(verbose) fprintf(stderr, "Opening X display %s\n", dpyname);
34 alarm(timeout);
35 if(!sigsetjmp(xopendpy, 1))
37 dpy = XOpenDisplay(dpyname);
39 else
41 dpy = NULL;
43 alarm(0);
44 if(dpy != NULL)
46 XCloseDisplay(dpy);
47 found_a_valid_display = 1;
48 printf("%s\n", dpyname == NULL ? getenv("DISPLAY") : dpyname);
49 return 1;
51 return 0;
54 int main(int argc, char** argv)
56 Display* dpy;
57 char dpyname[DPYNAME_MAXLEN];
58 unsigned int num;
59 int c;
60 int search_abstract = 1;
61 int search_sockets = 1;
62 int search_inet_max = 30;
63 FILE* fh;
64 char socksbuf[92];
65 DIR* dh;
66 struct dirent* dent;
67 unsigned int u;
70 while((c = getopt(argc, argv, "hvASt:x:")) != -1)
72 switch(c)
74 case 't':
75 timeout = atoi(optarg);
76 break;
77 case 'v':
78 verbose = 1;
79 break;
80 case 'A':
81 search_abstract = 0;
82 break;
83 case 'S':
84 search_sockets = 0;
85 break;
86 case 'x':
87 search_inet_max = atoi(optarg);
88 break;
89 case 'h':
90 printf("Usage: xdpys [-h|-v|-A|-S] [-t <sec>] [-x <max>] [display [display [...]]]\n"
91 " -h this help\n"
92 " -v verbose output to stderr\n"
93 " -A don't test abstract unix sockets\n"
94 " -S don't test unix socket files\n"
95 " -t <n> timeout for individual XDisplay open calls (%d)\n"
96 " -x <n> search this many X.org display in INET namespace (%d)\n",
97 timeout,
98 search_inet_max);
99 _exit(EXIT_SUCCESS);
100 break;
101 case '?':
102 _exit(EXIT_FAILURE);
103 break;
108 signal(SIGALRM, alarm_handler);
110 if(optind >= argc)
112 if(search_abstract)
114 fh = fopen("/proc/net/unix", "r");
115 if(fh != NULL)
117 while(!feof(fh))
119 fgets(socksbuf, 91, fh);
120 // e5d1fa40: 00000002 00000000 00010000 0001 01 187671 @/tmp/.X11-unix/X1003
121 // e697ba80: 00000002 00000000 00010000 0001 01 20247 @/tmp/.X11-unix/X1000
122 if(sscanf(socksbuf, "%*[^ ] %*[^ ] %*[^ ] %*[^ ] %*[^ ] 01 %*[^ ] @/tmp/.X11-unix/X%u", &u) == 1)
124 snprintf(dpyname, DPYNAME_MAXLEN, ":%u", u);
125 is_valid_xdisplay(dpyname);
127 while(socksbuf[strlen(socksbuf)-1] != '\n')
129 fgets(socksbuf, 91, fh);
133 fclose(fh);
136 if(search_sockets)
138 dh = opendir("/tmp/.X11-unix");
139 while((dent = readdir(dh)) != NULL)
141 if(dent->d_type == DT_SOCK && sscanf(dent->d_name, "X%u", &u) == 1)
143 snprintf(dpyname, DPYNAME_MAXLEN, ":%u", u);
144 is_valid_xdisplay(dpyname);
147 closedir(dh);
150 for(num = 0; num < search_inet_max; num++)
152 snprintf(dpyname, DPYNAME_MAXLEN, "localhost:%d", num);
153 is_valid_xdisplay(dpyname);
156 else
158 while(optind < argc)
160 is_valid_xdisplay(argv[optind]);
161 optind++;
165 return found_a_valid_display ? EXIT_SUCCESS : EXIT_FAILURE;