/*
* Copyright (c) 1990, 2015, Oracle and/or its affiliates. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/*
* winsysck - determine which window system protocols are available
*
* usage: winsysck [ -va ] [ -display display_name ] protocol [...]
*
* options:
* -a check every protocol listed, rather than stopping after
* the first one.
* -v print the first available protocol (or every available
* protocol, with the -a option) to stdout.
* -display display_name
* use the display display_name for X11 connections instead of
* the one specified by the $DISPLAY environment variable.
* -timeout seconds
* The timeout option sets the number of seconds before
* the winsysck will time out.
*
* protocols:
* x11
* The X11 protocol.
* news
* The NeWS protocol.
* x11news
* Both the X11 and the NeWS protocols, and both connect to
* the same server.
* sunview
* The SunView protocol.
*
* NOTE: Since news, x11news, and sunview have been unsupported for over
* a decade, we no longer actually check for them, but always return false.
*
* exit status:
* 0 if any listed protocols are available
* 1 if no listed protocols are available
* 2 usage error
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/time.h>
#include <signal.h>
#include <unistd.h>
static char* cmdname;
static void
usage (void) {
fprintf(stderr, "usage: %s %s\n\t%s\n", cmdname,
"[-va] [-display display_name] [-timeout seconds] protocol [...]",
"protocol can be one of: x11 news x11news sunview");
exit(2);
}
/*
* Keep track of what protocols we're checking, and in what order.
*/
#define PROTO_NONE 0
#define PROTO_X11 1
#define PROTO_NeWS 2
#define PROTO_X11NeWS 3
#define PROTO_SunView 4
#define N_PROTO 4
static int proto_list[N_PROTO], n_proto;
static void
AddProto(int proto)
{
int i;
for (i=0; i<N_PROTO; i++) {
if (proto_list[i]==proto) {
return;
}
}
proto_list[n_proto++]=proto;
}
/*
* Keep track of the options specified.
*/
static int verbose, showall, timeout = 0;
static char* display_name=NULL;
/*
* Parse the options.
*/
static void
Parse (int argc, char* argv[])
{
for (;argc > 1; argv++, argc--) {
if (argv[1][0] == '-') {
if (!strcmp(argv[1], "-display")) {
display_name=argv[2];
argv++;
argc--;
continue;
}
if (!strcmp(argv[1], "-timeout")) {
timeout = atoi(argv[2]);
argv++;
argc--;
continue;
}
for (; argv[1][1]; argv[1]++) {
switch (argv[1][1]) {
case 'a':
showall++;
break;
case 'v':
verbose++;
break;
default:
fprintf(stderr, "%s: -%c: unknown option\n",
cmdname,argv[1][1]);
usage();
}
}
}
else {
if (!strcmp(argv[1], "x11")) {
AddProto(PROTO_X11);
} else if (!strcmp(argv[1], "news")) {
AddProto(PROTO_NeWS);
} else if (!strcmp(argv[1], "x11news")) {
AddProto(PROTO_X11NeWS);
} else if (!strcmp(argv[1], "sunview")) {
AddProto(PROTO_SunView);
} else {
fprintf(stderr, "%s: %s: unknown protocol\n",
cmdname,argv[1]);
usage();
}
}
}
if (!n_proto) {
fprintf(stderr, "%s: no protocols specified\n",
cmdname);
usage();
}
}
/* Last remnants of x11-procs.c */
#include <X11/Xlib.h>
#include <X11/Xos.h>
static Display *display=NULL;
static void OnAlarm(int i)
{
fprintf(stderr, "winsysck timeout\n");
exit(1);
}
static int
ConnectToX (const char* display_name)
{
if(timeout > 0){
signal(SIGALRM, OnAlarm);
alarm(timeout);
}
display=XOpenDisplay(display_name);
if(timeout > 0)
alarm(0);
return((display != NULL));
}
static int
DisconnectFromX (void) {
XCloseDisplay(display);
return(1);
}
/*
* Try connecting via the specified protocols.
*/
static void
Probe(void)
{
int i, found=0;
for(i=0; (i < N_PROTO) && (proto_list[i] != PROTO_NONE); i++) {
switch (proto_list[i]) {
case PROTO_X11:
if (ConnectToX(display_name)) {
found++;
if (verbose) printf("%s\n","x11");
DisconnectFromX();
if (!showall) exit(0);
}
break;
case PROTO_NeWS:
case PROTO_X11NeWS:
case PROTO_SunView:
/* Don't even bother */
break;
default:
fprintf(stderr, "%s: WSGO: proto_list[%d]==%d\n",
cmdname,i,proto_list[i]);
}
}
exit(!found);
}
int
main (int argc, char* argv[])
{
cmdname=argv[0];
Parse(argc,argv);
Probe();
exit(0);
}