1 /*
2 # This file is part of the Astrometry.net suite.
3 # Licensed under a 3-clause BSD style license - see LICENSE
4 */
5
6 #include <stdlib.h>
7 #include <stdio.h>
8 #include <unistd.h>
9 #include <errno.h>
10 #include <string.h>
11 #include <sys/types.h>
12
13 #ifdef _WIN32 //# Modified by Robert Lancaster for the StellarSolver Internal Library
14 #include <winsock2.h>
15 #include <string.h>
16 #else
17 #include <sys/socket.h>
18 #include <netinet/in.h>
19 #include <arpa/inet.h>
20 #include <netdb.h>
21 #endif
22
23 #include <assert.h>
24
25 #include "solvedclient.h"
26 #include "bl.h"
27
28 static int serveraddr_initialized = 0;
29 static struct sockaddr_in serveraddr;
30 static FILE* fserver = NULL;
31
solvedclient_set_server(char * addr)32 int solvedclient_set_server(char* addr) {
33 char buf[256];
34 char* ind;
35 struct hostent* he;
36 int len;
37 int port;
38 if (fserver) {
39 if (fflush(fserver) ||
40 fclose(fserver)) {
41 fprintf(stderr, "Failed to close previous connection to server.\n");
42 }
43 fserver = NULL;
44 }
45 if (!addr)
46 return -1;
47 #ifdef _WIN32 //# Modified by Robert Lancaster for the StellarSolver Internal Library
48 ind = strstr(addr, ":");
49 #else
50 ind = index(addr, ':');
51 #endif
52 if (!ind) {
53 fprintf(stderr, "Invalid IP:port address: %s\n", addr);
54 return -1;
55 }
56 len = ind - addr;
57 memcpy(buf, addr, len);
58 buf[len] = '\0';
59 he = gethostbyname(buf);
60 if (!he) {
61 #ifdef _WIN32 //# Modified by Robert Lancaster for the StellarSolver Internal Library
62 fprintf(stderr, "Solved server \"%s\" not found.\n", buf);
63 #else
64 fprintf(stderr, "Solved server \"%s\" not found: %s.\n", buf, hstrerror(h_errno));
65 #endif
66 return -1;
67 }
68 if (!serveraddr_initialized) {
69 memset(&serveraddr, 0, sizeof(serveraddr));
70 serveraddr_initialized = 1;
71 }
72 memcpy(&(serveraddr.sin_addr), he->h_addr, he->h_length);
73 port = atoi(ind+1);
74 serveraddr.sin_family = AF_INET;
75 serveraddr.sin_port = htons(port);
76
77 return 0;
78 }
79
connect_to_server()80 static int connect_to_server() {
81 int sock;
82 if (fserver)
83 return 0;
84 sock = socket(PF_INET, SOCK_STREAM, 0);
85 if (sock == -1) {
86 fprintf(stderr, "Couldn't create socket: %s\n", strerror(errno));
87 return -1;
88 }
89 fserver = fdopen(sock, "r+b");
90 if (!fserver) {
91 fprintf(stderr, "Failed to fdopen socket: %s\n", strerror(errno));
92 return -1;
93 }
94 assert(serveraddr_initialized);
95 // gcc with strict-aliasing warns about this cast but it should be okay.
96 if (connect(sock, (struct sockaddr*)&serveraddr, sizeof(serveraddr))) {
97 fprintf(stderr, "Couldn't connect to server: %s\n", strerror(errno));
98 if (fclose(fserver))
99 fprintf(stderr, "Failed to close socket: %s\n", strerror(errno));
100 fserver = NULL;
101 return -1;
102 }
103 return 0;
104 }
105
solvedclient_get(int filenum,int fieldnum)106 int solvedclient_get(int filenum, int fieldnum) {
107 char buf[256];
108 const char* solvedstr = "solved";
109 int nchars;
110 int solved;
111
112 if (connect_to_server())
113 return -1;
114 nchars = sprintf(buf, "get %i %i\n", filenum, fieldnum);
115 if ((fwrite(buf, 1, nchars, fserver) != nchars) ||
116 fflush(fserver)) {
117 fprintf(stderr, "Failed to write request to server: %s\n", strerror(errno));
118 fclose(fserver);
119 fserver = NULL;
120 return -1;
121 }
122 if (!fgets(buf, 256, fserver)) {
123 fprintf(stderr, "Couldn't read response: %s\n", strerror(errno));
124 fclose(fserver);
125 fserver = NULL;
126 return -1;
127 }
128 solved = (strncmp(buf, solvedstr, strlen(solvedstr)) == 0);
129 return solved;
130 }
131
solvedclient_set(int filenum,int fieldnum)132 void solvedclient_set(int filenum, int fieldnum) {
133 char buf[256];
134 int nchars;
135 if (connect_to_server())
136 return;
137 nchars = sprintf(buf, "set %i %i\n", filenum, fieldnum);
138 if ((fwrite(buf, 1, nchars, fserver) != nchars) ||
139 fflush(fserver)) {
140 fprintf(stderr, "Failed to send command (%s) to solvedserver: %s\n", buf, strerror(errno));
141 return;
142 }
143 // wait for response.
144 if (!fgets(buf, 256, fserver)) {
145 fprintf(stderr, "Couldn't read response: %s\n", strerror(errno));
146 fclose(fserver);
147 fserver = NULL;
148 return;
149 }
150 }
151
solvedclient_get_fields(int filenum,int firstfield,int lastfield,int maxnfields)152 il* solvedclient_get_fields(int filenum, int firstfield, int lastfield,
153 int maxnfields) {
154 char* buf;
155 int bufsize;
156 il* list;
157 char* cptr;
158 int fld;
159 int nchars;
160
161 if (connect_to_server())
162 return NULL;
163 bufsize = 100 + 10 * (maxnfields ? maxnfields : (1 + lastfield - firstfield));
164 buf = malloc(bufsize);
165 nchars = sprintf(buf, "getall %i %i %i %i\n", filenum, firstfield,
166 lastfield, maxnfields);
167 if ((fwrite(buf, 1, nchars, fserver) != nchars) ||
168 fflush(fserver)) {
169 fprintf(stderr, "Failed to send command (%s) to solvedserver: %s\n", buf, strerror(errno));
170 return NULL;
171 }
172 // wait for response.
173 if (!fgets(buf, bufsize, fserver)) {
174 fprintf(stderr, "Couldn't read response: %s\n", strerror(errno));
175 fclose(fserver);
176 fserver = NULL;
177 free(buf);
178 return NULL;
179 }
180 if (sscanf(buf, "unsolved %i%n", &fld, &nchars) != 1) {
181 fprintf(stderr, "Couldn't parse response: %s\n", buf);
182 free(buf);
183 return NULL;
184 }
185 if (fld != filenum) {
186 fprintf(stderr, "Expected file number %i, not %i.\n", filenum, fld);
187 free(buf);
188 return NULL;
189 }
190 cptr = buf + nchars;
191 list = il_new(256);
192 while (*cptr && *cptr != '\n') {
193 if (sscanf(cptr, " %i%n", &fld, &nchars) != 1) {
194 fprintf(stderr, "Couldn't parse response: %s\n", buf);
195 il_free(list);
196 free(buf);
197 return NULL;
198 }
199 cptr += nchars;
200 il_append(list, fld);
201 }
202 free(buf);
203 return list;
204 }
205