16#include <netinet/in.h>
18#include <sys/socket.h>
27 {
"defNumberVector" },
28 {
"defSwitchVector" },
32static int ndefs =
sizeof(defs) /
sizeof(defs[0]);
42static void usage(
void);
43static void addDevice(
const char *dev);
44static int hasDevice(
const char *dev);
45static int matchPattern(
const char *str,
const char *pattern);
46static void openINDIServer(
void);
47static void getprops(
void);
48static void listenINDI(
void);
49static void onAlarm(
int dummy);
50static int readServerChar(
void);
51static void findDevices(
XMLEle *root);
54static char host_def[] =
"localhost";
55static char *host = host_def;
63static int directfd = -1;
66static char *devpattern = NULL;
68int main(
int ac,
char *av[])
74 while (--ac && **++av ==
'-')
84 fprintf(stderr,
"-d requires open fileno\n");
87 directfd = atoi(*++av);
93 fprintf(stderr,
"Can not combine -d and -h\n");
98 fprintf(stderr,
"-h requires host name\n");
107 fprintf(stderr,
"Can not combine -d and -p\n");
112 fprintf(stderr,
"-p requires tcp port number\n");
121 fprintf(stderr,
"-t requires timeout\n");
124 timeout = atoi(*++av);
131 fprintf(stderr,
"Unknown flag: %c\n", *s);
144 svrwfp = fdopen(directfd,
"w");
145 svrrfp = fdopen(directfd,
"r");
146 if (!svrwfp || !svrrfp)
148 fprintf(stderr,
"Direct fd %d: %s\n", directfd, strerror(
errno));
151 setbuf(svrrfp, NULL);
153 fprintf(stderr,
"Using direct fd %d\n", directfd);
159 fprintf(stderr,
"Connected to %s on port %d\n", host, port);
172 for (
int i = 0; i < devlist.
count; i++)
174 printf(
"%s\n", devlist.
devices[i]);
178 for (
int i = 0; i < devlist.
count; i++)
183 return (devlist.
count > 0 ? 0 : 1);
188 fprintf(stderr,
"Purpose: list devices from an INDI server\n");
189 fprintf(stderr,
"%s\n", GIT_TAG_STRING);
190 fprintf(stderr,
"Usage: %s [options] [device_pattern]\n", me);
191 fprintf(stderr,
" device_pattern may contain \"*\" to match all (beware shell metacharacters).\n");
192 fprintf(stderr,
" Lists all devices if no pattern specified.\n");
193 fprintf(stderr,
"Options:\n");
194 fprintf(stderr,
" -d f : use file descriptor f already open to server\n");
195 fprintf(stderr,
" -h h : alternate host, default is %s\n", host_def);
196 fprintf(stderr,
" -p p : alternate port, default is %d\n",
INDIPORT);
197 fprintf(stderr,
" -t t : max time to wait, default is %d secs\n",
TIMEOUT);
198 fprintf(stderr,
" -v : verbose (cumulative)\n");
199 fprintf(stderr,
"Exit status:\n");
200 fprintf(stderr,
" 0: found at least one device\n");
201 fprintf(stderr,
" 1: no devices found\n");
202 fprintf(stderr,
" 2: real trouble, try repeating with -v\n");
208static void addDevice(
const char *dev)
211 if (devpattern && !matchPattern(dev, devpattern))
224 fprintf(stderr,
"Found device: %s\n", dev);
228static int hasDevice(
const char *dev)
230 for (
int i = 0; i < devlist.
count; i++)
232 if (strcmp(devlist.
devices[i], dev) == 0)
239static int matchPattern(
const char *str,
const char *pattern)
242 if (strcmp(pattern,
"*") == 0)
246 const char *star = strchr(pattern,
WILDCARD);
250 return strcmp(str, pattern) == 0;
254 int prefix_len = star - pattern;
257 if (strncmp(str, pattern, prefix_len) != 0)
265 const char *suffix = star + 1;
266 int suffix_len = strlen(suffix);
267 int str_len = strlen(str);
269 if (str_len < prefix_len + suffix_len)
272 return strcmp(str + str_len - suffix_len, suffix) == 0;
278static void openINDIServer(
void)
280 struct sockaddr_in serv_addr;
285 hp = gethostbyname(host);
288 herror(
"gethostbyname");
293 (void)memset((
char *)&serv_addr, 0,
sizeof(serv_addr));
294 serv_addr.sin_family = AF_INET;
295 serv_addr.sin_addr.s_addr = ((
struct in_addr *)(hp->h_addr_list[0]))->s_addr;
296 serv_addr.sin_port = htons(port);
297 if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
304 if (connect(sockfd, (
struct sockaddr *)&serv_addr,
sizeof(serv_addr)) < 0)
311 svrwfp = fdopen(sockfd,
"w");
312 svrrfp = fdopen(sockfd,
"r");
316static void getprops()
318 fprintf(svrwfp,
"<getProperties version='%g'/>\n",
INDIV);
322 fprintf(stderr,
"Queried properties from server\n");
328static void listenINDI()
333 signal(SIGALRM, onAlarm);
350 fprintf(stderr,
"Bad XML from %s/%d: %s\n", host, port, msg);
357static void onAlarm(
int dummy)
362 for (
int i = 0; i < devlist.
count; i++)
364 printf(
"%s\n", devlist.
devices[i]);
368 for (
int i = 0; i < devlist.
count; i++)
373 exit(devlist.
count > 0 ? 0 : 1);
377static int readServerChar()
379 int c = fgetc(svrrfp);
386 fprintf(stderr,
"INDI server %s/%d disconnected\n", host, port);
391 fprintf(stderr,
"Read %c\n", c);
397static void findDevices(
XMLEle *root)
402 for (
int i = 0; i < ndefs; i++)
404 if (strcmp(tag, defs[i].vec) == 0)
Constants and Data structure definitions for the interface to the reference INDI C API implementation...
const char * findXMLAttValu(XMLEle *ep, const char *name)
Find an XML element's attribute value.
LilXML * newLilXML()
Create a new lilxml parser.
char * tagXMLEle(XMLEle *ep)
Return the tag of an XML element.
void prXMLEle(FILE *fp, XMLEle *ep, int level)
Print an XML element.
XMLEle * readXMLEle(LilXML *lp, int newc, char ynot[])
Process an XML one char at a time.
void delXMLEle(XMLEle *ep)
delXMLEle Delete XML element.
void delLilXML(LilXML *lp)
Delete a lilxml parser.
A little DOM-style library to handle parsing and processing an XML file.