Use command line parsing so we can specify different hostnames
[condor-woldlab.git] / src / castor_load.c
1 #define _POSIX_SOURCE 1
2 #define _XOPEN_SOURCE 500
3
4 #include <errno.h>
5 #include <getopt.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <sys/types.h>
10 #include <sys/socket.h>
11 #include <netdb.h>
12 #include <unistd.h>
13
14 #define BUF_SIZE 512
15
16 #define ERROR -1
17 #define SUCCESS 0
18
19 int usage(const char *cmd, int st);
20 int try_connecting(struct addrinfo *address);
21 int generate_condor_variables(int sock);
22
23 int main(int argc, char **argv) {
24   int sock = 0;
25   int rv = 0;
26   struct addrinfo hints;
27   struct addrinfo *address = 0;
28
29   int c;
30   int optidx = 0;
31   char *hostname = NULL;
32   char *port = NULL;
33   struct option ol[] =
34   {
35     { "host", required_argument, 0, 'h' },
36     { "port", required_argument, 0, 'p' },
37     { NULL, 0, 0, 0 }
38   };
39
40   memset(&hints, 0, sizeof(struct addrinfo));
41   hints.ai_family = AF_INET;
42   hints.ai_socktype = SOCK_STREAM;
43
44   if (argc < 5)
45     return usage(argv[0], -1);
46
47   while ((c = getopt_long(argc, argv, "h:p:", ol, &optidx)) != -1)
48   {
49     switch(c)
50     {
51       case 'h':
52         hostname = strdup(optarg);
53         break;
54
55       case 'p':
56         port = strdup(optarg);
57         break;
58
59       default:
60         fprintf(stderr, "bad option: %c\n", c);
61         return -1;
62     }
63   }
64
65   rv = getaddrinfo(hostname, port, &hints, &address);
66   if (rv != 0) {
67     fprintf(stderr, "Error looking up hostname, %d\n", errno);
68     exit(ERROR);
69   }
70
71   sock = try_connecting(address);
72   if (sock == -1) {
73     fprintf(stderr, "Unable to connect");
74     exit(ERROR);
75   }
76
77   /* now that we have a connection */
78   if (address != NULL) {
79     freeaddrinfo(address);
80   }
81
82   if (generate_condor_variables(sock) == -1) {
83     exit(ERROR);
84   }
85   exit(SUCCESS);
86 }
87
88 int usage(const char *cmd, int st)
89 {
90   fprintf(stderr, "usage:\n  %s [options]\n\n", cmd);
91   fprintf(stderr, "\t-h, --host\tHostname to connect to\n");
92   fprintf(stderr, "\t-p, --port\tPort to connect to\n");
93   fprintf(stderr, "\n");
94   return st;
95 }
96
97 int try_connecting(struct addrinfo *address)
98 {
99   int sock = 0;
100   int rv;
101   struct addrinfo *addr_ptr = 0;
102
103   for (addr_ptr = address; addr_ptr != NULL; addr_ptr = addr_ptr->ai_next) {
104     sock = socket(addr_ptr->ai_family, 
105                   addr_ptr->ai_socktype,
106                   addr_ptr->ai_protocol);
107     if (sock == -1) {
108       continue;
109     }
110     
111     rv = connect(sock, addr_ptr->ai_addr, addr_ptr->ai_addrlen);
112     if (rv != -1) {
113       /* we connected to something, return it */
114       return sock;
115     }
116     close(sock);
117   }
118   return (-1);
119 }
120
121 int generate_condor_variables(int sock)
122 {
123   int nread = 0;
124   int rv;
125   char buf[BUF_SIZE];
126  
127   memset(buf, 0, BUF_SIZE);
128   nread = read(sock, buf, BUF_SIZE-1);
129   if (nread == -1) {
130     fprintf(stderr, "read error");
131     return -1;
132   }
133   rv = fprintf(stdout, "castor_load = %s", buf);
134   if (rv == 0) {
135     return -1;
136   }
137   rv = fprintf(stdout, "--\n");
138   if (rv == 0) {
139     return -1;
140   }
141   return 0;
142 }