1 #include "raa_acnuc.h"
2 #include "parser.h"
3 
4 #include <limits.h>
5 #include <unistd.h>
6 #include <errno.h>
7 #include <stdarg.h>
8 #include <time.h>
9 #if defined(unix) || defined(__APPLE__)
10 #include <netdb.h>
11 #include <sys/types.h>
12 #include <netinet/in.h>
13 #include <sys/socket.h>
14 #include <sys/time.h>
15 #include <termios.h>
16 #elif defined(WIN32)
17 #if _WIN32_WINNT < 0x0501
18 #define _WIN32_WINNT  0x0501
19 #endif
20 #include <Winsock2.h>
21 #include <Ws2tcpip.h>  // for getaddrinfo, freeaddrinfo, struct addrinfo
22 //#include <Wspiapi.h>
23 #endif
24 
25 
26 #define SERVER_UPDATE_MESSAGE "acnuc stop for update\n"
27 /* seules fctions utilisables hors de ce fichier pour ecrire sur socket */
28 int sock_fputs(raa_db_access *f, const char *l);
29 int sock_flush(raa_db_access *f);
30 
31 /* some prototypes */
32 void raa_acnucclose(raa_db_access *raa_current_db);
33 static char *protect_quotes(char *name);
34 static void raa_free_matchkeys(raa_db_access *raa_current_db);
35 
36 /* needed functions */
37 extern char init_codon_to_aa(char *codon, int gc);
38 char codaa(char *codon, int code);
39 void *prepare_sock_gz_r(FILE *sockr);
40 char *z_read_sock(void *v);
41 int close_sock_gz_r(void *v);
42 char *unprotect_quotes(char *name);
43 
44 
45 /* global variables */
46 void (*raa_error_mess_proc)(raa_db_access *, char *) = NULL;
47 
48 #define MAX_RDSHRT 50 /* max short list length read in one time */
49 
50 #if defined(WIN32)
51 
socket_getc(raa_db_access * raa_current_db,SOCKET f)52 static int socket_getc(raa_db_access *raa_current_db, SOCKET f)
53 {
54 int q;
55 
56 if(raa_current_db->sock_input_pos < raa_current_db->sock_input_end) {
57 	return *(raa_current_db->sock_input_pos++);
58 	}
59 q = recv(f, raa_current_db->sock_input, SOCKBUFS, 0);
60 if(q == 0 || q == SOCKET_ERROR) return EOF;
61 raa_current_db->sock_input_end = raa_current_db->sock_input + q;
62 raa_current_db->sock_input_pos = raa_current_db->sock_input;
63 return *(raa_current_db->sock_input_pos++);
64 }
65 
66 
sock_fgets(raa_db_access * raa_current_db,char * line,int len)67 static char *sock_fgets(raa_db_access  *raa_current_db, char *line, int len)
68 {
69 int c;
70 char *p;
71 
72 p = line;
73 while(len > 1) {
74 	c = socket_getc(raa_current_db,  (SOCKET)(raa_current_db->raa_sockfdr) );
75 	if(c == EOF) {
76 		if(p == line) return NULL;
77 		break;
78 		}
79 	*(p++) = c;
80 	if(c == '\n') break;
81 	len--;
82 	}
83 *p = 0;
84 return line;
85 }
86 
87 
mswin_sock_flush(raa_db_access * raa_current_db)88 static int mswin_sock_flush(raa_db_access  *raa_current_db)
89 {
90 int w;
91 char *p;
92 
93 p = raa_current_db->sock_output;
94 while(raa_current_db->sock_output_lbuf > 0) {
95 	w = send((SOCKET)raa_current_db->raa_sockfdw, p, raa_current_db->sock_output_lbuf, 0);
96 	raa_current_db->sock_output_lbuf -= w;
97 	p += w;
98 	}
99 return 0;
100 }
101 
102 
sock_flush(raa_db_access * raa_current_db)103 int sock_flush(raa_db_access  *raa_current_db)
104 {
105 if(raa_current_db == NULL) return 0;
106 return mswin_sock_flush(raa_current_db);
107 }
108 
109 
sock_fputs(raa_db_access * raa_current_db,const char * s)110 int sock_fputs(raa_db_access  *raa_current_db, const char *s)
111 {
112 int l, r;
113 
114 if(raa_current_db == NULL) return 0;
115 l = strlen(s);
116 while(raa_current_db->sock_output_lbuf + l > SOCKBUFS) {
117 	r = SOCKBUFS - raa_current_db->sock_output_lbuf;
118 	memcpy(raa_current_db->sock_output + raa_current_db->sock_output_lbuf, s, r);
119 	raa_current_db->sock_output_lbuf += r;
120 	l -= r;
121 	s += r;
122 	mswin_sock_flush(raa_current_db);
123 	}
124 if(l > 0) {
125 	memcpy(raa_current_db->sock_output + raa_current_db->sock_output_lbuf, s, l);
126 	raa_current_db->sock_output_lbuf += l;
127 	}
128 return 0;
129 }
130 
131 
132 
133 #else
134 
sock_fputs(raa_db_access * raa_current_db,const char * s)135 int sock_fputs(raa_db_access  *raa_current_db, const char *s)
136 {
137 if(raa_current_db == NULL) return EOF;
138 return fputs(s, raa_current_db->raa_sockfdw);
139 }
140 
sock_flush(raa_db_access * raa_current_db)141 int sock_flush(raa_db_access  *raa_current_db)
142 {
143 if(raa_current_db == NULL) return EOF;
144 return fflush(raa_current_db->raa_sockfdw);
145 }
146 
147 #endif /* WIN32 */
148 
149 
sock_printf(raa_db_access * raa_current_db,const char * fmt,...)150 static int sock_printf(raa_db_access  *raa_current_db, const char *fmt, ...)
151 {
152 va_list ap;
153 int retval;
154 
155 va_start(ap, fmt);
156 vsprintf(raa_current_db->buffer, fmt, ap);
157 retval = sock_fputs(raa_current_db, raa_current_db->buffer);
158 va_end(ap);
159 return retval;
160 }
161 
162 
163 
164 /******************************************************************/
165 /* lit une ligne au plus de la socket et transfere le resultat dans une chaine char *   */
166 
read_sock_tell(raa_db_access * raa_current_db,int * wascompleteline)167 static char *read_sock_tell(raa_db_access *raa_current_db, int *wascompleteline) {
168   int lnbuf, isfull;
169   char *p ;
170 
171   if(raa_current_db == NULL || raa_current_db->was_here) return NULL;
172   sock_flush(raa_current_db); /* tres important */
173   isfull = FALSE;
174 #if defined(WIN32)
175   p = sock_fgets(raa_current_db, raa_current_db->buffer, sizeof(raa_current_db->buffer));
176 #else
177   p = fgets(raa_current_db->buffer, sizeof(raa_current_db->buffer), raa_current_db->raa_sockfdr);
178 #endif
179   if(p == NULL || strcmp(p, SERVER_UPDATE_MESSAGE) == 0) {
180 	if(!raa_current_db->was_here) {
181 		raa_current_db->was_here = TRUE;
182 		*raa_current_db->buffer = 0;
183 		if(raa_current_db != NULL && raa_current_db->dbname != NULL) {
184 			sprintf(raa_current_db->buffer, "%s: ", raa_current_db->dbname);
185 			}
186 		strcat(raa_current_db->buffer, ( p == NULL ?
187   			"Error: connection to acnuc server is down. Please try again."
188   			:
189 			"Error: acnuc server is down for database update. Please try again later." )
190 			);
191 		if(raa_error_mess_proc == NULL) {
192 			fprintf(stderr, "%s\n", raa_current_db->buffer);
193 			}
194 		else (*raa_error_mess_proc)(raa_current_db, raa_current_db->buffer);
195 		}
196 	return NULL;
197 	}
198 
199   raa_current_db->was_here = FALSE;
200   lnbuf = strlen(raa_current_db->buffer);
201   p = raa_current_db->buffer + lnbuf - 1;
202   if(*p ==  '\n') isfull = TRUE;
203   while(p >= raa_current_db->buffer && (*p ==  '\n' || *p == '\r') ) *(p--) = 0;
204   if(wascompleteline != NULL) *wascompleteline = isfull;
205   return raa_current_db->buffer;
206 }
207 
208 
read_sock(raa_db_access * raa_current_db)209 char *read_sock(raa_db_access *raa_current_db) /* lit une ligne entiere, rend ligne dans memoire privee */
210 {
211 int wasfull, l2, l = 0;
212 char *p;
213 
214 do	{
215 	p = read_sock_tell(raa_current_db, &wasfull);
216 	if(p == NULL) return NULL;
217 	l2 = strlen(p);
218 	if(l + l2 +  1 > raa_current_db->max_full_line) {
219 		raa_current_db->max_full_line = l + l2 +  100;
220 		raa_current_db->full_line = (char *)realloc(raa_current_db->full_line, raa_current_db->max_full_line);
221 		}
222 	memcpy(raa_current_db->full_line + l, p, l2);
223 	l += l2;
224 	}
225 while(! wasfull);
226 raa_current_db->full_line[l] = 0;
227 return raa_current_db->full_line;
228 }
229 
230 
read_sock_timeout(raa_db_access * raa_current_db,int timeout_ms)231 char *read_sock_timeout(raa_db_access *raa_current_db, int timeout_ms)
232 {
233 fd_set readfds;
234 struct timeval tout;
235 int err;
236 
237 #if defined(WIN32)
238 SOCKET fd;
239 if(raa_current_db == NULL) return NULL;
240 fd = (SOCKET)(raa_current_db->raa_sockfdr);
241 #else
242 int fd;
243 if(raa_current_db == NULL) return NULL;
244 fd = fileno(raa_current_db->raa_sockfdr);
245 #endif
246 FD_ZERO(&readfds);
247 FD_SET(fd, &readfds);
248 tout.tv_sec = timeout_ms / 1000; tout.tv_usec = 1000*(timeout_ms % 1000);
249 err = select(fd + 1, &readfds, NULL, NULL, &tout);
250 if(err > 0 && FD_ISSET(fd, &readfds) ) {
251 	return read_sock(raa_current_db);
252 	}
253 return NULL;
254 }
255 
256 enum {errservname=1, /* bad server name */
257 cantopensocket,  /* 2 error opening socket */
258 unknowndb,  /* 3 not in list of known dbs */
259 unavailabledb,  /* 4 db is currently unavailable */
260 dbisopen,  /* 5 a db is already open and was not closed */
261 badpsswd,  /* 6 bad password for protected db */
262 nomemory,  /* 7 not enough memory */
263 badracnuc,  /* 8 enviroment variables racnuc or acnuc undefined or inadequate */
264 nosocket /* 9 no socket was opened yet */
265 };
266 
raa_acnucopen(const char * clientid,raa_db_access ** psock)267 int raa_acnucopen (const char *clientid, raa_db_access **psock)
268 /* opens the acnuc db using the environment variable racnuc, or, if undefined, acnuc,
269 that should be defined to an url of the form
270 raa://pbil.univ-lyon1.fr:5558/embl
271 clientid: NULL or a string identifying the client
272 */
273 {
274 char *serveurName, *db_name, *p;
275 int port, err;
276 
277 if( (p = getenv("racnuc")) == NULL) p = getenv("acnuc");
278 if(p == NULL) return badracnuc;
279 err = raa_decode_address(p, &serveurName, &port, &db_name);
280 if(err) return badracnuc;
281 err = raa_acnucopen_alt (serveurName,  port, db_name, clientid, psock);
282 free(serveurName);
283 if (db_name) free(db_name);
284 return err;
285 }
286 
287 
raa_acnucopen_alt(const char * serveurName,int port,const char * db_name,const char * clientid,raa_db_access ** p)288 int raa_acnucopen_alt (const char *serveurName, int port, const char *db_name, const char *clientid, raa_db_access **p)
289 /*
290 clientid: NULL or a string identifying the client
291 */
292 {
293 int err;
294 
295  err = raa_open_socket(serveurName, port, clientid, p);
296  if(err != 0) return err;
297  err = raa_opendb(*p, db_name);
298  if(err != 0) {
299   	free(*p);
300  	}
301  return err;
302  }
303 
304 
raa_open_socket(const char * serveurName,int port,const char * clientid,raa_db_access ** psock)305 int raa_open_socket(const char *serveurName, int port, const char *clientid, raa_db_access **psock)
306 /*
307 clientid: NULL or a string identifying the client
308 */
309 {
310   raa_db_access *raa_current_db;
311   struct addrinfo *ai;
312   char *reponse, portstring[10];
313   int err;
314 #ifdef WIN32
315 WSADATA mywsadata;
316 SOCKET raa_snum;
317 #else
318 int raa_snum;
319 #endif
320 
321 raa_current_db = (raa_db_access *)calloc(1, sizeof(raa_db_access));
322 if(raa_current_db == NULL) return nomemory; /* not enough memory */
323   /* cr�ation de la socket */
324 #ifdef WIN32
325   err = WSAStartup(MAKEWORD(2,2), &mywsadata); /* indispensable avant utilisation socket */
326   if (err == 0) raa_snum = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, (GROUP)0, 0);
327   if (err != 0 || raa_snum == INVALID_SOCKET) {
328   	free(raa_current_db);
329   	return cantopensocket;
330   	}
331 #else
332   raa_snum = socket(AF_INET, SOCK_STREAM, 0);
333   if (raa_snum == -1) {
334   	free(raa_current_db);
335   	return cantopensocket;
336   	}
337 #endif
338 /* cr�ation de deux flux type FILE * */
339 #if defined(WIN32)
340 raa_current_db->raa_sockfdr = (FILE *)raa_snum;
341 raa_current_db->raa_sockfdw = (FILE *)raa_snum;
342 #else
343 raa_current_db->raa_sockfdr = fdopen(raa_snum,"r");
344 raa_current_db->raa_sockfdw = fdopen(raa_snum,"a");
345 #endif
346 
347   sprintf(portstring, "%d", port);
348   err = getaddrinfo(serveurName, portstring, NULL, &ai);
349   if (err) {
350     free(raa_current_db);
351     return errservname;
352     }
353   err = connect(raa_snum, ai->ai_addr, ai->ai_addrlen);
354   freeaddrinfo(ai);
355 
356  if (err != 0) {
357   	free(raa_current_db);
358  	return cantopensocket;
359  	}
360   // read first reply from the server
361   reponse = read_sock_timeout(raa_current_db, 1000*60 /* 1 min */);
362   if(reponse == NULL || strcmp(reponse, "OK acnuc socket started") != 0) {
363   	free(raa_current_db);
364  	return cantopensocket;
365  	}
366  if(clientid != NULL) {
367  	sock_printf(raa_current_db, "clientid&id=\"%s\"\n", clientid);
368 	reponse=read_sock(raa_current_db);
369 	if(reponse == NULL) {
370   		free(raa_current_db);
371 		return cantopensocket;
372 		}
373 	}
374 *psock = raa_current_db;
375  return 0;
376 }
377 
378 
379 extern void raa_MD5String (char *in_string, char out_digest[33]);
380 #define default_raa_maxlists  50
381 int raa_maxlists = default_raa_maxlists; // can be changed by caller of raa_opendb_pw() before the call
382 
raa_opendb_pw(raa_db_access * raa_current_db,const char * db_name,void * ptr,char * (* getpasswordf)(void *))383 int raa_opendb_pw(raa_db_access *raa_current_db, const char *db_name, void *ptr, char *(*getpasswordf)(void *) )
384 /*
385 getpasswordf: pointer to function that gets called if a password is needed
386 ptr: pointer to data passed to the getpasswordf function
387 return values :
388     3    not in list of known dbs
389     4    db is unavailable
390     5    a db is already open
391     6    failed password-based authorization
392 
393 */
394 {
395 Reponse *rep;
396 char *reponse, *code, *p, *challenge;
397 int codret, totspecs, totkeys, i;
398 
399 if(raa_current_db == NULL) return nosocket;
400  sock_printf(raa_current_db, "acnucopen&db=%s&maxlists=%d\n", db_name, raa_maxlists);
401  raa_maxlists = default_raa_maxlists; // reset to default in prevision of future raa_opendb_pw() calls
402  reponse=read_sock(raa_current_db);
403  if(reponse == NULL) return nosocket;
404  rep=initreponse();
405  parse(reponse,rep);
406  code=val(rep,"code");
407  codret=atoi(code);
408  free(code);
409  if(codret == 6) {
410 	char reply[33], tmp[300];
411 	char *password = NULL;
412 	clear_reponse(rep);
413 	if(getpasswordf != NULL) password = getpasswordf(ptr);
414 	if(password == NULL) return badpsswd;
415 	challenge = reponse + 17;
416 	/* reply = MD5 of challenge:db_name:MD5(password) */
417 	raa_MD5String(password, reply);
418 	memset(password, 0, strlen(password));
419 	sprintf(tmp, "%s:%s:%s", challenge, db_name, reply);
420 	raa_MD5String(tmp, reply);
421 	memset(tmp, 0, strlen(tmp));
422 	sock_printf(raa_current_db, "reply=%s\n", reply);
423 	reponse = read_sock(raa_current_db);
424 	rep=initreponse();
425 	parse(reponse,rep);
426 	code=val(rep,"code");
427 	codret=atoi(code);
428 	free(code);
429 	}
430 if (codret != 0) {
431 	clear_reponse(rep);
432  	return codret;
433  	}
434 
435   /* initialiser les champs non nuls */
436   raa_current_db->gfrag_data.l_nseq_buf = INT_MAX;
437   raa_current_db->nextelt_data.current_rank = -1;
438   raa_current_db->nextelt_data.previous = -2;
439   raa_current_db->readshrt_data.shrt_begin = S_BUF_SHRT - 1;
440 #ifdef WIN32
441   raa_current_db->sock_input_pos = raa_current_db->sock_input; raa_current_db->sock_input_end = raa_current_db->sock_input;
442 #endif
443   p = val(rep,"type");
444 raa_current_db->dbname = strdup(db_name);
445 raa_current_db->genbank = raa_current_db->embl = raa_current_db->swissprot =
446 	raa_current_db->nbrf = FALSE;
447 if(p != NULL) {
448  	if(strcmp(p, "GENBANK") == 0) raa_current_db->genbank = TRUE;
449  	else if(strcmp(p, "EMBL") == 0) raa_current_db->embl = TRUE;
450  	else if(strcmp(p, "SWISSPROT") == 0) raa_current_db->swissprot = TRUE;
451  	else if(strcmp(p, "NBRF") == 0) raa_current_db->nbrf = TRUE;
452  	free(p);
453  	}
454 p = val(rep,"totseqs");
455 raa_current_db->nseq = atoi(p);
456 free(p);
457 p = val(rep,"totspecs");
458 totspecs = atoi(p);
459 free(p);
460 p = val(rep,"totkeys");
461 totkeys = atoi(p);
462 free(p);
463 raa_current_db->maxa=(totspecs > totkeys ? totspecs : totkeys);
464 raa_current_db->longa=(raa_current_db->maxa-1)/(8 * sizeof(int))+1;
465 
466 /* default values useful if talking to old server */
467 	raa_current_db->WIDTH_SMJ = 20;
468 	raa_current_db->L_MNEMO = 16;
469 	raa_current_db->WIDTH_BIB = 40;
470 	raa_current_db->WIDTH_AUT = 20;
471 	raa_current_db->WIDTH_SP = 40;
472 	raa_current_db->WIDTH_KW = 40;
473 	raa_current_db->lrtxt = 60;
474 	raa_current_db->SUBINLNG=63;
475         raa_current_db->VALINSHRT2=0;
476 	raa_current_db->ACC_LENGTH=13; /* conservative value */
477 p = val(rep,"L_MNEMO");
478 if(p != NULL) { raa_current_db->L_MNEMO = atoi(p); free(p); }
479 p = val(rep,"WIDTH_SP");
480 if(p != NULL) { raa_current_db->WIDTH_SP = atoi(p); free(p); }
481 p = val(rep,"WIDTH_KW");
482 if(p != NULL) { raa_current_db->WIDTH_KW = atoi(p); free(p); }
483 p = val(rep,"WIDTH_AUT");
484 if(p != NULL) { raa_current_db->WIDTH_AUT = atoi(p); free(p); }
485 p = val(rep,"WIDTH_BIB");
486 if(p != NULL) { raa_current_db->WIDTH_BIB = atoi(p); free(p); }
487 p = val(rep,"WIDTH_SMJ");
488 if(p != NULL) { raa_current_db->WIDTH_SMJ = atoi(p); free(p); }
489 p = val(rep,"ACC_LENGTH");
490 if(p != NULL) { raa_current_db->ACC_LENGTH = atoi(p); free(p); }
491 p = val(rep,"lrtxt");
492 if(p != NULL) { raa_current_db->lrtxt = atoi(p); free(p); }
493 p = val(rep,"SUBINLNG");
494 if(p != NULL) {
495 	raa_current_db->SUBINLNG = atoi(p);
496 	free(p);
497 	raa_current_db->rlng_buffer = (struct rlng *)calloc((raa_current_db->SUBINLNG + 1), sizeof(int));
498 	}
499 p = val(rep,"VALINSHRT2");
500 if (p != NULL) {
501   raa_current_db->VALINSHRT2 = atoi(p); free(p);
502 }
503   int valinshrt = (raa_current_db->VALINSHRT2 ? raa_current_db->VALINSHRT2 : 1);
504     for (i = raa_sub_of_bib; i <= raa_acc_of_loc; i++) {
505       int size = 100 * valinshrt;
506       raa_current_db->readshrt2_data[i] = (struct shrt2_list*)malloc(sizeof(int) * (size + 4));
507       raa_current_db->readshrt2_data[i]->size = size;
508       raa_current_db->readshrt2_data[i]->length = 0;
509       raa_current_db->readshrt2_data[i]->point = 0;
510       raa_current_db->readshrt2_data[i]->next = 0;
511     }
512 p = val(rep,"version");
513 if (p != NULL) { raa_current_db->version_string = p; }
514 
515 clear_reponse(rep);
516 return 0;
517 }
518 
519 
raa_opendb(raa_db_access * raa_current_db,const char * db_name)520 int raa_opendb(raa_db_access *raa_current_db, const char *db_name)
521 {
522 return raa_opendb_pw(raa_current_db, db_name, NULL, NULL);
523 }
524 
525 
raa_decode_address(char * url,char ** p_ip_name,int * socket,char ** p_remote_db)526 int raa_decode_address(char *url, char **p_ip_name, int *socket, char **p_remote_db)
527 /* decode syntax such as raa://pbil.univ-lyon1.fr:5557/embl
528 return !=0 if error
529 */
530 {
531 char *p, *q;
532 char *ip_name;
533 char *remote_db;
534 
535 p = url;
536 if(p == NULL) return 1;
537 if( (q = strstr(url, "://") ) != NULL ) p = q + 3;
538 q = strchr(p, ':');
539 if(q == NULL) return 1;
540   ip_name = (char*)malloc(q-p+1);
541 memcpy(ip_name, p, q - p); ip_name[q - p] = 0;
542 if(p_ip_name != NULL) *p_ip_name = ip_name;
543 if(socket != NULL) *socket = atoi(q+1);
544 if(p_remote_db == NULL) return 0;
545 q = strchr(p, '/');
546 if(q != NULL) {
547 	q++;
548 	while(*q == ' ') q++;
549 	if(*q == 0) *p_remote_db = NULL;
550 	else 	{
551 		remote_db = strdup(q);
552 		*p_remote_db = remote_db;
553 		}
554 	}
555 else *p_remote_db = NULL;
556 return 0;
557 }
558 
559 
fill_gfrag_buf(raa_db_access * raa_current_db,int nsub,int first)560 static int fill_gfrag_buf(raa_db_access *raa_current_db, int nsub, int first)
561 {
562 char *p, *line;
563 int lu, l, wasfull;
564 
565 sock_printf(raa_current_db,"gfrag&number=%d&start=%d&length=%d\n", nsub, first, RAA_GFRAG_BSIZE);
566 /* retour:  length=xx&...the seq...\n */
567 line = read_sock_tell(raa_current_db, &wasfull);
568 if(line == NULL) return 0;
569 if(strncmp(line, "length=", 7) != 0 || (p = strchr(line, '&')) == NULL ) {
570 	return 0;
571 	}
572 lu = strlen(++p);
573 memcpy(raa_current_db->gfrag_data.buffer, p, lu);
574 while(! wasfull) {
575 	line = read_sock_tell(raa_current_db, &wasfull);
576 	if(line == NULL) break;
577 	l = strlen(line);
578 	if(lu+l <= RAA_GFRAG_BSIZE) memcpy(raa_current_db->gfrag_data.buffer + lu, line, l);
579 	lu += l;
580 	}
581 raa_current_db->gfrag_data.buffer[lu] = 0;
582 return lu;
583 }
584 
585 
586 
raa_gfrag(raa_db_access * raa_current_db,int nsub,int first,int lfrag,char * dseq)587 int raa_gfrag(raa_db_access *raa_current_db, int nsub, int first, int lfrag, char *dseq)
588 {
589 int lu, piece;
590 char *debut;
591 
592 if(raa_current_db == NULL) return 0;
593 if(raa_current_db->gfrag_data.lbuf == 0 || nsub != raa_current_db->gfrag_data.nseq_buf ||
594 		first >= raa_current_db->gfrag_data.first_buf + raa_current_db->gfrag_data.lbuf ||
595 		first < raa_current_db->gfrag_data.first_buf) {
596 	if( nsub == raa_current_db->gfrag_data.nseq_buf && first > raa_current_db->gfrag_data.l_nseq_buf)
597 		lu = 0;
598 	else
599 		lu = fill_gfrag_buf(raa_current_db, nsub, first);
600 
601 	if(lu == 0) return 0;
602 	raa_current_db->gfrag_data.lbuf = lu;
603 	if(raa_current_db->gfrag_data.lbuf < RAA_GFRAG_BSIZE)
604 		raa_current_db->gfrag_data.l_nseq_buf = first + raa_current_db->gfrag_data.lbuf - 1;
605 	else raa_current_db->gfrag_data.l_nseq_buf = INT_MAX;
606 	raa_current_db->gfrag_data.first_buf = first;
607 	raa_current_db->gfrag_data.nseq_buf = nsub;
608 	}
609 debut = raa_current_db->gfrag_data.buffer + (first - raa_current_db->gfrag_data.first_buf);
610 lu = raa_current_db->gfrag_data.lbuf + raa_current_db->gfrag_data.first_buf-1 - first+1;
611 if( lu > lfrag) lu = lfrag;
612 memcpy(dseq, debut, lu);
613 while(lfrag > lu) {
614 	piece = raa_gfrag(raa_current_db, nsub, first + lu, lfrag - lu, dseq + lu);
615 	if(piece == 0) break;
616 	lu += piece;
617 	}
618 dseq[lu] = 0;
619 return lu;
620 }
621 
622 
raa_free_sp_tree(raa_node * pere)623 static void raa_free_sp_tree(raa_node *pere)
624 {
625 raa_node *next, *tmp_n;
626 struct raa_pair *liste, *tmp_p;
627 
628 liste = pere->list_desc;
629 while(liste != NULL) {
630 	tmp_p = liste->next;
631 	raa_free_sp_tree(liste->value);
632 	free(liste);
633 	liste = tmp_p;
634 	}
635 next = pere->syno;
636 while(next != NULL && next != pere) {
637 	tmp_n = next->syno;
638 	free(next->name);
639 	free(next);
640 	next = tmp_n;
641 	}
642 free(pere->name);
643 if(pere->libel != NULL) free(pere->libel);
644 if(pere->libel_upcase != NULL) free(pere->libel_upcase);
645 free(pere);
646 }
647 
648 
raa_acnucclose(raa_db_access * raa_current_db)649 void raa_acnucclose(raa_db_access *raa_current_db) {
650 char *reponse;
651 int i;
652 
653 if(raa_current_db == NULL) return;
654 
655 sock_fputs(raa_current_db, "acnucclose\n");
656 
657 reponse=read_sock(raa_current_db);
658 if(reponse != NULL) {
659 	sock_fputs(raa_current_db, "quit\n");
660 	sock_flush(raa_current_db);
661 	}
662 #ifdef WIN32
663   closesocket( (SOCKET) (raa_current_db->raa_sockfdw) );
664 #else
665   fclose(raa_current_db->raa_sockfdr);
666   fclose(raa_current_db->raa_sockfdw);
667 #endif
668 
669 if(raa_current_db->tot_key_annots > 0) {
670 	for(i = 0; i < raa_current_db->tot_key_annots; i++) {
671 		free(raa_current_db->key_annots[i]);
672 		free(raa_current_db->key_annots_min[i]);
673 		}
674 	free(raa_current_db->key_annots);
675 	free(raa_current_db->key_annots_min);
676 	free(raa_current_db->want_key_annots);
677 	raa_current_db->tot_key_annots = 0;
678 	}
679 if(raa_current_db->tid_to_rank != NULL) free(raa_current_db->tid_to_rank);
680 if(raa_current_db->sp_tree != NULL) {
681 	raa_free_sp_tree(raa_current_db->sp_tree[2]);
682 	free(raa_current_db->sp_tree);
683 	}
684   if(raa_current_db->dbname != NULL) free(raa_current_db->dbname);
685   if(raa_current_db->rlng_buffer != NULL) free(raa_current_db->rlng_buffer);
686   if(raa_current_db->readsub_data.name != NULL) free(raa_current_db->readsub_data.name);
687   for(i = 0; i < raa_current_db->annot_data.annotcount; i++)
688     free(raa_current_db->annot_data.annotline[i]);
689   for(i = 0; i < BLOCK_ELTS_IN_LIST; i++) if(raa_current_db->nextelt_data.tabname[i] != NULL)
690     free(raa_current_db->nextelt_data.tabname[i]);
691   if(raa_current_db->readsmj_data.lastrec > 0) {
692     free(raa_current_db->readsmj_data.plongs);
693     for(i=2; i <= raa_current_db->readsmj_data.lastrec; i++) {
694       if(raa_current_db->readsmj_data.names[i] != NULL) free(raa_current_db->readsmj_data.names[i]);
695       if(raa_current_db->readsmj_data.libels[i] != NULL) free(raa_current_db->readsmj_data.libels[i]);
696     }
697     free(raa_current_db->readsmj_data.names); free(raa_current_db->readsmj_data.libels);
698     raa_current_db->readsmj_data.lastrec = 0;
699   }
700   raa_free_matchkeys(raa_current_db);
701   if (raa_current_db->full_line) free(raa_current_db->full_line);
702   if (raa_current_db->namestr) free(raa_current_db->namestr);
703   if (raa_current_db->help) free(raa_current_db->help);
704   if (raa_current_db->tmp_prelist) free(raa_current_db->tmp_prelist);
705   if (raa_current_db->translate_buffer) free(raa_current_db->translate_buffer);
706 
707   free(raa_current_db);
708 }
709 
710 
raa_prep_acnuc_query(raa_db_access * raa_current_db)711 int raa_prep_acnuc_query(raa_db_access *raa_current_db) {
712 /* returns -1 if error or number of free bit lists
713 */
714   char *reponse, *p, *q, *annotlines;
715   int codret, i;
716   Reponse *rep;
717 
718   if (raa_current_db == NULL) return -1;
719   if (raa_current_db->maxlists) return raa_current_db->maxlists;
720   rep = initreponse();
721 
722   sock_fputs(raa_current_db, "countfreelists\n");
723   reponse=read_sock(raa_current_db);
724 if(reponse == NULL) return -1;
725   parse(reponse,rep);
726   reponse=val(rep,"code");
727   if(reponse == NULL) return -1;
728   codret=atoi(reponse);
729   free(reponse);
730   if(codret != 0) return -1;
731   reponse=val(rep,"free");
732   if(reponse != NULL) {
733 	codret = atoi(reponse);
734         raa_current_db->maxlists = codret;
735   	free(reponse);
736   	}
737 annotlines = val(rep, "annotlines");
738 raa_current_db->tot_key_annots = 0;
739 if(annotlines != NULL) {
740 	p = annotlines - 1;
741 	do 	{
742 		p++;
743 		raa_current_db->tot_key_annots++;
744 		}
745 	while((p = strchr(p, '|')) != NULL);
746 	raa_current_db->want_key_annots = (unsigned char *)calloc(raa_current_db->tot_key_annots,
747 		sizeof(unsigned char));
748         raa_current_db->want_key_annots[0] = TRUE;
749 	raa_current_db->key_annots = (char **)malloc(raa_current_db->tot_key_annots * sizeof(char *));
750 	raa_current_db->key_annots_min = (char **)malloc(raa_current_db->tot_key_annots * sizeof(char *));
751 	p = annotlines;
752 	for(i = 0; i < raa_current_db->tot_key_annots; i++) {
753 		q = strchr(p, '|');
754 		if(q == NULL) q = p + strlen(p);
755 		raa_current_db->key_annots[i] = malloc(q - p + 1);
756 		raa_current_db->key_annots_min[i] = malloc(q - p + 1);
757 		memcpy(raa_current_db->key_annots_min[i], p, q - p);
758 		raa_current_db->key_annots_min[i][q - p] = 0;
759 		strcpy(raa_current_db->key_annots[i], raa_current_db->key_annots_min[i]);
760 		majuscules(raa_current_db->key_annots[i]);
761 		compact(raa_current_db->key_annots[i]);
762 		p = q + 1;
763 		}
764 	free(annotlines);
765 	}
766 else codret = -1;
767   clear_reponse(rep);
768   return codret;
769 }
770 
771 
772 static char *raa_requete_remote_file(raa_db_access *raa_current_db, char *oldrequete, int **plist, char **);
773 
raa_proc_query(raa_db_access * raa_current_db,char * requete,char ** message,char * nomliste,int * numlist,int * count,int * locus,int * type)774 int raa_proc_query(raa_db_access *raa_current_db, char *requete, char **message,
775 	char *nomliste, int *numlist, int *count, int *locus, int *type) {
776   char *reponse, *code, *numlistchr, *countchr, *locuschr, *typechr, *badfname, *p;
777   int codret, *tmp_blists;
778   Reponse *rep;
779 
780 if(raa_current_db == NULL) return -1;
781   requete = raa_requete_remote_file(raa_current_db, requete, &tmp_blists, &badfname);
782   if(requete == NULL) {
783   	if(message != NULL) {
784 		char fmt[] = "problem accessing file: %s";
785   		*message = (char *)malloc(strlen(fmt) + strlen(badfname) + 1);
786   		sprintf(*message, fmt, badfname);
787   		}
788   	return 1;
789   	}
790   p = protect_quotes(requete);
791   sock_printf(raa_current_db,"proc_query&query=\"%s\"&name=\"%s\"\n", p, nomliste);
792   free(p);
793   free(requete);
794   reponse=read_sock(raa_current_db);
795   if(reponse == NULL) {
796   	 if(message != NULL) *message = strdup("connection with server is down");
797 	 return -1;
798 	 }
799   rep=initreponse();
800   parse(reponse,rep);
801   code=val(rep,"code");
802   codret=atoi(code);
803   if(codret == 0) {
804     	numlistchr=val(rep,"lrank");
805  	 *numlist=atoi(numlistchr);
806   	countchr=val(rep,"count");
807  	if(count != NULL) *count=atoi(countchr);
808   	typechr=val(rep,"type");
809   	locuschr=val(rep,"locus");
810   	if(type != NULL) {
811   		if (strcmp(typechr,"SQ")==0) *type='S';
812   		else if (strcmp(typechr,"KW")==0) *type='K';
813   		else if (strcmp(typechr,"SP")==0) *type='E';
814   		}
815   	if(locus != NULL) *locus = strcmp(locuschr,"T") == 0;
816 	  free(countchr);
817 	  free(locuschr);
818 	  free(typechr);
819 	  free(numlistchr);
820   	}
821  else if(message != NULL) {
822  	*message = val(rep, "message");
823  	}
824   free(code);
825   clear_reponse(rep);
826   if(tmp_blists != NULL) {
827  	 while(*tmp_blists != 0) raa_releaselist(raa_current_db, *(tmp_blists++) );
828  	 }
829   return codret;
830 }
831 
832 
raa_nexteltinlist(raa_db_access * raa_current_db,int first,int lrank,char ** pname,int * plength)833 int raa_nexteltinlist(raa_db_access *raa_current_db, int first, int lrank, char **pname, int *plength)
834 {
835 return raa_nexteltinlist_annots(raa_current_db, first, lrank, pname, plength, NULL, NULL);
836 }
837 
838 
raa_nexteltinlist_annots(raa_db_access * raa_current_db,int first,int lrank,char ** pname,int * plength,raa_long * paddr,int * pdiv)839 int raa_nexteltinlist_annots(raa_db_access *raa_current_db, int first, int lrank, char **pname, int *plength,
840 	raa_long *paddr, int *pdiv)
841 {
842 int num, next, count;
843 char *p;
844 Reponse *rep;
845 
846 if(raa_current_db == NULL) return 0;
847 if(lrank == raa_current_db->nextelt_data.current_rank &&
848 		raa_current_db->nextelt_data.previous < raa_current_db->nextelt_data.total - 1 &&
849 	(raa_current_db->nextelt_data.previous == -1 ||
850 		first == raa_current_db->nextelt_data.tabnum[raa_current_db->nextelt_data.previous] ) ) {
851 	raa_current_db->nextelt_data.previous++;
852 	next = raa_current_db->nextelt_data.tabnum[raa_current_db->nextelt_data.previous];
853 	if(next != 0) {
854 		if(pname != NULL) *pname = raa_current_db->nextelt_data.tabname[raa_current_db->nextelt_data.previous];
855 		if(plength != NULL) *plength = raa_current_db->nextelt_data.tablength[raa_current_db->nextelt_data.previous];
856 		if(paddr != NULL) *paddr = raa_current_db->nextelt_data.taboffset[raa_current_db->nextelt_data.previous];
857 		if(pdiv != NULL) *pdiv = raa_current_db->nextelt_data.tabdiv[raa_current_db->nextelt_data.previous];
858 		}
859 	return next;
860 	}
861 
862 count = BLOCK_ELTS_IN_LIST;
863 for(num = 0; num < count; num++) {
864 	if(raa_current_db->nextelt_data.tabname[num] != NULL) free(raa_current_db->nextelt_data.tabname[num]);
865 	}
866 memset(raa_current_db->nextelt_data.tabname, 0, count * sizeof(char *));
867 sock_printf(raa_current_db,"nexteltinlist&lrank=%d&first=%d&count=%d\n",lrank,first, count);
868 num = 0; raa_current_db->nextelt_data.current_rank = lrank;
869 raa_current_db->nextelt_data.total = 0;
870 do {
871   p = read_sock(raa_current_db);
872   if(p == NULL) return 0;
873   rep = initreponse();
874   parse(p, rep);
875   p = val(rep,"next");
876   if(p == NULL) {
877 	clear_reponse(rep);
878 	return 0;
879 	}
880   next = atoi(p);
881   free(p);
882   raa_current_db->nextelt_data.total++;
883   raa_current_db->nextelt_data.tabnum[num] = next;
884   if(next != 0) {
885 	  raa_current_db->nextelt_data.tabname[num] = val(rep, "name");
886 	  if( (p= val(rep, "length")) != NULL) {
887 		raa_current_db->nextelt_data.tablength[num] = atoi(p);
888 		free(p);
889 		}
890 	  if((p= val(rep, "offset")) != NULL) {
891 		raa_current_db->nextelt_data.taboffset[num] = scan_raa_long(p);
892 		free(p);
893 		}
894 	  if((p= val(rep, "div")) != NULL) {
895 		raa_current_db->nextelt_data.tabdiv[num] = atoi(p);
896 		free(p);
897 		}
898 	}
899   clear_reponse(rep);
900   num++;
901   }
902 while(next != 0 && --count > 0);
903 raa_current_db->nextelt_data.previous = -1;
904 return raa_nexteltinlist_annots(raa_current_db, first, lrank, pname, plength, paddr, pdiv);
905 }
906 
907 
scan_raa_long(char * txt)908 raa_long scan_raa_long(char *txt)
909 {
910 raa_long val;
911 
912 sscanf(txt, RAA_LONG_FORMAT, &val);
913 return val;
914 }
915 
916 
print_raa_long(raa_long val,char * buffer)917 char *print_raa_long(raa_long val, char *buffer)
918 {
919 sprintf(buffer, RAA_LONG_FORMAT, val);
920 return buffer;
921 }
922 
923 
924 
925 
load_annots_buf(raa_db_access * raa_current_db,raa_long faddr,int div,int was_nextannots)926 static char *load_annots_buf(raa_db_access *raa_current_db, raa_long faddr, int div, int was_nextannots)
927 /* appeler juste apr�s avoir envoye sur socket
928 read_annots&... ou  next_annots&... :
929 retour attendu sur socket : nl=xx[&offset=xx]&...nl lines each with \n     */
930 {
931 int i, nl;
932 char *firstline, *p, *q;
933 
934   if(raa_current_db == NULL) return NULL;
935   for(i=0; i < raa_current_db->annot_data.annotcount; i++)
936   	free(raa_current_db->annot_data.annotline[i]);
937   raa_current_db->annot_data.annotcount = 0;
938   raa_current_db->annot_data.annotaddrlast = faddr;
939   firstline = read_sock(raa_current_db);
940   if(firstline == NULL) return NULL;
941   if(strncmp(firstline, "nl=", 3) != 0 || (p = strchr(firstline, '&')) == NULL ) return NULL;
942   nl = atoi(firstline + 3);
943   if(nl == 0) return NULL;
944   p++;
945   if(was_nextannots && strncmp(p, "offset=", 7) == 0) {
946   	p = strchr(p, '&');
947   	if(p == NULL) return NULL;
948   	p++;
949   	}
950   i = strlen(p);
951   raa_current_db->annot_data.annotline[0] = (char *)malloc(i+1);
952   strcpy(raa_current_db->annot_data.annotline[0], p);
953   raa_current_db->annot_data.annotaddrlast += strlen(raa_current_db->annot_data.annotline[0]) + 1;
954   for(i = 1; i < nl; i++) {
955   	q = read_sock(raa_current_db);
956   	if(q == NULL) return NULL;
957   	raa_current_db->annot_data.annotline[i] = strdup( q );
958   	raa_current_db->annot_data.annotaddrlast += strlen(raa_current_db->annot_data.annotline[i]) + 1;
959   	}
960   raa_current_db->annot_data.annotcurrent = 1; raa_current_db->annot_data.annotcount = nl;
961   raa_current_db->annot_data.annotaddr = faddr; raa_current_db->annot_data.annotdiv = div;
962   raa_current_db->annot_data.annotaddrfirst = faddr;
963   strcpy(raa_current_db->annot_data.annotsbuffer, raa_current_db->annot_data.annotline[0]);
964   return raa_current_db->annot_data.annotsbuffer;
965 }
966 
967 
raa_read_annots(raa_db_access * raa_current_db,raa_long faddr,int div)968 char *raa_read_annots(raa_db_access *raa_current_db, raa_long faddr, int div)
969 {
970   int i;
971   raa_long debut;
972   char *p, buffer[40];
973 
974 if(raa_current_db == NULL) return NULL;
975   if(raa_current_db->annot_data.annotcount > 0 &&
976   		div == raa_current_db->annot_data.annotdiv &&
977   		faddr >= raa_current_db->annot_data.annotaddrfirst &&
978   		faddr < raa_current_db->annot_data.annotaddrlast ) {
979 	debut = raa_current_db->annot_data.annotaddrfirst;
980   	for(i = 1; i <= raa_current_db->annot_data.annotcount; i++) {
981   		if(debut == faddr) {
982   			raa_current_db->annot_data.annotcurrent = i;
983   			raa_current_db->annot_data.annotaddr = debut;
984   			strcpy(raa_current_db->annot_data.annotsbuffer, raa_current_db->annot_data.annotline[raa_current_db->annot_data.annotcurrent - 1]);
985   			return raa_current_db->annot_data.annotsbuffer;
986   			}
987   		debut += strlen(raa_current_db->annot_data.annotline[i - 1]) + 1;
988   		}
989 	}
990   sock_printf(raa_current_db,"read_annots&offset=%s&div=%d&nl=%d\n",
991   		print_raa_long(faddr, buffer), div, ANNOTCOUNT);
992   p = load_annots_buf(raa_current_db, faddr, div, FALSE);
993   return p;
994 }
995 
996 
raa_next_annots(raa_db_access * raa_current_db,raa_long * paddr)997 char *raa_next_annots(raa_db_access *raa_current_db, raa_long *paddr)
998 {
999   raa_long faddr;
1000   char *p;
1001 
1002 if(raa_current_db == NULL) return NULL;
1003   if(raa_current_db->annot_data.annotcurrent < raa_current_db->annot_data.annotcount) {
1004   	raa_current_db->annot_data.annotaddr +=
1005   		strlen(raa_current_db->annot_data.annotline[raa_current_db->annot_data.annotcurrent - 1]) + 1;
1006   	if(paddr != NULL) *paddr = raa_current_db->annot_data.annotaddr;
1007   	raa_current_db->annot_data.annotcurrent++;
1008   	strcpy(raa_current_db->annot_data.annotsbuffer,
1009   		raa_current_db->annot_data.annotline[raa_current_db->annot_data.annotcurrent - 1]);
1010   	return raa_current_db->annot_data.annotsbuffer;
1011   	}
1012   faddr = raa_current_db->annot_data.annotaddrlast;
1013   if(paddr != NULL) *paddr = faddr;
1014   sock_printf(raa_current_db, "next_annots&nl=%d\n", ANNOTCOUNT);
1015   p = load_annots_buf(raa_current_db, faddr, raa_current_db->annot_data.annotdiv, TRUE);
1016   return p;
1017 }
1018 
1019 
raa_iknum(raa_db_access * raa_current_db,char * name,raa_file cas)1020 int raa_iknum(raa_db_access *raa_current_db, char *name, raa_file cas)
1021 {
1022 char *reponse, *p;
1023 int val;
1024 
1025 if(raa_current_db == NULL) return 0;
1026   p = protect_quotes(name);
1027   sock_printf(raa_current_db,"iknum&name=\"%s\"&type=%s\n", p, (cas == raa_key ? "KW" : "SP") );
1028   free(p);
1029   reponse = read_sock(raa_current_db);
1030   if(reponse == NULL) return 0;
1031   p = strchr(reponse, '=');
1032   if(p == NULL) return 0;
1033   p++;
1034   sscanf(p, "%u", &val);
1035   return val;
1036 }
1037 
1038 
raa_isenum(raa_db_access * raa_current_db,char * name)1039 int raa_isenum(raa_db_access *raa_current_db, char *name)
1040 {
1041 char *reponse, *p;
1042 int val;
1043 
1044 if(raa_current_db == NULL) return 0;
1045   p = protect_quotes(name);
1046   sock_printf(raa_current_db,"isenum&name=\"%s\"\n", p );
1047   free(p);
1048   reponse = read_sock(raa_current_db);
1049   if(reponse == NULL) return 0;
1050   p = strchr(reponse, '=');
1051   if(p == NULL) return 0;
1052   p++;
1053   sscanf(p, "%u", &val);
1054   return val;
1055 }
1056 
1057 
raa_bcount(raa_db_access * raa_current_db,int lrank)1058 int raa_bcount(raa_db_access *raa_current_db, int lrank)
1059 {
1060   Reponse *rep;
1061   char *reponse, *code, *countstr;
1062   int count = 0;
1063 
1064 if(raa_current_db == NULL) return 0;
1065   rep=initreponse();
1066   sock_printf(raa_current_db,"bcount&lrank=%d\n",lrank);
1067   reponse=read_sock(raa_current_db);
1068   if(reponse == NULL) return 0;
1069   parse(reponse, rep);
1070   code = val(rep,"code");
1071   if(*code == '0') {
1072   	countstr = val(rep,"count");
1073 	count = atoi(countstr);
1074 	free(countstr);
1075   	}
1076   free(code);
1077   clear_reponse(rep);
1078   return count;
1079 }
1080 
raa_bit1(raa_db_access * raa_current_db,int lrank,int num)1081 void raa_bit1(raa_db_access *raa_current_db, int lrank, int num)
1082 {
1083 char *reponse;
1084 
1085 if(raa_current_db == NULL) return;
1086   sock_printf(raa_current_db,"bit1&lrank=%d&num=%d\n", lrank, num);
1087   reponse=read_sock(raa_current_db);
1088 }
1089 
1090 
raa_bit0(raa_db_access * raa_current_db,int lrank,int num)1091 void raa_bit0(raa_db_access *raa_current_db, int lrank, int num)
1092 {
1093 char *reponse;
1094 
1095 if(raa_current_db == NULL) return;
1096   sock_printf(raa_current_db,"bit0&lrank=%d&num=%d\n", lrank, num);
1097   reponse=read_sock(raa_current_db);
1098 }
1099 
1100 
raa_btest(raa_db_access * raa_current_db,int lrank,int num)1101 int raa_btest(raa_db_access *raa_current_db, int lrank, int num)
1102 {
1103 char *reponse;
1104 
1105 if(raa_current_db == NULL) return 0;
1106   sock_printf(raa_current_db,"btest&lrank=%d&num=%d\n", lrank, num);
1107   reponse=read_sock(raa_current_db);
1108   if(reponse == NULL) return 0;
1109   return strcmp(reponse, "code=0&on") == 0;
1110 }
1111 
raa_copylist(raa_db_access * raa_current_db,int from,int to)1112 void raa_copylist(raa_db_access *raa_current_db, int from, int to)
1113 {
1114 char *reponse;
1115 
1116 if(raa_current_db == NULL) return;
1117   sock_printf(raa_current_db,"copylist&lfrom=%d&lto=%d\n", from, to);
1118   reponse=read_sock(raa_current_db);
1119 }
1120 
1121 
raa_zerolist(raa_db_access * raa_current_db,int rank)1122 void raa_zerolist(raa_db_access *raa_current_db, int rank)
1123 {
1124 char *reponse;
1125 
1126 if(raa_current_db == NULL) return;
1127   sock_printf(raa_current_db,"zerolist&lrank=%d\n", rank);
1128   reponse=read_sock(raa_current_db);
1129 }
1130 
1131 
raa_setliststate(raa_db_access * raa_current_db,int lrank,int locus,int type)1132 void raa_setliststate(raa_db_access *raa_current_db, int lrank, int locus, int type)
1133 {
1134 char *reponse, str_type[3];
1135 
1136 if(raa_current_db == NULL) return;
1137 if(type == 'S') strcpy(str_type, "SQ");
1138 else if(type == 'K') strcpy(str_type, "KW");
1139 else  strcpy(str_type, "SP");
1140 
1141   sock_printf(raa_current_db,"setliststate&lrank=%d&locus=%c&type=%s\n", lrank, (locus ? 'T' : 'F'),
1142   	str_type );
1143   reponse=read_sock(raa_current_db);
1144 }
1145 
1146 
raa_getliststate(raa_db_access * raa_current_db,int lrank,int * locus,int * type,int * count)1147 char *raa_getliststate(raa_db_access *raa_current_db, int lrank, int *locus, int *type, int *count)
1148 {
1149   Reponse *rep;
1150   char *reponse, *code, *countstr, *locusstr, *typestr, *retp = NULL;
1151 
1152 if(raa_current_db == NULL) return NULL;
1153   rep=initreponse();
1154   sock_printf(raa_current_db,"getliststate&lrank=%d\n",lrank);
1155   reponse=read_sock(raa_current_db);
1156   if(reponse == NULL) return NULL;
1157   parse(reponse, rep);
1158   code = val(rep,"code");
1159   if(code != NULL && *code == '0') {
1160   	typestr = val(rep,"type");
1161   	if(type != NULL) {
1162   		if(strcmp(typestr, "SQ") == 0) *type = 'S';
1163   		else if(strcmp(typestr, "KW") == 0) *type = 'K';
1164   		else *type = 'E';
1165   		}
1166   	if(raa_current_db->namestr != NULL) free(raa_current_db->namestr); /* allocation precedante */
1167   	raa_current_db->namestr = val(rep, "name");
1168   	countstr = val(rep, "count");
1169 	if(count != NULL) *count = atoi(countstr);
1170   	locusstr = val(rep, "locus");
1171   	if(locus != NULL) *locus = (*locusstr == 'T');
1172 	free(countstr);
1173 	free(locusstr);
1174 	free(typestr);
1175 	retp = raa_current_db->namestr;
1176   	}
1177   if(code != NULL) free(code);
1178   clear_reponse(rep);
1179   return retp;
1180 }
1181 
1182 
raa_residuecount(raa_db_access * raa_current_db,int lrank)1183 char *raa_residuecount(raa_db_access *raa_current_db, int lrank)
1184 {
1185 Reponse *rep;
1186 char *reponse, *code;
1187 
1188 if(raa_current_db == NULL) return 0;
1189   rep=initreponse();
1190   sock_printf(raa_current_db,"residuecount&lrank=%d\n",lrank);
1191   reponse=read_sock(raa_current_db);
1192   if(reponse == NULL) return 0;
1193   parse(reponse, rep);
1194   code = val(rep,"code");
1195   strcpy(raa_current_db->residuecount, "0");
1196   if(code != NULL && *code == '0') {
1197 	free(code);
1198   	code = val(rep,"count");
1199  	if(code != NULL) {
1200 		strcpy(raa_current_db->residuecount, code);
1201 		free(code);
1202 		}
1203 	}
1204 clear_reponse(rep);
1205 return raa_current_db->residuecount;
1206 }
1207 
1208 
raa_getemptylist(raa_db_access * raa_current_db,char * name)1209 int raa_getemptylist(raa_db_access *raa_current_db, char *name)
1210 {
1211   Reponse *rep;
1212   char *reponse, *code, *rankstr, *p;
1213   int rank = 0;
1214 
1215 if(raa_current_db == NULL) return 0;
1216   rep=initreponse();
1217   p = protect_quotes(name);
1218   sock_printf(raa_current_db, "getemptylist&name=\"%s\"\n", p);
1219   free(p);
1220   reponse=read_sock(raa_current_db);
1221   if(reponse == NULL) return 0;
1222   parse(reponse, rep);
1223   code = val(rep,"code");
1224   if(code != NULL && (*code == '0' || *code == '3') ) {
1225   	rankstr = val(rep, "lrank");
1226 	rank = atoi(rankstr);
1227 	free(rankstr);
1228   	}
1229   if(code != NULL) free(code);
1230   clear_reponse(rep);
1231   return rank;
1232 }
1233 
1234 
raa_setlistname(raa_db_access * raa_current_db,int lrank,char * name)1235 int raa_setlistname(raa_db_access *raa_current_db, int lrank, char *name)
1236 {
1237   Reponse *rep;
1238 char *reponse, *code;
1239 int retval;
1240 
1241 if(raa_current_db == NULL) return -1;
1242   rep=initreponse();
1243   sock_printf(raa_current_db, "setlistname&lrank=%d&name=\"%s\"\n", lrank, name);
1244   reponse=read_sock(raa_current_db);
1245   if(reponse == NULL) return -1;
1246   parse(reponse, rep);
1247   code = val(rep,"code");
1248   if(*code == '0') retval = 0;
1249   else if(*code == '3') retval = 1;
1250   else retval = -1;
1251   free(code);
1252   clear_reponse(rep);
1253 return retval;
1254 }
1255 
1256 
raa_getlistrank(raa_db_access * raa_current_db,char * name)1257 int raa_getlistrank(raa_db_access *raa_current_db, char *name)
1258 {
1259   Reponse *rep;
1260 char *reponse, *rankstr;
1261 int rank;
1262 
1263 if(raa_current_db == NULL) return 0;
1264   rep=initreponse();
1265   sock_printf(raa_current_db, "getlistrank&name=\"%s\"\n", name);
1266   reponse=read_sock(raa_current_db);
1267   if(reponse == NULL) return 0;
1268   parse(reponse, rep);
1269   rankstr = val(rep,"lrank");
1270   if(rankstr == NULL) return 0;
1271   rank = atoi(rankstr);
1272   free(rankstr);
1273   clear_reponse(rep);
1274   return rank;
1275 }
1276 
1277 
1278 
raa_releaselist(raa_db_access * raa_current_db,int lrank)1279 int raa_releaselist(raa_db_access *raa_current_db, int lrank)
1280 {
1281   Reponse *rep;
1282 char *reponse, *rankstr;
1283 int rank;
1284 
1285 if(raa_current_db == NULL) return 1;
1286   rep=initreponse();
1287   sock_printf(raa_current_db, "releaselist&lrank=%d\n", lrank);
1288   reponse=read_sock(raa_current_db);
1289   if(reponse == NULL) return 1;
1290   parse(reponse, rep);
1291   rankstr = val(rep,"code");
1292   if(rankstr == NULL) return 1;
1293   rank = atoi(rankstr);
1294   free(rankstr);
1295   clear_reponse(rep);
1296   return rank;
1297 }
1298 
1299 
1300 
raa_countfilles(raa_db_access * raa_current_db,int lrank)1301 int raa_countfilles(raa_db_access *raa_current_db, int lrank)
1302 {
1303   Reponse *rep;
1304 char *reponse, *rankstr;
1305 int rank;
1306 
1307 if(raa_current_db == NULL) return 0;
1308   rep=initreponse();
1309   sock_printf(raa_current_db, "countsubseqs&lrank=%d\n", lrank);
1310   reponse=read_sock(raa_current_db);
1311   if(reponse == NULL) return 0;
1312   parse(reponse, rep);
1313   rankstr = val(rep,"count");
1314   if(rankstr == NULL) return 0;
1315   rank = atoi(rankstr);
1316   free(rankstr);
1317   clear_reponse(rep);
1318   return rank;
1319 }
1320 
1321 
raa_alllistranks(raa_db_access * raa_current_db,int ** pranks)1322 int raa_alllistranks(raa_db_access *raa_current_db, int **pranks)
1323 {
1324   Reponse *rep;
1325 char *reponse, *rankstr, *p;
1326 int count, *ranks, i;
1327 
1328 if(raa_current_db == NULL) return 0;
1329   rep=initreponse();
1330   sock_fputs(raa_current_db, "alllistranks\n");
1331   reponse=read_sock(raa_current_db);
1332   if(reponse == NULL) return 0;
1333   parse(reponse, rep);
1334   rankstr = val(rep,"count");
1335   p = strchr(reponse, '&');
1336   if(rankstr == NULL || p == NULL) return 0;
1337   count = atoi(rankstr);
1338   ranks = (int *)malloc(count * sizeof(int));
1339   if(ranks == NULL ) return 0;
1340   p++;
1341   for(i=0; i< count; i++) {
1342   	sscanf(p, "%d", &ranks[i]);
1343   	p = strchr(p, ',');
1344   	if(p == NULL) break;
1345   	p++;
1346   	}
1347   *pranks = ranks;
1348   free(rankstr);
1349   clear_reponse(rep);
1350   return count;
1351 }
1352 
1353 
1354 
raa_fcode(raa_db_access * raa_current_db,raa_file cas,char * name)1355 int raa_fcode(raa_db_access *raa_current_db, raa_file cas, char *name)
1356 {
1357 char *reponse, *p, type[5];
1358 int value;
1359 
1360 if(raa_current_db == NULL) return 0;
1361 if(cas == raa_aut) strcpy(type, "AUT");
1362 else if(cas == raa_bib) strcpy(type, "BIB");
1363 else if(cas == raa_acc) strcpy(type, "ACC");
1364 else if(cas == raa_smj) strcpy(type, "SMJ");
1365 else if(cas == raa_sub) strcpy(type, "SUB");
1366 else return 0;
1367   p = protect_quotes(name);
1368   sock_printf(raa_current_db,"fcode&name=\"%s\"&type=%s\n", p, type );
1369   free(p);
1370   reponse = read_sock(raa_current_db);
1371   if(reponse == NULL) return 0;
1372   p = strchr(reponse, '=');
1373   if(p == NULL) return 0;
1374   p++;
1375   sscanf(p, "%u", &value);
1376   return value;
1377 }
1378 
1379 
1380 
raa_read_first_rec(raa_db_access * raa_current_db,raa_file cas)1381 int raa_read_first_rec(raa_db_access *raa_current_db, raa_file cas)
1382 {
1383 int value;
1384 char type[5], *p, *reponse;
1385 
1386 if(raa_current_db == NULL) return 1;
1387 if(raa_current_db->first_recs[cas] != 0) return raa_current_db->first_recs[cas];
1388 
1389 if(cas == raa_aut) strcpy(type, "AUT");
1390 else if(cas == raa_bib) strcpy(type, "BIB");
1391 else if(cas == raa_acc) strcpy(type, "ACC");
1392 else if(cas == raa_smj) strcpy(type, "SMJ");
1393 else if(cas == raa_sub) strcpy(type, "SUB");
1394 
1395 
1396 else if(cas == raa_loc) strcpy(type, "LOC");
1397 else if(cas == raa_key) strcpy(type, "KEY");
1398 else if(cas == raa_spec) strcpy(type, "SPEC");
1399 else if(cas == raa_shrt) strcpy(type, "SHRT");
1400 else if(cas == raa_lng) strcpy(type, "LNG");
1401 else if(cas == raa_ext) strcpy(type, "EXT");
1402 else if(cas == raa_txt) strcpy(type, "TXT");
1403 else return 0;
1404 sock_printf(raa_current_db,"readfirstrec&type=%s\n", type );
1405 reponse = read_sock(raa_current_db);
1406 if(reponse == NULL) return 1;
1407 p = strstr(reponse, "count=");
1408 if(p == NULL) return 0;
1409 sscanf(p + 6, "%u", &value);
1410 raa_current_db->first_recs[cas] = value;
1411 return value;
1412 }
1413 
1414 
raa_readsub_pannots(raa_db_access * raa_current_db,int num,int * plength,int * ptype,int * pext,int * plkey,int * plocus,int * pframe,int * pgencode,raa_long * paddr,int * pdiv)1415 char *raa_readsub_pannots(raa_db_access *raa_current_db, int num, int *plength, int *ptype, int *pext, int *plkey, int *plocus,
1416 	int *pframe, int *pgencode, raa_long *paddr, int *pdiv)
1417 /* do both seq_to_annots and readsub and buffer result for one seq */
1418 {
1419   Reponse *rep;
1420   char *p, *reponse;
1421   int code, l;
1422 
1423 if(raa_current_db == NULL) return NULL;
1424   if(num < 2 || num > raa_current_db->nseq) return NULL;
1425   if(num != raa_current_db->readsub_data.previous) {
1426   	sock_printf(raa_current_db,"seq_to_annots&number=%d\nreadsub&num=%u\n", num, num);
1427   	reponse = read_sock(raa_current_db);
1428     if(reponse == NULL) return NULL;
1429   	/* process reply to seq_to_annots */
1430   	rep=initreponse();
1431   	parse(reponse, rep);
1432  	p = val(rep,"code");
1433 	code = atoi(p);
1434   	free(p);
1435   	if(code == 0) {
1436   		p = val(rep,"offset");
1437   		raa_current_db->readsub_data.addr = scan_raa_long(p);
1438   		free(p);
1439   		p = val(rep,"div");
1440 		raa_current_db->readsub_data.div = atoi(p);
1441   		free(p);
1442   		}
1443   	clear_reponse(rep);
1444   	/* process reply to readsub */
1445   	reponse = read_sock(raa_current_db);
1446     if(reponse == NULL) return NULL;
1447   	rep=initreponse();
1448   	parse(reponse, rep);
1449   	p = val(rep,"code");
1450   	if(p == NULL) return NULL;
1451   	code = atoi(p);
1452   	free(p);
1453   	if(code != 0) {
1454   		clear_reponse(rep);
1455   		return NULL;
1456   		}
1457   	p = val(rep, "name");
1458   	l = strlen(p) + 1;
1459   	if(l > raa_current_db->readsub_data.lname) {
1460   		raa_current_db->readsub_data.lname = l;
1461   		raa_current_db->readsub_data.name = (char *)realloc(raa_current_db->readsub_data.name,
1462   			raa_current_db->readsub_data.lname);
1463   		}
1464   	strcpy(raa_current_db->readsub_data.name, p);
1465   	free(p);
1466   	p = val(rep, "length");
1467   	raa_current_db->readsub_data.length = atoi(p);
1468   	free(p);
1469   	p = val(rep, "type");
1470   	raa_current_db->readsub_data.type = atoi_u(p);
1471   	free(p);
1472   	p = val(rep, "is_sub");
1473   	raa_current_db->readsub_data.locus = atoi_u(p);
1474   	free(p);
1475   	p = val(rep, "toext");
1476   	raa_current_db->readsub_data.toext = atoi_u(p);
1477   	if(raa_current_db->readsub_data.locus > 0)
1478   			raa_current_db->readsub_data.toext = - raa_current_db->readsub_data.toext;
1479   	free(p);
1480   	p = val(rep, "plkey");
1481   	raa_current_db->readsub_data.lkey = atoi_u(p);
1482   	free(p);
1483   	p = val(rep, "frame");
1484   	raa_current_db->readsub_data.frame = atoi_u(p);
1485   	free(p);
1486   	p = val(rep, "genet");
1487   	raa_current_db->readsub_data.gencode = atoi_u(p);
1488   	free(p);
1489   	raa_current_db->readsub_data.previous = num;
1490   	clear_reponse(rep);
1491   	}
1492   if(plength != NULL) *plength = raa_current_db->readsub_data.length;
1493   if(ptype != NULL) *ptype = raa_current_db->readsub_data.type;
1494   if(plocus != NULL) *plocus = raa_current_db->readsub_data.locus;
1495   if(pext != NULL) *pext = raa_current_db->readsub_data.toext;
1496   if(plkey != NULL) *plkey = raa_current_db->readsub_data.lkey;
1497   if(pframe != NULL) *pframe = raa_current_db->readsub_data.frame;
1498   if(pgencode != NULL) *pgencode = raa_current_db->readsub_data.gencode;
1499   if(paddr != NULL) *paddr = raa_current_db->readsub_data.addr;
1500   if(pdiv != NULL) *pdiv = raa_current_db->readsub_data.div;
1501   return raa_current_db->readsub_data.name;
1502 }
1503 
1504 
raa_seq_to_annots(raa_db_access * raa_current_db,int numseq,raa_long * faddr,int * div)1505 int raa_seq_to_annots(raa_db_access *raa_current_db, int numseq, raa_long *faddr, int *div)
1506 {
1507 char *p;
1508 
1509 p = raa_readsub_pannots(raa_current_db, numseq,NULL,NULL,NULL,NULL,NULL,NULL,NULL,faddr,div);
1510 return p == NULL;
1511 }
1512 
1513 
raa_readsub(raa_db_access * raa_current_db,int num,int * plength,int * ptype,int * pext,int * plkey,int * plocus,int * pframe,int * pgencode)1514 char *raa_readsub(raa_db_access *raa_current_db, int num, int *plength, int *ptype, int *pext, int *plkey, int *plocus,
1515 	int *pframe, int *pgencode)
1516 {
1517 return raa_readsub_pannots(raa_current_db, num,plength,ptype,pext,plkey,plocus,pframe,pgencode,NULL,NULL);
1518 }
1519 
1520 
raa_readloc(raa_db_access * raa_current_db,int num,int * sub,int * pnuc,int * spec,int * host,int * plref,int * molec,int * placc,int * org)1521 char *raa_readloc(raa_db_access *raa_current_db, int num, int *sub, int *pnuc, int *spec, int *host, int *plref,
1522 	int *molec, int *placc, int *org)
1523 {
1524   Reponse *rep;
1525   char *p, *reponse;
1526   int code;
1527 
1528 if(raa_current_db == NULL) return NULL;
1529   rep=initreponse();
1530   sock_printf(raa_current_db,"readloc&num=%u\n", num);
1531   reponse = read_sock(raa_current_db);
1532   if(reponse == NULL) return NULL;
1533   parse(reponse, rep);
1534   p = val(rep,"code");
1535   if(p == NULL) return NULL;
1536   code = atoi(p);
1537   free(p);
1538   if(code == 0) {
1539   	if(sub != NULL) {
1540   		p = val(rep, "sub");
1541   		*sub = atoi_u(p);
1542   		free(p);
1543   		}
1544   	if(pnuc != NULL) {
1545   		p = val(rep, "pnuc");
1546   		*pnuc = atoi_u(p);
1547   		free(p);
1548   		}
1549   	if(spec != NULL) {
1550   		p = val(rep, "spec");
1551   		*spec = atoi_u(p);
1552   		free(p);
1553   		}
1554   	if(host != NULL) {
1555   		p = val(rep, "host");
1556   		*host = atoi_u(p);
1557   		free(p);
1558   		}
1559   	if(plref != NULL) {
1560   		p = val(rep, "plref");
1561   		*plref = atoi_u(p);
1562   		free(p);
1563   		}
1564   	if(molec != NULL) {
1565   		p = val(rep, "molec");
1566   		*molec = atoi_u(p);
1567   		free(p);
1568   		}
1569   	if(placc != NULL) {
1570   		p = val(rep, "placc");
1571   		*placc = atoi_u(p);
1572   		free(p);
1573   		}
1574   	if(org != NULL) {
1575   		p = val(rep, "org");
1576   		*org = atoi_u(p);
1577   		free(p);
1578   		}
1579   	p = val(rep, "date");
1580   	strcpy(raa_current_db->date, p);
1581   	free(p);
1582   	p = raa_current_db->date;
1583   	}
1584   else p = NULL;
1585   clear_reponse(rep);
1586   return p;
1587 }
1588 
1589 
raa_readspec(raa_db_access * raa_current_db,int num,char ** plibel,int * plsub,int * pdesc,int * psyno,int * plhost)1590 char *raa_readspec(raa_db_access *raa_current_db, int num, char **plibel, int *plsub, int *pdesc, int *psyno, int *plhost)
1591 {
1592   Reponse *rep;
1593   char *p, *reponse;
1594   int code;
1595 
1596 if(raa_current_db == NULL) return NULL;
1597   if(num == raa_current_db->readspec_data.previous && raa_current_db->readspec_data.previous != 0) {
1598   	if(plibel != NULL) {
1599   		if(*(raa_current_db->readspec_data.libel) != 0) *plibel = raa_current_db->readspec_data.libel;
1600   		else *plibel = NULL;
1601   		}
1602   	if(plsub != NULL) *plsub = raa_current_db->readspec_data.lsub;
1603   	if(pdesc != NULL) *pdesc = raa_current_db->readspec_data.desc;
1604   	if(psyno != NULL) *psyno = raa_current_db->readspec_data.syno;
1605   	if(plhost != NULL) *plhost = raa_current_db->readspec_data.host;
1606   	return raa_current_db->readspec_data.name;
1607   	}
1608 
1609   rep=initreponse();
1610   sock_printf(raa_current_db, "readspec&num=%u\n", num);
1611   reponse = read_sock(raa_current_db);
1612   if(reponse == NULL) return NULL;
1613   parse(reponse, rep);
1614   p = val(rep,"code");
1615   if(p == NULL) return NULL;
1616   code = atoi(p);
1617   free(p);
1618   if(code != 0) {
1619   	  clear_reponse(rep);
1620   	  return NULL;
1621   	  }
1622 
1623   raa_current_db->readspec_data.previous = num;
1624   	p = val(rep, "plsub");
1625   	raa_current_db->readspec_data.lsub = atoi_u(p);
1626   	free(p);
1627   	p = val(rep, "desc");
1628   	raa_current_db->readspec_data.desc = atoi_u(p);
1629   	free(p);
1630   	p = val(rep, "syno");
1631   	raa_current_db->readspec_data.syno = atoi_u(p);
1632   	free(p);
1633   	p = val(rep, "host");
1634   	raa_current_db->readspec_data.host = atoi_u(p);
1635   	free(p);
1636   	p = val(rep, "libel");
1637   	if(p != NULL) {
1638   		strcpy(raa_current_db->readspec_data.libel, p);
1639   		free(p);
1640   		}
1641   	else *(raa_current_db->readspec_data.libel) = 0;
1642   	p = val(rep, "name");
1643   	strcpy(raa_current_db->readspec_data.name, p );
1644   	free(p);
1645   clear_reponse(rep);
1646   return raa_readspec(raa_current_db, num, plibel, plsub, pdesc, psyno, plhost);
1647 }
1648 
1649 
raa_readkey(raa_db_access * raa_current_db,int num,char ** plibel,int * plsub,int * pdesc,int * psyno)1650 char *raa_readkey(raa_db_access *raa_current_db, int num, char **plibel, int *plsub, int *pdesc, int *psyno)
1651 {
1652   Reponse *rep;
1653   char *p, *reponse;
1654   int code;
1655 
1656 if(raa_current_db == NULL) return NULL;
1657   if(num == raa_current_db->readkey_data.previous && raa_current_db->readkey_data.previous != 0) {
1658   	if(plibel != NULL) {
1659   		if(*(raa_current_db->readkey_data.libel) != 0) *plibel = raa_current_db->readkey_data.libel;
1660   		else *plibel = NULL;
1661   		}
1662   	if(plsub != NULL) *plsub = raa_current_db->readkey_data.lsub;
1663   	if(pdesc != NULL) *pdesc = raa_current_db->readkey_data.desc;
1664   	if(psyno != NULL) *psyno = raa_current_db->readkey_data.syno;
1665   	return raa_current_db->readkey_data.name;
1666   	}
1667 
1668   rep=initreponse();
1669   sock_printf(raa_current_db, "readkey&num=%u\n", num);
1670   reponse = read_sock(raa_current_db);
1671   if(reponse == NULL) return NULL;
1672   parse(reponse, rep);
1673   p = val(rep,"code");
1674   if(p == NULL) return NULL;
1675   code = atoi(p);
1676   free(p);
1677   if(code != 0) {
1678   	  clear_reponse(rep);
1679   	  return NULL;
1680   	  }
1681 
1682     raa_current_db->readkey_data.previous = num;
1683   	p = val(rep, "plsub");
1684   	raa_current_db->readkey_data.lsub = atoi_u(p);
1685   	free(p);
1686   	p = val(rep, "desc");
1687   	raa_current_db->readkey_data.desc = atoi_u(p);
1688   	free(p);
1689   	p = val(rep, "syno");
1690   	raa_current_db->readkey_data.syno = atoi_u(p);
1691   	free(p);
1692   	p = val(rep, "libel");
1693   	if(p != NULL) {
1694   		strcpy(raa_current_db->readkey_data.libel, p);
1695   		free(p);
1696   		}
1697   	else *(raa_current_db->readkey_data.libel) = 0;
1698   	p = val(rep, "name");
1699   	strcpy(raa_current_db->readkey_data.name, p);
1700   	free(p);
1701   clear_reponse(rep);
1702   return raa_readkey(raa_current_db, num, plibel, plsub, pdesc, psyno);
1703 }
1704 
1705 
load_smj(raa_db_access * raa_current_db,char *** names,unsigned ** plongs,char *** libels)1706 static int load_smj(raa_db_access *raa_current_db, char ***names, unsigned **plongs, char ***libels)
1707 {
1708   Reponse *rep;
1709   char *reponse, *p;
1710   int nl, i, code, totsmj, recnum;
1711 
1712 if(raa_current_db == NULL) return 0;
1713 totsmj = raa_read_first_rec(raa_current_db, raa_smj);
1714   rep=initreponse();
1715   sock_printf(raa_current_db,"readsmj&num=2&nl=%d\n", totsmj - 1);
1716 /* ==>readsmj&num=..&nl=..
1717 code=0&nl=..
1718 recnum=..&name=".."&plong=..{&libel=".."}   nl times
1719 */
1720   reponse = read_sock(raa_current_db);
1721   if(reponse == NULL) return 0;
1722   parse(reponse, rep);
1723   p = val(rep,"code");
1724   if(p == NULL) return 0;
1725   code = atoi(p);
1726   free(p);
1727   if(code != 0) return 0;
1728   p = val(rep,"nl");
1729   if(p == NULL) return 0;
1730   nl = atoi(p);
1731   free(p);
1732   clear_reponse(rep);
1733   if(nl == 0) return 0;
1734   *names = (char **)calloc(totsmj + 1 , sizeof(char *));
1735   *plongs = (unsigned *)calloc(totsmj + 1 , sizeof(unsigned));
1736   *libels = (char **)calloc(totsmj + 1 , sizeof(char *));
1737   for(i = 0; i < nl; i++) {
1738    	reponse = read_sock(raa_current_db);
1739     if(reponse == NULL) return 0;
1740  	rep=initreponse();
1741     	parse(reponse, rep);
1742   	p = val(rep, "recnum");
1743   	recnum = atoi(p);
1744   	free(p);
1745   	p = val(rep, "plong");
1746   	(*plongs)[recnum] = atoi_u(p);
1747   	free(p);
1748   	p = val(rep, "name");
1749   	(*names)[recnum] = p;
1750   	p = val(rep, "libel");
1751   	(*libels)[recnum] = p;
1752   	clear_reponse(rep);
1753   	}
1754 return totsmj;
1755 }
1756 
1757 
raa_readsmj(raa_db_access * raa_current_db,int num,char ** plibel,int * plong)1758 char *raa_readsmj(raa_db_access *raa_current_db, int num, char **plibel, int *plong)
1759 {
1760 if(raa_current_db == NULL) return NULL;
1761 if(raa_current_db->readsmj_data.lastrec == 0) {
1762 	raa_current_db->readsmj_data.lastrec = load_smj(raa_current_db,
1763 		&raa_current_db->readsmj_data.names, &raa_current_db->readsmj_data.plongs,
1764 		&raa_current_db->readsmj_data.libels);
1765 	}
1766 if(num <= 1 || num > raa_current_db->readsmj_data.lastrec) return NULL;
1767 if(plong != NULL) *plong = raa_current_db->readsmj_data.plongs[num];
1768 if(plibel != NULL) *plibel = raa_current_db->readsmj_data.libels[num];
1769 return raa_current_db->readsmj_data.names[num];
1770 }
1771 
1772 
raa_readacc(raa_db_access * raa_current_db,int num,int * plsub)1773 char *raa_readacc(raa_db_access *raa_current_db, int num, int *plsub)
1774 {
1775   Reponse *rep;
1776   char *p, *reponse;
1777   int code;
1778 
1779 if(raa_current_db == NULL) return NULL;
1780   rep=initreponse();
1781   sock_printf(raa_current_db,"readacc&num=%u\n", num);
1782   reponse = read_sock(raa_current_db);
1783   if(reponse == NULL) return NULL;
1784   parse(reponse, rep);
1785   p = val(rep,"code");
1786   if(p == NULL) return NULL;
1787   code = atoi(p);
1788   free(p);
1789   if(code == 0) {
1790   	if(plsub != NULL) {
1791   		p = val(rep, "plsub");
1792   		*plsub = atoi_u(p);
1793   		free(p);
1794   		}
1795   	p = val(rep, "name");
1796   	strcpy(raa_current_db->access, p);
1797   	free(p);
1798   	p = raa_current_db->access;
1799   	}
1800   else p = NULL;
1801   clear_reponse(rep);
1802   return p;
1803 }
1804 
1805 
raa_readaut(raa_db_access * raa_current_db,int num,int * plref)1806 char *raa_readaut(raa_db_access *raa_current_db, int num, int *plref)
1807 {
1808   Reponse *rep;
1809   char *p, *reponse;
1810   int code;
1811 
1812 if(raa_current_db == NULL) return NULL;
1813   rep=initreponse();
1814   sock_printf(raa_current_db,"readaut&num=%u\n", num);
1815   reponse = read_sock(raa_current_db);
1816   if(reponse == NULL) return NULL;
1817   parse(reponse, rep);
1818   p = val(rep,"code");
1819   if(p == NULL) return NULL;
1820   code = atoi(p);
1821   free(p);
1822   if(code == 0) {
1823   	if(plref != NULL) {
1824   		p = val(rep, "plref");
1825   		*plref = atoi_u(p);
1826   		free(p);
1827   		}
1828   	p = val(rep, "name");
1829   	strcpy(raa_current_db->author, p);
1830   	free(p);
1831   	p = raa_current_db->author;
1832   	}
1833   else p = NULL;
1834   clear_reponse(rep);
1835   return p;
1836 }
1837 
1838 
raa_readbib(raa_db_access * raa_current_db,int num,int * plsub,int * plaut,int * pj,int * py)1839 char *raa_readbib(raa_db_access  *raa_current_db, int num, int *plsub, int *plaut, int *pj, int *py)
1840 {
1841   Reponse *rep;
1842   char *p, *reponse;
1843   int code;
1844 
1845   if (raa_current_db == NULL) return NULL;
1846   rep=initreponse();
1847   sock_printf(raa_current_db,"readbib&num=%u\n", num);
1848   reponse = read_sock(raa_current_db);
1849   if (reponse == NULL) return NULL;
1850   parse(reponse, rep);
1851   p = val(rep,"code");
1852   if(p == NULL) return NULL;
1853   code = atoi(p);
1854   free(p);
1855   if (code == 0) {
1856     if (plsub != NULL) {
1857       p = val(rep, "plsub");
1858       *plsub = atoi_u(p);
1859       free(p);
1860       }
1861     if (plaut != NULL) {
1862       p = val(rep, "plaut");
1863       *plaut = atoi_u(p);
1864       free(p);
1865     }
1866     if (pj != NULL) {
1867       p = val(rep, "j");
1868       *pj = atoi_u(p);
1869       free(p);
1870     }
1871     if (py != NULL) {
1872       p = val(rep, "y");
1873       *py = atoi_u(p);
1874       free(p);
1875     }
1876     p = val(rep, "name");
1877     strcpy(raa_current_db->biblio, p);
1878     free(p);
1879     p = raa_current_db->biblio;
1880   }
1881   else p = NULL;
1882   clear_reponse(rep);
1883   return p;
1884 }
1885 
1886 
raa_readext(raa_db_access * raa_current_db,int num,int * mere,int * deb,int * fin)1887 int raa_readext(raa_db_access *raa_current_db, int num, int *mere, int *deb, int *fin)
1888 {
1889   Reponse *rep;
1890   char *p, *reponse;
1891   int code, next;
1892 
1893 if(raa_current_db == NULL) return 0;
1894   rep=initreponse();
1895   sock_printf(raa_current_db,"readext&num=%u\n", num);
1896   reponse = read_sock(raa_current_db);
1897   if(reponse == NULL) return 0;
1898   parse(reponse, rep);
1899   p = val(rep,"code");
1900   if(p == NULL) return 0;
1901   code = atoi(p);
1902   free(p);
1903   if(code == 0) {
1904   	if(mere != NULL) {
1905   		p = val(rep, "mere");
1906   		*mere = atoi_u(p);
1907   		free(p);
1908   		}
1909   	if(deb != NULL) {
1910   		p = val(rep, "debut");
1911   		*deb = atoi_u(p);
1912   		free(p);
1913   		}
1914   	if(fin != NULL) {
1915   		p = val(rep, "fin");
1916   		*fin = atoi_u(p);
1917   		free(p);
1918   		}
1919   	p = val(rep, "next");
1920   	next = atoi_u(p);
1921   	free(p);
1922   	}
1923   else next = 0;
1924   clear_reponse(rep);
1925   return next;
1926 }
1927 
1928 
raa_readlng(raa_db_access * raa_current_db,int num)1929 int raa_readlng(raa_db_access *raa_current_db, int num)
1930 /* fills the rlng_buffer structure */
1931 {
1932   char *p, *reponse;
1933   int count, i;
1934 
1935 if(raa_current_db == NULL) return 0;
1936   memset(raa_current_db->rlng_buffer, 0, (raa_current_db->SUBINLNG+1)*sizeof(int));
1937   sock_printf(raa_current_db,"readlng&num=%u\n", num);
1938 /* retour code=0&n=xx&x1,x2,...{&next=xx}  */
1939   reponse = read_sock(raa_current_db);
1940   if(reponse == NULL) return 0;
1941   if(strncmp(reponse, "code=0&n=", 9) != 0 || (count = atoi(reponse+9)) == 0) {
1942   	return 0;
1943   	}
1944   p = strchr(reponse+9, '&');
1945   for(i=0; i < count && i < raa_current_db->SUBINLNG; i++) {
1946   	raa_current_db->rlng_buffer->sub[i] = atoi_u(p+1);
1947   	p = strchr(p+1, ',');
1948   	if(p == NULL) break;
1949   	}
1950   p = strstr(reponse, "next=");
1951   if(p!= NULL) raa_current_db->rlng_buffer->next = atoi_u(p+5);
1952   else raa_current_db->rlng_buffer->next=0;
1953   return raa_current_db->rlng_buffer->next;
1954 }
1955 
1956 
1957 
load_shrt_buffer(raa_db_access * raa_current_db,unsigned point)1958 static void load_shrt_buffer(raa_db_access *raa_current_db, unsigned point)
1959 {
1960 char *reponse, *p, *q;
1961 int n, i;
1962 unsigned val, next, previous;
1963 
1964 if(raa_current_db == NULL) return;
1965 sock_printf(raa_current_db, "readshrt&num=%u&max=%d\n", point, MAX_RDSHRT);
1966 /* reponse is:  code=0&n=xx&val,next,.... n times ...\n  */
1967 reponse = read_sock(raa_current_db);
1968 
1969 if(reponse == NULL || strncmp(reponse, "code=0&n=", 9) != 0) {
1970 	return;
1971 	}
1972 n = atoi(reponse + 9);
1973 if (n == 0) return;
1974 p = strchr(reponse+9, '&');
1975 if(p == NULL) return;
1976 q = p + 1;
1977 previous = point;
1978 for(i = 0; i < n; i++) {
1979 	p = strtok(q, ",");
1980 	q = NULL;
1981 	sscanf(p, "%u", &val);
1982 	p = strtok(NULL, ",");
1983 	sscanf(p, "%u", &next);
1984 	raa_current_db->readshrt_data.shrt_begin = (raa_current_db->readshrt_data.shrt_begin + 1) % S_BUF_SHRT;
1985 	raa_current_db->readshrt_data.shrt_buffer[raa_current_db->readshrt_data.shrt_begin][0] = previous;
1986 	raa_current_db->readshrt_data.shrt_buffer[raa_current_db->readshrt_data.shrt_begin][1] = val;
1987 	raa_current_db->readshrt_data.shrt_buffer[raa_current_db->readshrt_data.shrt_begin][2] = next;
1988 	previous = next;
1989 	}
1990 if(raa_current_db->readshrt_data.shrt_begin > raa_current_db->readshrt_data.shrt_max - 1) {
1991 	raa_current_db->readshrt_data.shrt_max = raa_current_db->readshrt_data.shrt_begin + 1;
1992 	}
1993 return;
1994 }
1995 
1996 
raa_readshrt(raa_db_access * raa_current_db,unsigned point,int * pval)1997 unsigned raa_readshrt(raa_db_access *raa_current_db, unsigned point, int *pval)
1998 {
1999 int i;
2000 
2001 if(raa_current_db == NULL) return 0;
2002 if(raa_current_db->readshrt_data.total == 0)
2003 	raa_current_db->readshrt_data.total = (unsigned)raa_read_first_rec(raa_current_db, raa_shrt);
2004 if(point < 2 || point > raa_current_db->readshrt_data.total) return 0;
2005 
2006 for(i = 0; i < raa_current_db->readshrt_data.shrt_max; i++) {
2007 	if(raa_current_db->readshrt_data.shrt_buffer[i][0] == point) {
2008 		if(pval != NULL) *pval = raa_current_db->readshrt_data.shrt_buffer[i][1];
2009 		return raa_current_db->readshrt_data.shrt_buffer[i][2];
2010 		}
2011 	}
2012 load_shrt_buffer(raa_current_db, point);
2013 return raa_readshrt(raa_current_db, point, pval);
2014 }
2015 
2016 
load_shrt2_aux(raa_db_access * raa_current_db,unsigned point,raa_shortl2_kind kind)2017 static void load_shrt2_aux(raa_db_access *raa_current_db, unsigned point, raa_shortl2_kind kind)
2018 {
2019   static const char kind_name[][11] = {"sub_of_bib", "spc_of_loc", "bib_of_loc", "aut_of_bib", "bib_of_aut",
2020     "sub_of_acc", "key_of_sub", "acc_of_loc"};
2021   char *p, *reponse;
2022   int i;
2023 
2024   if (raa_current_db == NULL) return;
2025   sock_printf(raa_current_db, "followshrt2&num=%u&kind=%s&rank=0&max=%d\n", point, kind_name[kind],
2026               raa_current_db->readshrt2_data[kind]->size);
2027   /* reponse is:  code=0&num=xx&rank=xx&n=xx&val,.... n times ...\n  */
2028   reponse = read_sock(raa_current_db);
2029 
2030   if (reponse == NULL || strncmp(reponse, "code=0&", 7) != 0) {
2031     return;
2032   }
2033   raa_current_db->readshrt2_data[kind]->point = point;
2034   p = strstr(reponse, "num=");
2035   raa_current_db->readshrt2_data[kind]->next = atoi(p + 4);
2036   p = strstr(reponse, "n=");
2037   raa_current_db->readshrt2_data[kind]->length = atoi(p + 2);
2038   p = strchr(p, '&') + 1;
2039   for (i = 0; i < raa_current_db->readshrt2_data[kind]->length; i++) {
2040     sscanf(p, "%u", raa_current_db->readshrt2_data[kind]->vals+i);
2041     p = strchr(p, ',') + 1;
2042   }
2043 }
2044 
2045 
raa_followshrt2(raa_db_access * raa_current_db,int * p_point,int * p_rank,raa_shortl2_kind kind)2046 unsigned raa_followshrt2(raa_db_access *raa_current_db, int *p_point, int *p_rank, raa_shortl2_kind kind)
2047 {
2048   int rank = *p_rank;
2049   unsigned retval;
2050 
2051   if (raa_current_db->readshrt2_data[kind]->point == *p_point &&
2052       rank < raa_current_db->readshrt2_data[kind]->length) {
2053     retval = raa_current_db->readshrt2_data[kind]->vals[rank++];
2054     if (rank >= raa_current_db->readshrt2_data[kind]->length) {
2055       *p_rank = 0;
2056       *p_point = raa_current_db->readshrt2_data[kind]->next;
2057     }
2058     else *p_rank = rank;
2059     return retval;
2060   }
2061   load_shrt2_aux(raa_current_db, *p_point, kind);
2062   return raa_followshrt2(raa_current_db, p_point, p_rank, kind);
2063 }
2064 
2065 
raa_ghelp(raa_db_access * raa_current_db,char * fname,char * topic)2066 char *raa_ghelp(raa_db_access *raa_current_db, char *fname, char *topic)
2067 /* returns all help topic in one string in private memory
2068 */
2069 {
2070 char *reponse, *p, *fintext, *tmp;
2071 int nl, l, i;
2072 
2073 if(raa_current_db == NULL) return NULL;
2074   sock_printf(raa_current_db,"ghelp&file=%s&item=%s\n", fname, topic);
2075   reponse = read_sock(raa_current_db);
2076   if(reponse == NULL) return NULL;
2077   nl = 0;
2078   if(strncmp(reponse, "nl=", 3) == 0) nl = atoi(reponse+3);
2079   p = strchr(reponse, '&');
2080   if(nl <= 0 || p == NULL) return NULL;
2081   fintext = raa_current_db->help; p++;
2082   for(i = 0; i < nl; i++) {
2083   	l = strlen(p) + 1; /* +1 pour ajouter \n */
2084   	if( (fintext - raa_current_db->help) + l > raa_current_db->lhelp) {
2085   		raa_current_db->lhelp += 1000;
2086   		tmp = (char *)realloc(raa_current_db->help, raa_current_db->lhelp + 1);
2087   		if(tmp == NULL) {
2088   			if(raa_current_db->help != NULL) free(raa_current_db->help);
2089   			raa_current_db->help = NULL; raa_current_db->lhelp = 0;
2090   			return NULL;
2091   			}
2092   		fintext = tmp + (fintext - raa_current_db->help);
2093   		raa_current_db->help = tmp;
2094   		}
2095   	memcpy(fintext, p, l -1);
2096   	fintext += l;
2097   	*(fintext - 1) = '\n';
2098   	if(i + 1 < nl) reponse = read_sock(raa_current_db);
2099     if(reponse == NULL) return NULL;
2100   	p = reponse;
2101   	}
2102   *fintext = 0;
2103   return raa_current_db->help;
2104 }
2105 
2106 
2107 struct raa_matchkey {
2108 	int *ranks;
2109 	char **names;
2110 	int count;
2111 	int current;
2112 	int no_more;
2113 	};
2114 
raa_free_matchkeys(raa_db_access * raa_current_db)2115 static void raa_free_matchkeys(raa_db_access *raa_current_db)
2116 {
2117 int i;
2118 struct raa_matchkey *data = (struct raa_matchkey *)(raa_current_db->matchkey_data);
2119 
2120 if(data == NULL) return;
2121 if(data->count > 0) {
2122 	for(i = 0; i < data->count; i++) free(data->names[i]);
2123 	free(data->names);
2124 	free(data->ranks);
2125 	}
2126 free(data);
2127 raa_current_db->matchkey_data = NULL;
2128 }
2129 
2130 
next_block_matchkeys(raa_db_access * raa_current_db,int num,char * pattern)2131 static void next_block_matchkeys(raa_db_access *raa_current_db, int num, char *pattern)
2132 {
2133 const int blocksize = 2001;
2134 char *reponse, *p;
2135 int count, i;
2136 struct raa_matchkey *data;
2137 
2138 if(raa_current_db == NULL) return;
2139 raa_free_matchkeys(raa_current_db);
2140 sock_printf(raa_current_db, "nextmatchkey&num=%d", num );
2141   p = protect_quotes(pattern);
2142 if(num == 2) sock_printf(raa_current_db, "&pattern=\"%s\"", p );
2143   free(p);
2144 sock_printf(raa_current_db, "&count=%d\n", blocksize);
2145 reponse = read_sock(raa_current_db);
2146 if(reponse == NULL || strncmp(reponse, "code=0&count=", 13) != 0) return;
2147 sscanf(reponse + 13, "%d", &count);
2148 data = (struct raa_matchkey *)calloc(1, sizeof(struct raa_matchkey));
2149 raa_current_db->matchkey_data = data;
2150 if(data == NULL || count == 0) return;
2151 data->ranks = (int *)malloc(count * sizeof(int));
2152 data->names = (char **)malloc(count * sizeof(char *));
2153 data->current = 0;
2154 data->no_more = (count < blocksize);
2155 data->count = count;
2156 if(data->ranks == NULL || data->names == NULL) data->count = 0;
2157 for(i = 0; i < data->count; i++) {
2158 	reponse = read_sock(raa_current_db);
2159 	sscanf(reponse + 4, "%d", &(data->ranks[i]) );
2160 	p = strchr(reponse, '&');
2161 	p = strchr(p, '=') + 1;
2162 	data->names[i] = strdup(unprotect_quotes(p));
2163 	if(data->names[i] == NULL) {
2164 		data->count = i;
2165 		break;
2166 		}
2167 	}
2168 for(i = data->count; i < count; i++) {
2169 	read_sock(raa_current_db);
2170 	}
2171 return;
2172 }
2173 
2174 
raa_nextmatchkey(raa_db_access * raa_current_db,int num,char * pattern,char ** matching)2175 int raa_nextmatchkey(raa_db_access *raa_current_db, int num, char *pattern, char **matching)
2176 /*  *matching returned in static memory */
2177 {
2178 struct raa_matchkey *data;
2179 int no_more=0, count;
2180 
2181 if(raa_current_db == NULL) return 0;
2182 if(num == 2) {
2183 	next_block_matchkeys(raa_current_db, 2, pattern);
2184 	}
2185 data = (struct raa_matchkey *)(raa_current_db->matchkey_data);
2186 if(data == NULL) return 0;
2187 if(data->current < data->count) {
2188 	if(matching != NULL) *matching = data->names[data->current];
2189 	return data->ranks[(data->current)++];
2190 	}
2191 count = data->count;
2192 if(count > 0) {
2193 	no_more = data->no_more;
2194 	}
2195 raa_free_matchkeys(raa_current_db);
2196 if(count == 0 || no_more) return 0;
2197 next_block_matchkeys(raa_current_db, num, NULL);
2198 return raa_nextmatchkey(raa_current_db, num, NULL, matching);
2199 }
2200 
2201 
atoi_u(const char * p)2202 int atoi_u(const char *p)
2203 {
2204 unsigned value;
2205 
2206 sscanf(p, "%u", &value);
2207 return (int)value;
2208 }
2209 
2210 
protect_quotes(char * name)2211 static char *protect_quotes(char *name)
2212 /* remplacer tous les " par \"
2213 name : une chaine inchangee
2214 retourne un pointeur vers la chaine rendue allouee par malloc
2215 */
2216 {
2217 char *p, *q;
2218 int count;
2219 char *bis;
2220 
2221 count = 0; p = name - 1;
2222 while( (p=strchr(p+1, '"')) != NULL) count++;
2223 if(count == 0) return strdup(name);
2224 
2225 bis = (char *)malloc(strlen(name) + count + 1);
2226 p = name; q = bis;
2227 while(TRUE) {
2228 	if(*p == '"') *(q++) = '\\';
2229 	*q = *p;
2230 	if(*p == 0) break;
2231 	q++; p++;
2232 	}
2233 return bis;
2234 }
2235 
2236 
prepare_remote_file(raa_db_access * raa_current_db,char * oldrequete,char * debut,char * type,int * plrank,char ** badfname)2237 static char *prepare_remote_file(raa_db_access *raa_current_db, char *oldrequete, char *debut, char *type, int *plrank,
2238 	char **badfname)
2239 {
2240 char *p, *q, *reponse, *fin;
2241 char *line = raa_current_db->remote_file;
2242 int nl, l, code;
2243 FILE *in;
2244 Reponse *rep;
2245 
2246 *plrank = 0; *badfname = line;
2247 p = strchr(debut, '=') + 1;
2248 while(isspace(*p)) p++;
2249 if(*p == '"') { /* if filename is bracketed by " */
2250 	*(p++) = ' ';
2251 	fin = strchr(p, '"');
2252 	if(fin == NULL) return NULL;
2253 	*fin = ' ';
2254 	}
2255 else	{
2256 	fin = p;
2257 	do ++fin; while( *fin != 0 && *fin != ')' && !isspace(*fin) );
2258 	}
2259 l = fin - p;
2260 if(l >= sizeof(raa_current_db->remote_file)) l = sizeof(raa_current_db->remote_file) - 1;
2261 memcpy(line, p, l); line[l] = 0;
2262 if(fin - p >= sizeof(raa_current_db->remote_file)) return NULL;
2263 in = fopen(line, "r");
2264 if(in == NULL) return NULL;
2265 nl = 0;
2266 while( fgets(line, sizeof(raa_current_db->remote_file), in) != NULL) nl++;
2267 rewind(in);
2268 sock_printf(raa_current_db, "crelistfromclientdata&type=%s&nl=%d\n", type, nl);
2269 if(nl > 0) {
2270 	while( fgets(line, sizeof(raa_current_db->remote_file), in) != NULL) {
2271 		l = strlen(line);
2272 		if(line[l - 1] != '\n')  strcpy(line + l, "\n");
2273 		sock_fputs(raa_current_db, line);
2274 		}
2275 	}
2276 fclose(in);
2277 
2278 reponse = read_sock(raa_current_db);
2279 if(reponse == NULL) {
2280 	strcpy(line, "connection with server is down");
2281 	return NULL;
2282 	}
2283 rep = initreponse();
2284 parse(reponse, rep);
2285 q = val(rep,"code");
2286 code = atoi(q);
2287 free(q);
2288 if(code != 0) {
2289 	if(code == 3) strcpy(line, "too many lists, delete a few");
2290 	else sprintf(line, "code=%d", code);
2291 	return NULL;
2292 	}
2293 q = val(rep,"name");
2294 l = strlen(q);
2295 reponse = (char *)malloc( (debut - oldrequete) + 1 + l + 1 + strlen(fin) + 1);
2296 p = reponse;
2297 memcpy(p, oldrequete, debut - oldrequete);
2298 p += debut - oldrequete;
2299 *(p++) = ' ';
2300 memcpy(p, q, l);
2301 p += l;
2302 *(p++) = ' ';
2303 free(q);
2304 strcpy(p, fin);
2305 free(oldrequete);
2306 q = val(rep,"lrank");
2307 if(q != NULL) {
2308 	*plrank = atoi(q);
2309 	free(q);
2310 	}
2311 
2312 clear_reponse(rep);
2313 return reponse;
2314 }
2315 
2316 
add_tmp_blist(raa_db_access * raa_current_db,int lrank,int * list)2317 static int *add_tmp_blist(raa_db_access *raa_current_db, int lrank, int *list)
2318 {
2319 if(list == NULL) { /* initialisation */
2320 	if(raa_current_db->tmp_prelist != NULL) free(raa_current_db->tmp_prelist);
2321 	raa_current_db->tmp_total = 10; raa_current_db->tmp_current = 0;
2322 	list = (int *)malloc(raa_current_db->tmp_total*sizeof(int));
2323 	raa_current_db->tmp_prelist = list;
2324 	return list;
2325 	}
2326 if(raa_current_db->tmp_current >= raa_current_db->tmp_total) {
2327 	int *tmp;
2328 	tmp = (int *)realloc(list, (raa_current_db->tmp_total + 10)*sizeof(int));
2329 	if(tmp == NULL) return list;
2330 	raa_current_db->tmp_total += 10;
2331 	list = tmp;
2332 	}
2333 list[raa_current_db->tmp_current++] = lrank;
2334 raa_current_db->tmp_prelist = list;
2335 return list;
2336 }
2337 
2338 
maj_strstr(char * in,char * target)2339 static char *maj_strstr(char *in, char *target)
2340 {
2341 char *p, *buffer;
2342 
2343   buffer = strdup(in);
2344 majuscules(buffer);
2345 p = strstr(buffer, target);
2346 if(p != NULL) p = in + (p - buffer);
2347   free(buffer);
2348 return p;
2349 }
2350 
2351 
raa_requete_remote_file(raa_db_access * raa_current_db,char * oldrequete,int ** plist,char ** pbadfname)2352 static char *raa_requete_remote_file(raa_db_access *raa_current_db, char *oldrequete, int **plist, char **pbadfname)
2353 /*
2354 rend NULL ou une requete dont les F= FA= FS= FK= ont ete changes en list-name
2355 et qui a ete creee par malloc
2356 */
2357 {
2358 char *oldori, *p;
2359 int lrank, *list;
2360 
2361 oldori = strdup(oldrequete);
2362 if(maj_strstr(oldori, "F=") == NULL && maj_strstr(oldori, "FA=") == NULL &&
2363    maj_strstr(oldori, "FK=") == NULL && maj_strstr(oldori, "FS=") == NULL) {
2364 	*plist = NULL;
2365 	return oldori;
2366 	}
2367 list = add_tmp_blist(raa_current_db, 0, NULL); /* initialisation a vide */
2368 while(oldori != NULL && (p = maj_strstr(oldori, "F=")) != NULL) {
2369 	oldori = prepare_remote_file(raa_current_db, oldori, p, "SQ", &lrank, pbadfname);
2370 	if(lrank != 0) list = add_tmp_blist(raa_current_db, lrank, list);
2371 	}
2372 while(oldori != NULL && (p = maj_strstr(oldori, "FA=")) != NULL) {
2373 	oldori = prepare_remote_file(raa_current_db, oldori, p, "AC", &lrank, pbadfname);
2374 	if(lrank != 0) list = add_tmp_blist(raa_current_db, lrank, list);
2375 	}
2376 while(oldori != NULL && (p = maj_strstr(oldori, "FS=")) != NULL) {
2377 	oldori = prepare_remote_file(raa_current_db, oldori, p, "SP", &lrank, pbadfname);
2378 	if(lrank != 0) list = add_tmp_blist(raa_current_db, lrank, list);
2379 	}
2380 while(oldori != NULL && (p = maj_strstr(oldori, "FK=")) != NULL) {
2381 	oldori = prepare_remote_file(raa_current_db, oldori, p, "KW", &lrank, pbadfname);
2382 	if(lrank != 0) list = add_tmp_blist(raa_current_db, lrank, list);
2383 	}
2384 list = add_tmp_blist(raa_current_db, 0, list); /* marquage fin de liste par zero */
2385 if(oldori == NULL && list != NULL) {
2386  	 while(*list != 0) raa_releaselist(raa_current_db,  *(list++) );
2387  	 list = NULL;
2388  	 }
2389 *plist = list;
2390 return oldori;
2391 }
2392 
2393 
raa_savelist(raa_db_access * raa_current_db,int lrank,FILE * out,int use_acc,char * prefix)2394 int raa_savelist(raa_db_access *raa_current_db, int lrank, FILE *out, int use_acc, char *prefix)
2395 {
2396 char *reponse;
2397 int err;
2398 
2399 if(raa_current_db == NULL) return 1;
2400 sock_printf(raa_current_db, "savelist&lrank=%d&type=%c\n", lrank, (use_acc ? 'A' : 'N') );
2401 reponse = read_sock(raa_current_db);
2402 if(reponse == NULL) return 1;
2403 err = strcmp(reponse, "code=0");
2404 if(err != 0) {
2405 	return 1;
2406 	}
2407 while(TRUE) {
2408 	reponse = read_sock(raa_current_db);
2409 	if(reponse == NULL) return 1;
2410 	if(strcmp(reponse, "savelist END.") == 0) break;
2411 	if(prefix != NULL) fputs(prefix, out);
2412 	fprintf(out, "%s\n", reponse);
2413 	}
2414 return 0;
2415 }
2416 
2417 
raa_modifylist(raa_db_access * raa_current_db,int lrank,char * type,char * operation,int * pnewlist,int (* check_interrupt)(void),int * p_processed)2418 int raa_modifylist(raa_db_access *raa_current_db, int lrank, char *type, char *operation, int *pnewlist, int (*check_interrupt)(void),
2419 	int *p_processed )
2420 {
2421 Reponse *rep;
2422 char *p, *reponse;
2423 int code;
2424 
2425 if(raa_current_db == NULL) return 3;
2426 sock_printf(raa_current_db, "modifylist&lrank=%d&type=%s&operation=\"%s\"\n", lrank,
2427 	type, operation );
2428 sock_flush(raa_current_db); /* tres important */
2429 if(check_interrupt == NULL) {
2430 	reponse = read_sock(raa_current_db);
2431 	if(reponse == NULL) return 3;
2432 	}
2433 else	{
2434 	while(TRUE) {
2435 		reponse = read_sock_timeout(raa_current_db, 500 /* msec */);
2436 		if(raa_current_db == NULL) return 3;
2437 		if(reponse != NULL) break;
2438 		if( check_interrupt() ) {
2439 			sock_fputs(raa_current_db, "\033" /* esc */ );
2440 			sock_flush(raa_current_db);
2441 			}
2442 		}
2443 	}
2444 
2445 rep = initreponse();
2446 parse(reponse, rep);
2447 p = val(rep,"code");
2448 code = atoi(p);
2449 free(p);
2450 if(code != 0) return code;
2451 p = val(rep,"lrank");
2452 *pnewlist = atoi(p);
2453 free(p);
2454 p = val(rep,"processed");
2455 if(p != NULL && p_processed != NULL) *p_processed = atoi(p);
2456 if(p != NULL) free(p);
2457 clear_reponse(rep);
2458 return 0;
2459 }
2460 
2461 
raa_knowndbs(raa_db_access * raa_current_db,char *** pnames,char *** pdescriptions)2462 int raa_knowndbs(raa_db_access *raa_current_db, char ***pnames, char ***pdescriptions)
2463 {
2464 int nl;
2465 char **names = NULL, **descriptions = NULL;
2466 char *reponse, *p, *q, *r;
2467 int l, i;
2468 
2469 if(raa_current_db == NULL) return 0;
2470 sock_printf(raa_current_db, "knowndbs\n" );
2471 reponse = read_sock(raa_current_db);
2472 if(reponse == NULL || strncmp(reponse, "nl=", 3) != 0) {
2473 	return 0;
2474 	}
2475 nl = atoi(reponse + 3);
2476 if(nl == 0) return 0;
2477 names = (char **) malloc(nl * sizeof(char *));
2478 descriptions = (char **) malloc(nl * sizeof(char *));
2479 for(i = 0; i < nl; i++) {
2480 	reponse = read_sock(raa_current_db);
2481 	if(reponse == NULL) return 0;
2482 	p = strchr(reponse, '|');
2483 	if(p != NULL)  {
2484 		*(p++) = 0;
2485 		q = strchr(p, '|');
2486 		if(q != NULL)  *(q++) = 0;
2487 		}
2488 	l = strlen(reponse);
2489 	names[i] = (char *)malloc(l+1);
2490 	strcpy(names[i], reponse);
2491 	compact(names[i]);
2492 	if(p != NULL && q != NULL) {
2493 		while( (r=strchr(p, '\t')) != NULL) *r = ' ';
2494 		majuscules(p); compact(p);
2495 		l = strlen(q);
2496 		descriptions[i] = (char *)malloc(l+20);
2497 		descriptions[i][0] = 0;
2498 		if(strcmp(p, "OFF") == 0) strcpy(descriptions[i], "(offline) ");
2499 		strcat(descriptions[i], q);
2500 		}
2501 	else descriptions[i] = NULL;
2502 	}
2503 *pnames = names; *pdescriptions = descriptions;
2504 return nl;
2505 }
2506 
2507 
raa_short_descr(raa_db_access * raa_current_db,int seqnum,char * text,int maxlen,raa_long pinf,int div,char * name)2508 char *raa_short_descr(raa_db_access *raa_current_db, int seqnum, char *text, int maxlen, raa_long pinf, int div, char *name)
2509 /*
2510 to get a description of a sequence or of a subsequence
2511 seqnum	the sequence number
2512 text	the string to be loaded with description
2513 maxlen	the max # of chars allowed in text (\0 is put but not counted in maxlen)
2514 return value	a pointer to text
2515 */
2516 {
2517 int l, deb;
2518 char *p;
2519 
2520 text[maxlen]=0;
2521 strcpy(text, name);
2522 l=strlen(text);
2523 if(strchr(name, '.') != NULL) { /* subsequence */
2524 	if( (p = raa_read_annots(raa_current_db, pinf, div)) == NULL) return text;
2525 	p[20]=0;
2526 	strcat(text,p+4);
2527 	l=strlen(text);
2528 	while(text[l-1]==' ') l--;
2529 	text[l]=0;
2530 	if( ( p = strchr(p + 21, '/') ) != NULL) {
2531 		strncat(text, p, maxlen - l);
2532 		l = strlen(text);
2533 		if(l > 75) return text;
2534 		}
2535 	do	{
2536 		p = raa_next_annots(raa_current_db, NULL);
2537 		if( strcmptrail(p,20,NULL,0) &&
2538 			strncmp(p,"FT        ",10) ) return text;
2539 		}
2540 	while(p[21]!='/');
2541 	do	{
2542 		strncat(text,p+20,maxlen-l);
2543 		l=strlen(text);
2544 		if(l>75) return text;
2545 		p = raa_next_annots(raa_current_db, NULL);
2546 		}
2547 	while ( !strcmptrail(p,20,NULL,0) ||
2548 				!strncmp(p,"FT        ",10) );
2549 	}
2550 else	{ /* parent sequence */
2551 	if( raa_read_annots(raa_current_db, pinf, div) == NULL) return text;
2552 	p = raa_next_annots(raa_current_db, NULL);
2553 	if(raa_current_db->nbrf) {
2554 		deb=17;
2555 		}
2556 	else	{
2557 		deb=13;
2558 		if(raa_current_db->embl || raa_current_db->swissprot) {
2559 			while (strncmp(p,"DE",2)) {
2560 				p = raa_next_annots(raa_current_db, NULL);
2561 				}
2562 			deb=6;
2563 			}
2564 		}
2565 	do	{
2566 		strncat(text,p+deb-2,maxlen-l);
2567 		l=strlen(text);
2568 		if(l>=77) return text;
2569 		p = raa_next_annots(raa_current_db, NULL);
2570 		}
2571 	while( !strncmp(p,"  ",2) || !strncmp(p,"DE",2) );
2572 	}
2573 return text;
2574 }
2575 
2576 
2577 #define END_COORDINATE_TEST(line) strncmp(line, "extractseqs END.", 16)
2578 
next_1_coordinate_set(raa_db_access * raa_current_db)2579 static int *next_1_coordinate_set(raa_db_access *raa_current_db)
2580 {
2581 char  *p, *line, *q;
2582 int  start, last, seqnum, elt, i, count;
2583 int *table = NULL;
2584 
2585 line = read_sock(raa_current_db);
2586 if(END_COORDINATE_TEST(line) == 0) return NULL;
2587 count = 0; p = line;
2588 while(TRUE) {
2589 	p = strchr(p+1, '|');
2590 	if( p == NULL) break;
2591 	count++;
2592 	}
2593 table = (int *)malloc( (3 * count + 1) * sizeof(int));
2594 if(table == NULL) {
2595 	do line = read_sock(raa_current_db);
2596 	while(END_COORDINATE_TEST(line) != 0) ;
2597 	return NULL;
2598 	}
2599 table[0] = count;
2600 elt = 1;
2601 for(i = 0; i < count; i++) {
2602 	p = strchr(line, '|');
2603 	if(p == NULL) break;
2604 	q = strchr(line, '=');
2605 	if(q == NULL || q > p) break;
2606 	sscanf(q+1, "%d", &seqnum);
2607 	q = strchr(q+1, '=');
2608 	if(q == NULL || q > p) break;
2609 	sscanf(q+1, "%d", &start);
2610 	q = strchr(q+1, '=');
2611 	if(q == NULL || q > p) break;
2612 	sscanf(q+1, "%d", &last);
2613 	table[elt++] = seqnum;
2614 	table[elt++] = start;
2615 	table[elt++] = last;
2616 	line = p + 1;
2617 	}
2618 return table;
2619 }
2620 
2621 
2622 struct coord_series_struct {
2623 	int count;
2624 	int **table;
2625 	int next;
2626 	} ;
2627 
raa_prep_coordinates(raa_db_access * raa_current_db,int lrank,int seqnum,char * operation,char * feature_name,char * bounds,char * min_bounds)2628 void *raa_prep_coordinates(raa_db_access *raa_current_db, int lrank, int seqnum,
2629 	char *operation, /* "simple","fragment","feature","region" */
2630 	char *feature_name, char *bounds, char *min_bounds)
2631 /*
2632 only one of lrank and seqnum is != 0 to work on a sequence list or on an individual sequence
2633 feature_name: used for operations feature and region, NULL otherwise
2634 bounds: used for operations fragment and region, NULL otherwise
2635         syntax by examples "45,155"  "-100,100"  "-10,e+100"  "E-10,e+100"
2636 min_bounds: NULL for operations other than fragment and region
2637             can be NULL for fragment and region and means min_bounds same as bounds
2638             if not NULL, same syntax as bounds
2639 pcount: upon return, set to number of coordinate series
2640 
2641 return value: NULL if error, or pointer to opaque data
2642 */
2643 {
2644 char message[200];
2645 char *line;
2646 int *v, maxi, **table, rank;
2647 struct coord_series_struct *retval;
2648 
2649 sprintf(message, "extractseqs&%s=%d&format=coordinates&operation=%s",
2650 	seqnum == 0 ? "lrank" : "seqnum",
2651 	seqnum == 0 ? lrank : seqnum,
2652 	operation);
2653 sock_fputs(raa_current_db, message);
2654 if(strcmp(operation, "feature") == 0 || strcmp(operation, "region") == 0) {
2655 	sprintf(message, "&feature=%s", feature_name);
2656 	sock_fputs(raa_current_db, message);
2657 	}
2658 if(strcmp(operation, "fragment") == 0 || strcmp(operation, "region") == 0) {
2659 	sprintf(message, "&bounds=%s", bounds);
2660 	sock_fputs(raa_current_db, message);
2661 	}
2662 if(min_bounds != NULL) {
2663 	sprintf(message, "&minbounds=%s", min_bounds);
2664 	sock_fputs(raa_current_db, message);
2665 	}
2666 sock_fputs(raa_current_db, "\n"); sock_flush(raa_current_db);
2667 line = read_sock(raa_current_db);
2668 if(strcmp(line, "code=0") != 0) {
2669 	return NULL;
2670 	}
2671 
2672 maxi = 100; rank = 0;
2673 table = (int **)malloc(maxi*sizeof(int *));
2674 if(table == NULL) {
2675 	do line = read_sock(raa_current_db);
2676 	while(END_COORDINATE_TEST(line) != 0) ;
2677 	return NULL;
2678 	}
2679 while( (v = next_1_coordinate_set(raa_current_db)) != NULL) {
2680 	if(rank >= maxi) {
2681 		int **vv;
2682 		vv = (int **)realloc(table, 2*maxi*sizeof(int *));
2683 		if(vv == NULL) {
2684 			do line = read_sock(raa_current_db);
2685 			while(END_COORDINATE_TEST(line) != 0) ;
2686 			break;
2687 			}
2688 		maxi = 2*maxi;
2689 		table = vv;
2690 		}
2691 	table[rank++] = v;
2692 	}
2693 table = realloc(table, rank*sizeof(int *));
2694 retval = (struct coord_series_struct *)malloc(sizeof(struct coord_series_struct));
2695 if(retval == NULL) return NULL;
2696 retval->count = rank;
2697 retval->table = table;
2698 retval->next = 0;
2699 return retval;
2700 }
2701 
2702 
raa_1_coordinate_set(void * v)2703 int *raa_1_coordinate_set(void *v)
2704 /*
2705 to be called repetitively as
2706 table = raa_1_coordinate_set(v);
2707 until returns NULL
2708 with the opaque pointer returned by the raa_prep_coordinates call
2709 
2710 returns int array table in private memory containing 1 + 3*table[0] elements
2711 count = table[0] ;
2712 j = 0;
2713 for(i=0; i < count; i++) {
2714 	table[j+1] is the acnuc number of the sequence
2715 	table[j+2] is the start position in this sequence
2716 	table[j+3] is the end position in this sequence
2717 	j += 3;
2718 	}
2719 start position > end position <==> fragment is on the complementary strand of the acnuc seq
2720 returns NULL when all coordinate series have been processed
2721 */
2722 {
2723 int *retval, i;
2724 struct coord_series_struct *s = (struct coord_series_struct *)v;
2725 
2726 if(s->next >= s->count) {
2727 	for(i=0; i < s->count; i++) free(s->table[i]);
2728 	free(s->table);
2729 	free(s);
2730 	return NULL;
2731 	}
2732 retval = s->table[(s->next)++];
2733 return retval;
2734 }
2735 
2736 
raa_translate_cds(raa_db_access * raa_current_db,int seqnum)2737 char *raa_translate_cds(raa_db_access *raa_current_db, int seqnum)
2738 /* traduction d'un cds avec codon initiateur traite et * internes ==> X
2739 rendue dans memoire allouee ici qu'il ne faut pas modifier
2740 retour NULL si pb lecture de la seq
2741 */
2742 {
2743 int debut_codon, longueur, pos, code, phase;
2744 char codon[4], *p;
2745 
2746 raa_readsub(raa_current_db, seqnum,&longueur,NULL,NULL,NULL,NULL,&phase,&code);
2747 debut_codon = phase + 1;
2748 longueur = (longueur - debut_codon + 1)/3;
2749   raa_current_db->translate_buffer = (char*)realloc(raa_current_db->translate_buffer, longueur + 1);
2750 if(raa_current_db->translate_buffer == NULL) { return NULL; }
2751 raa_current_db->translate_buffer[0] = raa_translate_init_codon(raa_current_db, seqnum);
2752 debut_codon += 3;
2753 for(pos = 1; pos < longueur; pos++) {
2754 	if( raa_gfrag(raa_current_db, seqnum, debut_codon, 3, codon) == 0) return NULL;
2755 	raa_current_db->translate_buffer[pos] = codaa(codon,code);
2756 	debut_codon += 3;
2757 	}
2758 raa_current_db->translate_buffer[longueur] = 0;
2759 while( (p = strchr(raa_current_db->translate_buffer, '*') ) != NULL && p - raa_current_db->translate_buffer < longueur - 1 )
2760 	*p = 'X';
2761 return raa_current_db->translate_buffer;
2762 }
2763 
2764 
raa_translate_init_codon(raa_db_access * raa_current_db,int numseq)2765 char raa_translate_init_codon(raa_db_access *raa_current_db, int numseq)
2766 {
2767 char codon[4];
2768 int point, special_init = TRUE, val, gc, phase, rank = 0;
2769 
2770 if (raa_current_db->num_5_partial == 0) raa_current_db->num_5_partial = raa_iknum(raa_current_db, "5'-PARTIAL", raa_key);
2771 raa_readsub(raa_current_db, numseq, NULL, NULL,NULL, &point, NULL, &phase, &gc);
2772 if(phase != 0) special_init = FALSE;
2773 else	{ /* la seq est-elle 5'-PARTIAL ? */
2774 	while (point != 0) {
2775 		val = raa_followshrt2(raa_current_db, &point, &rank, raa_key_of_sub);
2776 		if (val == raa_current_db->num_5_partial) {
2777 			special_init = FALSE;
2778 			break;
2779 			}
2780 		}
2781 	}
2782 raa_gfrag(raa_current_db, numseq, phase + 1, 3, codon);
2783 if(special_init)  /* traduction speciale du codon initiateur */
2784 	return init_codon_to_aa(codon, gc);
2785 else	return codaa(codon, gc);
2786 }
2787 
2788 
ajout_synonyme(raa_node * secondaire,raa_node * principal)2789 static void ajout_synonyme(raa_node *secondaire, raa_node *principal)
2790 {
2791 raa_node *next;
2792 
2793 if(principal->syno == NULL) {
2794 	principal->syno = secondaire;
2795 	secondaire->syno = principal;
2796 	}
2797 else	{
2798 	next = principal->syno;
2799 	principal->syno = secondaire;
2800 	secondaire->syno = next;
2801 	}
2802 }
2803 
redresse_branches(raa_node * pere)2804 static void redresse_branches(raa_node *pere)
2805 /* Recursively reverse the order of descendants because it has been reversed
2806  */
2807 {
2808   struct raa_pair *point, *next1, *next2, *last;
2809   point = pere->list_desc;
2810   if (!point) return;
2811   next1 = point->next;
2812   if (next1) point->next = NULL;
2813   while (TRUE) {
2814     last = point;
2815     redresse_branches(point->value);
2816     if (!next1) break;
2817     next2 = next1->next;
2818     next1->next = point;
2819     point = next1;
2820     next1 = next2;
2821     }
2822   pere->list_desc = last;
2823 }
2824 
2825 
ajout_branche(raa_node * pere,raa_node * fils)2826 static void ajout_branche(raa_node *pere, raa_node *fils)
2827 /* adds a pere->fils branch. The last added branch is the first child of pere.
2828  */
2829 {
2830 struct raa_pair *nouveau;
2831 
2832 nouveau = (struct raa_pair *)calloc(1,sizeof(struct raa_pair));
2833 nouveau->value = fils;
2834 if( pere->list_desc == NULL) {
2835 	pere->list_desc = nouveau;
2836 	}
2837 else	{
2838   nouveau->next = pere->list_desc;
2839   pere->list_desc = nouveau;
2840 	}
2841 }
2842 
2843 
raa_decode_desc_arbre(char * reponse,raa_node ** tab_noeud)2844 static void raa_decode_desc_arbre(char *reponse, raa_node **tab_noeud)
2845 /* reponse contient
2846 rank&pere&count&"...name..."&"...libel..."
2847 synonyme est identifie par pere < 0 et -pere = son principal
2848 */
2849 {
2850 int num, pere, count, l;
2851 char *p, *q, *name, *libel;
2852 
2853 num = atoi(reponse);
2854 p = strchr(reponse, '&');
2855 pere = atoi(p + 1);
2856 p = strchr(p+1, '&');
2857 count = atoi(p + 1);
2858 /* ne pas brancher un noeud deja branche ailleurs auparavant */
2859 if(tab_noeud[num] != NULL ) return;
2860 tab_noeud[num] = (raa_node *)calloc(1, sizeof(raa_node));
2861 tab_noeud[num]->rank = num;
2862 if(pere < 0) { /* un synonyme */
2863 	ajout_synonyme(tab_noeud[num], tab_noeud[-pere]);
2864 	}
2865 else 	{
2866 	tab_noeud[num]->count = count;
2867 	tab_noeud[num]->parent = tab_noeud[pere];
2868 	if(num != 2) ajout_branche(tab_noeud[pere], tab_noeud[num]);
2869 	}
2870 
2871 p = strchr(p+1, '&') + 1;
2872 q = p;
2873 do 	{
2874 	q++;
2875     	if(*q == 0) break;
2876 	}
2877 while(*q != '"' || *(q-1) == '\\');
2878 l = q-p+1;
2879 name = (char *)malloc(l+1);
2880 strncpy(name, p, l); name[l] = 0;
2881 unprotect_quotes(name);
2882 tab_noeud[num]->name = name;
2883 q++;
2884 if(*q == '&') {
2885 	p = q+1;
2886 	q = p;
2887 	do 	{
2888 		q++;
2889     		if(*q == 0) break;
2890 		}
2891 	while(*q != '"' || *(q-1) == '\\');
2892 	l = q-p+1;
2893 	libel = (char *)malloc(l+1);
2894 	strncpy(libel, p, l); libel[l] = 0;
2895 	unprotect_quotes(libel);
2896 	tab_noeud[num]->libel = libel;
2897 	p = (char *)malloc(l+1);
2898 	strcpy(p, libel);
2899 	majuscules(p);
2900 	tab_noeud[num]->libel_upcase = p;
2901 	if(strncmp(p, "ID:", 3) == 0 || (p = strstr(p, "|ID:")) != NULL) {
2902 		p += 2; if(*p != ':') p++;
2903 		sscanf(p + 1, "%d", &(tab_noeud[num]->tid) );
2904 		}
2905 	}
2906 }
2907 
2908 
raa_calc_taxo_count(raa_node * racine)2909 static void raa_calc_taxo_count(raa_node *racine)
2910 {
2911 struct raa_pair *paire;
2912 int count = 0;
2913 
2914 paire = racine->list_desc;
2915 while(paire != NULL) {
2916 	raa_calc_taxo_count(paire->value);
2917 	count += paire->value->count;
2918 	paire = paire->next;
2919 	}
2920 racine->count += count;
2921 }
2922 
2923 
raa_loadtaxonomy(raa_db_access * raa_current_db,char * rootname,int (* progress_function)(int,void *),void * progress_arg,int (* need_interrupt_f)(void *),void * interrupt_arg)2924 int raa_loadtaxonomy(raa_db_access  *raa_current_db, char *rootname,
2925 	int (*progress_function)(int, void *), void *progress_arg,
2926 	int (*need_interrupt_f)(void *), void *interrupt_arg)
2927 /* charge la taxo complete dans raa_current_db->sp_tree et rend 0 ssi OK */
2928 {
2929 int totspec, i, maxtid;
2930 raa_node **tab_noeud;
2931 struct raa_pair *pair, *pair2;
2932 char *reponse;
2933 int count, pourcent, prev_pourcent = 0;
2934 void *opaque;
2935 int interrupted;
2936 
2937 if(raa_current_db == NULL) return 1;
2938 if(raa_current_db->sp_tree != NULL) return 0;
2939 interrupted = FALSE;
2940 sock_fputs(raa_current_db, "zlibloadtaxonomy\n");
2941 sock_flush(raa_current_db);
2942 /* reply:
2943 <start of compressed data using zlib >
2944 code=0&total=xx
2945 rank&pere&count&"...name..."&"...libel..."
2946 loadtaxonomy END.
2947 <end of compressed data, back to normal data >
2948 */
2949 opaque = prepare_sock_gz_r( raa_current_db->raa_sockfdr );
2950 reponse = z_read_sock(opaque);
2951 if(reponse == NULL || strncmp(reponse, "code=0&total=", 13) != 0) {
2952 	return 1;
2953 	}
2954 totspec = atoi(reponse + 13);
2955 tab_noeud = (raa_node **)calloc(totspec + 1, sizeof(raa_node *));
2956 count = 0;
2957 while(TRUE) {
2958 	reponse = z_read_sock(opaque);
2959 	if(strcmp(reponse, "loadtaxonomy END.") == 0) {
2960 		if(interrupted && (tab_noeud != NULL) ) {
2961 			for(i = 2; i <= totspec; i++) {
2962 				if(tab_noeud[i] == NULL) continue;
2963 				if(tab_noeud[i]->name != NULL) free(tab_noeud[i]->name);
2964 				if(tab_noeud[i]->libel != NULL) free(tab_noeud[i]->libel);
2965 				if(tab_noeud[i]->libel_upcase != NULL) free(tab_noeud[i]->libel_upcase);
2966 				pair = tab_noeud[i]->list_desc;
2967 				while(pair != NULL) {
2968 					pair2 = pair->next;
2969 					free(pair);
2970 					pair = pair2;
2971 					}
2972 				free(tab_noeud[i]);
2973 				}
2974 			free(tab_noeud);
2975 			tab_noeud = NULL;
2976 			/* just to consume ESC that may have arrived after loadtaxonomy END. */
2977 			sock_fputs(raa_current_db, "null_command\n");
2978 			read_sock(raa_current_db);
2979 			}
2980 		break;
2981 		}
2982 	if(tab_noeud != NULL) raa_decode_desc_arbre(reponse, tab_noeud);
2983 	pourcent = ((++count) * 100) / totspec;
2984 	if(pourcent > prev_pourcent) {
2985 		prev_pourcent = pourcent;
2986 		if( progress_function != NULL && progress_function(pourcent, progress_arg) ) {
2987 			if( need_interrupt_f != NULL && (! interrupted) && need_interrupt_f(interrupt_arg) ) {
2988 				sock_fputs(raa_current_db, "\033" /* esc */);
2989 				sock_flush(raa_current_db);
2990 				interrupted = TRUE;
2991 				}
2992 			}
2993 		}
2994 	}
2995 close_sock_gz_r(opaque);
2996 if(tab_noeud != NULL) {
2997 	redresse_branches(tab_noeud[2]);
2998 	raa_calc_taxo_count(tab_noeud[2]);
2999 	free(tab_noeud[2]->name);
3000 	tab_noeud[2]->name = strdup(rootname);
3001 	maxtid = 0;
3002 	for(i = 2; i <= totspec; i++) if(tab_noeud[i] != NULL && tab_noeud[i]->tid > maxtid) maxtid = tab_noeud[i]->tid;
3003 	raa_current_db->tid_to_rank = (int *)calloc(maxtid + 1, sizeof(int));
3004 	if(raa_current_db->tid_to_rank != NULL) {
3005 		raa_current_db->max_tid = maxtid;
3006 		for(i = 2; i <= totspec; i++) {
3007 			if(tab_noeud[i] != NULL && tab_noeud[i]->tid != 0) raa_current_db->tid_to_rank[tab_noeud[i]->tid] =
3008 				tab_noeud[i]->rank;
3009 			}
3010 		}
3011 	raa_current_db->sp_tree = tab_noeud;
3012 	}
3013 return (tab_noeud == NULL ? 1 : 0);
3014 }
3015 
3016 
raa_get_taxon_info(raa_db_access * raa_current_db,char * name,int rank,int tid,int * p_rank,int * p_tid,int * p_parent,struct raa_pair ** p_desc_list)3017 char *raa_get_taxon_info(raa_db_access *raa_current_db, char *name, int rank, int tid, int *p_rank,
3018 	int *p_tid, int *p_parent, struct raa_pair **p_desc_list)
3019 /*
3020 from a taxon identified by its name or, if name is NULL, by its rank or, if rank is 0, by its taxon ID (tid)
3021 computes :
3022 - if p_rank != NULL, the taxon rank in *p_rank
3023 - if p_tid != NULL, the taxon ID in *p_tid
3024 - if p_parent != NULL, the taxon's parent rank in *p_parent (2 indicates that taxon is at top level)
3025 - if p_desc_list != NULL, the start of the linked chain of taxon's descending taxa in *p_desc_list
3026 returns the taxon name, or NULL if any error
3027 */
3028 {
3029 int totspec;
3030 
3031 if(raa_current_db == NULL) return NULL;
3032 if(raa_current_db->sp_tree == NULL) raa_loadtaxonomy(raa_current_db, "root", NULL, NULL, NULL, NULL);
3033 if(raa_current_db->sp_tree == NULL) return NULL;
3034 totspec = raa_read_first_rec(raa_current_db, raa_spec);
3035 if(name != NULL) {
3036 	name = strdup(name);
3037 	if(name == NULL) return NULL;
3038 	trim_key(name); majuscules(name);
3039 	for(rank = 3; rank <= totspec; rank++) {
3040 		if(raa_current_db->sp_tree[rank] != NULL && strcmp(name, raa_current_db->sp_tree[rank]->name) == 0) break;
3041 		}
3042 	free(name);
3043 	}
3044 if(name == NULL && rank == 0 && tid >= 1 && tid <= raa_current_db->max_tid) rank = raa_current_db->tid_to_rank[tid];
3045 if(rank > totspec || rank < 2 || raa_current_db->sp_tree[rank] == NULL) return NULL;
3046 if(rank != 2) {
3047 	while(raa_current_db->sp_tree[rank]->parent == NULL) {
3048 		rank = raa_current_db->sp_tree[rank]->syno->rank;
3049 		}
3050 	}
3051 if(p_rank != NULL) *p_rank = rank;
3052 if(p_tid != NULL) *p_tid = raa_current_db->sp_tree[rank]->tid;
3053 if(p_parent != NULL) *p_parent = ( raa_current_db->sp_tree[rank]->parent != NULL ?
3054 										raa_current_db->sp_tree[rank]->parent->rank : 0);
3055 if(p_desc_list != NULL) *p_desc_list = raa_current_db->sp_tree[rank]->list_desc;
3056 return raa_current_db->sp_tree[rank]->name;
3057 }
3058 
3059 
raa_getattributes_both(raa_db_access * raa_current_db,const char * id,int rank,int * prank,int * plength,int * pframe,int * pgc,char ** pacc,char ** pdesc,char ** pspecies,char ** pseq,char ** pprot)3060 char *raa_getattributes_both(raa_db_access *raa_current_db, const char *id, int rank,
3061 	int *prank, int *plength, int *pframe, int *pgc, char **pacc, char **pdesc, char **pspecies, char **pseq, char **pprot)
3062 /*
3063 for a sequence identified by name or acc. no. (id != NULL) or by rank
3064 returns rank, name, accession, length, frame, acnuc genetic code ID,
3065 one-line description, species, and full sequence.
3066 return value: NULL if not found or name (in private memory)
3067 pacc, pdesc, pspecies, pseq and pprot point to private memory upon return
3068 prank, plength, pframe, pgc, pacc, pdesc, pspecies, pseq, pprot can be NULL is no such information is needed
3069 */
3070 {
3071 Reponse *rep;
3072 char *p, *reponse;
3073 int err;
3074 
3075 if(raa_current_db == NULL) return NULL;
3076 if(id != NULL) sock_printf(raa_current_db, "getattributes&id=%s&seq=%c&prot=%c\n", id, pseq == NULL ? 'F' : 'T', pprot == NULL ? 'F' : 'T');
3077 else sock_printf(raa_current_db, "getattributes&rank=%d&seq=%c&prot=%c\n", rank, pseq == NULL ? 'F' : 'T', pprot == NULL ? 'F' : 'T');
3078 reponse = read_sock(raa_current_db);
3079 if(reponse == NULL) {
3080 	return NULL;
3081 	}
3082 rep=initreponse();
3083 parse(reponse,rep);
3084 p=val(rep,"code");
3085 err = atoi(p);
3086 free(p);
3087 if(err == 0) {
3088 	if(prank != NULL) {
3089 		p=val(rep,"rank");
3090 		*prank = atoi(p);
3091 		free(p);
3092 		}
3093 	if(plength != NULL) {
3094 		p=val(rep,"length");
3095 		*plength = atoi(p);
3096 		free(p);
3097 		}
3098 	if(pframe != NULL) {
3099 		p=val(rep,"fr");
3100 		if(p != NULL) {
3101 			*pframe = atoi(p);
3102 			free(p);
3103 			}
3104 		else *pframe = 0;
3105 		}
3106 	if(pgc != NULL) {
3107 		p=val(rep,"gc");
3108 		if(p != NULL) {
3109 			*pgc = atoi(p);
3110 			free(p);
3111 			}
3112 		else *pgc = 0;
3113 		}
3114 	p = val(rep, "name");
3115 	strcpy(raa_current_db->mnemo, p);
3116 	free(p);
3117 	if(pacc != NULL) {
3118 		p = val(rep, "acc");
3119 		strcpy(raa_current_db->access, p);
3120 		free(p);
3121 		*pacc = raa_current_db->access;
3122 		}
3123 	if(pspecies != NULL) {
3124 		p = val(rep, "spec");
3125 		strcpy(raa_current_db->species, p);
3126 		free(p);
3127 		*pspecies = raa_current_db->species;
3128 		p = raa_current_db->species;
3129 		while(*(++p) != 0) *p = tolower(*p);
3130 		}
3131 	if(pdesc != NULL) {
3132 		p = val(rep, "descr");
3133 		strcpy(raa_current_db->descript, p);
3134 		free(p);
3135 		*pdesc = raa_current_db->descript;
3136 		}
3137 	if(pseq != NULL || pprot != NULL) {
3138 		char *p = read_sock(raa_current_db);
3139 		char *q = strstr(p, "prot=");
3140 		if (q && q > p && *(q-1) == '&') *(q-1) = 0;
3141 		p = strstr(p, "seq=");
3142 		if (pseq != NULL) {
3143 			if (p) *pseq = p + 4; /* seq=xxxx */
3144 			else *pseq = "";
3145 			}
3146 		if (pprot != NULL) {
3147 			if (q) *pprot = q + 5; /* prot=xxxx */
3148 			else *pprot = "";
3149 			}
3150 		}
3151 	err = 0;
3152 	}
3153 clear_reponse(rep);
3154 return (err ? NULL : raa_current_db->mnemo);
3155 }
3156 
3157 
raa_getattributes(raa_db_access * raa_current_db,const char * id,int * prank,int * plength,int * pframe,int * pgc,char ** pacc,char ** pdesc,char ** pspecies,char ** pseq)3158 char *raa_getattributes(raa_db_access *raa_current_db, const char *id,
3159 						int *prank, int *plength, int *pframe, int *pgc, char **pacc, char **pdesc, char **pspecies, char **pseq)
3160 {
3161 	return raa_getattributes_both(raa_current_db, id, 0, prank, plength, pframe, pgc, pacc, pdesc, pspecies, pseq, NULL);
3162 }
3163 
3164 
raa_seqrank_attributes(raa_db_access * raa_current_db,int rank,int * plength,int * pframe,int * pgc,char ** pacc,char ** pdesc,char ** pspecies,char ** pseq)3165 char *raa_seqrank_attributes(raa_db_access *raa_current_db, int rank,
3166 							 int *plength, int *pframe, int *pgc, char **pacc, char **pdesc, char **pspecies, char **pseq)
3167 {
3168 	return raa_getattributes_both(raa_current_db, NULL, rank, NULL, plength, pframe, pgc, pacc, pdesc, pspecies, pseq, NULL);
3169 }
3170 
3171 
3172 
3173