1 /* @source jembossctl
2 **
3 ** @author Copyright (C) 2002 Alan Bleasby
4 ** @version 1.0
5 ** @modified Mar 02 2002 ajb First version
6 ** @@
7 **
8 ** This library is free software; you can redistribute it and/or
9 ** modify it under the terms of the GNU Library General Public
10 ** License as published by the Free Software Foundation; either
11 ** version 2 of the License, or (at your option) any later version.
12 **
13 ** This library is distributed in the hope that it will be useful,
14 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 ** Library General Public License for more details.
17 **
18 ** You should have received a copy of the GNU Library General Public
19 ** License along with this library; if not, write to the
20 ** Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 ** Boston, MA  02111-1307, USA.
22 ******************************************************************************/
23 
24 #include "emboss.h"
25 
26 #ifdef HAVE_JAVA
27 
28 #include <errno.h>
29 #include <sys/types.h>
30 #include <fcntl.h>
31 #include <grp.h>
32 
33 #include <sys/file.h>
34 #include <sys/resource.h>
35 #include <sys/param.h>
36 #include <sys/wait.h>
37 #include <dirent.h>
38 #include <sys/stat.h>
39 #include <sys/time.h>
40 #include <strings.h>
41 #include <sys/ioctl.h>
42 #include <limits.h>
43 
44 #ifdef __hpux
45 #include <stropts.h>
46 #endif /* !__hpux */
47 
48 #ifdef HAVE_POLL
49 #include <poll.h>
50 #endif /* !HAVE_POLL */
51 
52 #if defined (__SVR4) && defined (__sun)
53 #include <sys/filio.h>
54 #endif /* !(__SVR4 && __sun) */
55 
56 #if defined(__CYGWIN__)
57 #include <sys/termios.h>
58 #endif /* __CYGWIN__ */
59 
60 #ifndef TOMCAT_UID
61 #define TOMCAT_UID 506	  /* Set this to be the UID of the tomcat process */
62 #endif /* !TOMCAT_UID */
63 
64 #define UIDLIMIT 0
65 #define GIDLIMIT 0
66 
67 
68 #define TIMEOUT 30	/* Arbitrary pipe timeout (secs)                  */
69 #define TIMEBUFFER 256	/* Arbitrary length buffer for time printing      */
70 #define PUTTIMEOUT  120	/* Max no. of secs to write a file                */
71 
72 #define R_BUFFER 2048   /* Arbitrary length buffer for reentrant syscalls */
73 
74 
75 
76 
77 static AjBool jembossctl_up(char *buf,int *uid,int *gid,AjPStr *home);
78 static AjBool jembossctl_do_fork(char *buf, int uid, int gid);
79 static AjBool jembossctl_do_batch(char *buf, int uid, int gid);
80 static AjBool jembossctl_do_directory(char *buf, int uid, int gid);
81 static AjBool jembossctl_do_deletefile(char *buf, int uid, int gid);
82 static AjBool jembossctl_do_seq(char *buf, int uid, int gid);
83 static AjBool jembossctl_do_seqset(char *buf, int uid, int gid);
84 static AjBool jembossctl_do_renamefile(char *buf, int uid, int gid);
85 static AjBool jembossctl_do_deletedir(char *buf, int uid, int gid);
86 static AjBool jembossctl_do_listfiles(char *buf, int uid, int gid,
87 				      AjPStr *retlist);
88 static AjBool jembossctl_do_listdirs(char *buf, int uid, int gid,
89 				     AjPStr *retlist);
90 static AjBool jembossctl_do_getfile(char *buf, int uid, int gid,
91 			      unsigned char **fbuf, int *size);
92 static AjBool jembossctl_do_putfile(char *buf, int uid, int gid);
93 
94 static char **jembossctl_make_array(const AjPStr str);
95 static void jembossctl_tidy_strings(AjPStr *tstr, AjPStr *home,
96 				    AjPStr *retlist,
97 				    char *buf);
98 static void jembossctl_fork_tidy(AjPStr *cl, AjPStr *prog, AjPStr *enviro,
99 				 AjPStr *dir, AjPStr *outstd, AjPStr *errstd);
100 static AjBool jembossctl_check_buffer(char *buf, int mlen);
101 static AjBool jembossctl_chdir(const char *file);
102 static AjBool jembossctl_initgroups(const char *buf, int gid);
103 static void jembossctl_zero(char *buf);
104 static time_t jembossctl_Datestr(const AjPStr s);
105 static int    jembossctl_date(const void* str1, const void* str2);
106 
107 static AjBool jembossctl_GetSeqFromUsa(const AjPStr thys, AjPSeq *seq);
108 static AjBool jembossctl_GetSeqsetFromUsa(const AjPStr thys, AjPSeqset *seq);
109 
110 
111 
112 
113 #include <pwd.h>
114 #ifndef _XOPEN_SOURCE
115 #define _XOPEN_SOURCE
116 #endif /* !_XOPEN_SOURCE */
117 
118 #if !defined(__ppc__) && !defined(__APPLE__) && !defined(__FreeBSD__)
119 #include <crypt.h>
120 #endif /* !__ppc__ && !__APPLE__ && !__FreeBSD__ */
121 
122 #ifdef N_SHADOW
123 #include <shadow.h>
124 #endif /* N_SHADOW */
125 #ifdef R_SHADOW
126 #include <shadow.h>
127 #endif /* R_SHADOW */
128 #ifdef HPUX_SHADOW
129 #include <shadow.h>
130 #endif /* HPUX_SHADOW */
131 
132 #ifdef PAM
133 #if defined(__ppc__) || defined(__APPLE__)
134 #include <pam/pam_appl.h>
135 #else /* !(__ppc__ || __APPLE__)*/
136 #include <security/pam_appl.h>
137 #endif /* !(__ppc__ || __APPLE__)*/
138 #endif /* PAM */
139 
140 #ifdef AIX_SHADOW
141 #include <userpw.h>
142 #endif /* AIX_SHADOW */
143 
144 #ifdef HPUX_SHADOW
145 #include <prot.h>
146 #endif /* HPUX_SHADOW */
147 
148 
149 static void jembossctl_empty_core_dump(void);
150 #ifndef NO_AUTH
151 static AjBool jembossctl_check_pass(AjPStr username, AjPStr password,
152 				    ajint *uid,
153 				    ajint *gid, AjPStr *home);
154 #endif /* !NO_AUTH */
155 
156 #ifdef PAM
157 static int jembossctl_pam_conv(int num_msg, struct pam_message **msg,
158 			       struct pam_response **resp, void *appdata_ptr);
159 #endif /* PAM */
160 
161 #define JBUFFLEN 10000
162 
163 
164 
165 
166 static int jembossctl_pipe_read(char *buf, int n, int seconds);
167 static int jembossctl_pipe_write(const char *buf, int n, int seconds);
168 static int jembossctl_snd(const char *buf,int len);
169 static int jembossctl_rcv(char *buf);
170 
171 static int jembossctl_java_block(int chan, unsigned long flag);
172 
173 #ifndef __ppc__
174 extern char *strptime(const char *s, const char *format, struct tm *tm);
175 #endif /* !__ppc__ */
176 
177 #if defined (__SVR4) && defined (__sun)
178 #define exit(a) _exit(a)
179 #endif /* __SRV4 && __sun */
180 
181 
182 
183 
184 /* @prog jembossctl ***********************************************************
185 **
186 ** Slave suid program for Jemboss
187 **
188 ******************************************************************************/
189 
main(void)190 int main(void)
191 {
192     AjPStr message = NULL;
193     char *cbuf = NULL;
194     int mlen;
195     int command = 0;
196     int uid = 0;
197     int gid = 0;
198     AjPStr home = NULL;
199     AjBool ok = ajFalse;
200     char c = '\0';
201     AjPStr tstr = NULL;
202     AjPStr retlist = NULL;
203     unsigned char *fbuf = NULL;
204     int size;
205 
206     /* Only allow user with the real uid TOMCAT_UID to proceed */
207     if(getuid() != TOMCAT_UID)
208 	exit(-1);
209 
210     home    = ajStrNew();
211     tstr    = ajStrNew();
212     retlist = ajStrNew();
213 
214 
215     if(!(cbuf=(char *)malloc(JBUFFLEN+1)))
216     {
217 	jembossctl_tidy_strings(&tstr,&home,&retlist,cbuf);
218 	fprintf(stderr,"jctl buf malloc error (jembossctl)\n");
219 	fflush(stderr);
220 	exit(-1);
221     }
222 
223     bzero((void*)cbuf,JBUFFLEN+1);
224 
225     jembossctl_empty_core_dump();
226 
227 
228     message = ajStrNewC("OK");
229     if(jembossctl_snd(ajStrGetPtr(message),ajStrGetLen(message))==-1)
230     {
231 	jembossctl_tidy_strings(&tstr,&home,&retlist,cbuf);
232 	ajStrDel(&message);
233 	fprintf(stderr,"jctl send error (jembossctl)\n");
234 	fflush(stderr);
235 	exit(-1);
236     }
237 
238 
239     /* Wait for a command from jni */
240 
241     if((mlen = jembossctl_rcv(cbuf))==-1)
242     {
243 	jembossctl_tidy_strings(&tstr,&home,&retlist,cbuf);
244 	ajStrDel(&message);
245 	fprintf(stderr,"jctl command recv error (jembossctl)\n");
246 	fflush(stderr);
247 	exit(-1);
248     }
249 
250 
251     if(!jembossctl_check_buffer(cbuf,mlen))
252     {
253 	jembossctl_tidy_strings(&tstr,&home,&retlist,cbuf);
254 	ajStrDel(&message);
255 	fprintf(stderr,"jctl bad buffer error (jembossctl)\n");
256 	fflush(stderr);
257 	exit(-1);
258     }
259 
260 
261 
262     if(sscanf(cbuf,"%d",&command)!=1)
263     {
264 	jembossctl_tidy_strings(&tstr,&home,&retlist,cbuf);
265 	ajStrDel(&message);
266 	fprintf(stderr,"jctl sscanf error (jembossctl)\n");
267 	fflush(stderr);
268 	exit(-1);
269     }
270 
271 
272     switch(command)
273     {
274     case COMM_AUTH:
275 	ajStrAssignC(&tstr,cbuf);
276 	c='\0';
277 	ok = jembossctl_up(tstr->Ptr,&uid,&gid,&home);
278 	if(ok)
279 	    c=1;
280 
281  	if((mlen = jembossctl_snd(&c,1)) < 0)
282 	{
283 	    jembossctl_tidy_strings(&tstr,&home,&retlist,cbuf);
284 	    ajStrDel(&message);
285 	    fprintf(stderr,"jctl command send error (auth)\n");
286 	    fflush(stderr);
287 	    exit(-1);
288 	}
289 	fprintf(stdout,"%s",ajStrGetPtr(home));
290 	break;
291 
292     case EMBOSS_FORK:
293 	ajStrAssignC(&tstr,cbuf);
294 	ok = jembossctl_up(tstr->Ptr,&uid,&gid,&home);
295 
296 	if(ok)
297 	    ok = jembossctl_do_fork(cbuf,uid,gid);
298 	break;
299 
300     case MAKE_DIRECTORY:
301 	ajStrAssignC(&tstr,cbuf);
302 	ok = jembossctl_up(tstr->Ptr,&uid,&gid,&home);
303 	if(ok)
304 	    ok = jembossctl_do_directory(cbuf,uid,gid);
305 	break;
306 
307     case DELETE_FILE:
308 	ajStrAssignC(&tstr,cbuf);
309 	ok = jembossctl_up(tstr->Ptr,&uid,&gid,&home);
310 	if(ok)
311 	    ok = jembossctl_do_deletefile(cbuf,uid,gid);
312 	break;
313 
314     case DELETE_DIR:
315 	ajStrAssignC(&tstr,cbuf);
316 	ok = jembossctl_up(tstr->Ptr,&uid,&gid,&home);
317 	if(ok)
318 	    ok = jembossctl_do_deletedir(cbuf,uid,gid);
319 	break;
320 
321     case LIST_FILES:
322 	ajStrAssignC(&tstr,cbuf);
323 	ok = jembossctl_up(tstr->Ptr,&uid,&gid,&home);
324 
325 	if(ok)
326 	    ok = jembossctl_do_listfiles(cbuf,uid,gid,&retlist);
327 
328 	fprintf(stdout,"%s",ajStrGetPtr(retlist));
329 	break;
330 
331     case LIST_DIRS:
332 	ajStrAssignC(&tstr,cbuf);
333 	ok = jembossctl_up(tstr->Ptr,&uid,&gid,&home);
334 	if(ok)
335 	    ok = jembossctl_do_listdirs(cbuf,uid,gid,&retlist);
336 
337 	fprintf(stdout,"%s",ajStrGetPtr(retlist));
338 	break;
339 
340     case GET_FILE:
341 	ajStrAssignC(&tstr,cbuf);
342 	ok = jembossctl_up(tstr->Ptr,&uid,&gid,&home);
343 	if(ok)
344 	    ok = jembossctl_do_getfile(cbuf,uid,gid,&fbuf,&size);
345 
346 	break;
347 
348     case PUT_FILE:
349 	ajStrAssignC(&tstr,cbuf);
350 	ok = jembossctl_up(tstr->Ptr,&uid,&gid,&home);
351 	if(ok)
352 	    ok = jembossctl_do_putfile(cbuf,uid,gid);
353 
354 	break;
355 
356     case BATCH_FORK:
357 	ajStrAssignC(&tstr,cbuf);
358 	ok = jembossctl_up(tstr->Ptr,&uid,&gid,&home);
359 
360 	if(ok)
361 	    ok = jembossctl_do_batch(cbuf,uid,gid);
362 	break;
363 
364     case RENAME_FILE:
365 	ajStrAssignC(&tstr,cbuf);
366 	ok = jembossctl_up(tstr->Ptr,&uid,&gid,&home);
367 	if(ok)
368 	    ok = jembossctl_do_renamefile(cbuf,uid,gid);
369 	break;
370 
371 
372     case SEQ_ATTRIB:
373 	ajStrAssignC(&tstr,cbuf);
374 	ok = jembossctl_up(tstr->Ptr,&uid,&gid,&home);
375 	if(ok)
376 	    ok = jembossctl_do_seq(cbuf,uid,gid);
377 	break;
378 
379     case SEQSET_ATTRIB:
380 	ajStrAssignC(&tstr,cbuf);
381 	ok = jembossctl_up(tstr->Ptr,&uid,&gid,&home);
382 	if(ok)
383 	    ok = jembossctl_do_seqset(cbuf,uid,gid);
384 	break;
385 
386     default:
387 	break;
388     }
389 
390 
391     bzero((void*)cbuf,JBUFFLEN+1);
392     ajStrDel(&message);
393     jembossctl_tidy_strings(&tstr,&home,&retlist,cbuf);
394 
395     fflush(stdout);
396     fflush(stderr);
397     exit(0);
398 
399     return 0;
400 }
401 
402 
403 
404 
405 /* @funcstatic jembossctl_empty_core_dump *************************************
406 **
407 ** Set process coredump size to be zero
408 **
409 ** @return [void]
410 ** @@
411 ******************************************************************************/
412 
jembossctl_empty_core_dump(void)413 static void jembossctl_empty_core_dump(void)
414 {
415     struct rlimit limit;
416 
417     limit.rlim_cur = 0;
418     limit.rlim_max = 0;
419 
420     setrlimit(RLIMIT_CORE,&limit);
421 
422     return;
423 }
424 
425 
426 
427 
428 #ifdef N_SHADOW
429 /* @header jembossctl_check_pass **********************************************
430 **
431 ******************************************************************************/
jembossctl_check_pass(AjPStr username,AjPStr password,ajint * uid,ajint * gid,AjPStr * home)432 static AjBool jembossctl_check_pass(AjPStr username, AjPStr password,
433 				    ajint *uid,
434 			      ajint *gid, AjPStr *home)
435 {
436     struct spwd *shadow = NULL;
437     struct passwd *pwd  = NULL;
438     char *p = NULL;
439 
440 
441     shadow = getspnam(ajStrGetPtr(username));
442 
443     if(!shadow)                 /* No such username */
444         return ajFalse;
445 
446 
447     pwd = getpwnam(ajStrGetPtr(username));
448 
449     if(!pwd)
450         return ajFalse;
451 
452     *uid = pwd->pw_uid;
453     *gid = pwd->pw_gid;
454 
455     ajStrAssignC(home,pwd->pw_dir);
456 
457     p = crypt(ajStrGetPtr(password),shadow->sp_pwdp);
458 
459     if(!strcmp(p,shadow->sp_pwdp))
460         return ajTrue;
461 
462     return ajFalse;
463 }
464 #endif /* N_SHADOW */
465 
466 
467 
468 
469 #ifdef AIX_SHADOW
470 /* @header jembossctl_check_pass **********************************************
471 **
472 ******************************************************************************/
jembossctl_check_pass(AjPStr username,AjPStr password,ajint * uid,ajint * gid,AjPStr * home)473 static AjBool jembossctl_check_pass(AjPStr username, AjPStr password,
474 				    ajint *uid,
475 			      ajint *gid, AjPStr *home)
476 {
477     struct userpw *shadow = NULL;
478     struct passwd *pwd    = NULL;
479     char *p = NULL;
480 
481     shadow = getuserpw(ajStrGetPtr(username));
482     if(!shadow)
483 	return ajFalse;
484 
485     pwd = getpwnam(ajStrGetPtr(username));
486     if(!pwd)
487 	return ajFalse;
488 
489     *uid = pwd->pw_uid;
490     *gid = pwd->pw_gid;
491 
492     ajStrAssignC(home,pwd->pw_dir);
493 
494     p = crypt(ajStrGetPtr(password),shadow->upw_passwd);
495 
496     if(!strcmp(p,shadow->upw_passwd))
497 	return ajTrue;
498 
499     return ajFalse;
500 }
501 #endif /* AIX_SHADOW */
502 
503 
504 
505 
506 #ifdef HPUX_SHADOW
507 /* @header jembossctl_check_pass **********************************************
508 **
509 ******************************************************************************/
jembossctl_check_pass(AjPStr username,AjPStr password,ajint * uid,ajint * gid,AjPStr * home)510 static AjBool jembossctl_check_pass(AjPStr username, AjPStr password,
511 				    ajint *uid,
512 			ajint *gid, AjPStr *home)
513 {
514     struct spwd *shadow = NULL;
515     struct spwd sresult;
516     struct passwd *pwd  = NULL;
517     struct passwd presult;
518     char *p = NULL;
519     char *epwd = NULL;
520     char *buf  = NULL;
521     int ret = 0;
522     int trusted;
523 
524     trusted = iscomsec();
525     if(!(epwd=(char *)malloc(R_BUFFER)))
526 	return ajFalse;
527 
528 
529     if(trusted)
530     {
531 	shadow = getspnam(ajStrGetPtr(username));
532 	if(!shadow)
533 	{
534 	    AJFREE(epwd);
535 	    return ajFalse;
536 	}
537 	strcpy(epwd,shadow->sp_pwdp);
538     }
539 
540 
541     if(!(buf=(char *)malloc(R_BUFFER)))
542 	return ajFalse;
543 
544     ret = getpwnam_r(ajStrGetPtr(username),&presult,buf,R_BUFFER,&pwd);
545     if(ret!=0)
546     {
547 	AJFREE(buf);
548 	AJFREE(epwd);
549 	return ajFalse;
550     }
551 
552     if(!trusted)
553 	strcpy(epwd,pwd->pw_passwd);
554 
555     *uid = pwd->pw_uid;
556     *gid = pwd->pw_gid;
557     ajStrAssignC(home,pwd->pw_dir);
558 
559     p = crypt(ajStrGetPtr(password),epwd);
560 
561     if(!strcmp(p,epwd))
562     {
563 	AJFREE(buf);
564 	AJFREE(epwd);
565 	return ajTrue;
566     }
567 
568     AJFREE(buf);
569     AJFREE(epwd);
570 
571     return ajFalse;
572 }
573 #endif /* HPUX_SHADOW */
574 
575 
576 
577 
578 #ifdef NO_SHADOW
579 /* @header jembossctl_check_pass **********************************************
580 **
581 ******************************************************************************/
jembossctl_check_pass(AjPStr username,AjPStr password,ajint * uid,ajint * gid,AjPStr * home)582 static AjBool jembossctl_check_pass(AjPStr username, AjPStr password,
583 				    ajint *uid,
584 				    ajint *gid, AjPStr *home)
585 {
586     struct passwd *pwd  = NULL;
587     char *p = NULL;
588 
589     pwd = getpwnam(ajStrGetPtr(username));
590     if(!pwd)		 /* No such username */
591 	return ajFalse;
592 
593     *uid = pwd->pw_uid;
594     *gid = pwd->pw_gid;
595 
596     ajStrAssignC(home,pwd->pw_dir);
597 
598     p = crypt(ajStrGetPtr(password),pwd->pw_passwd);
599 
600     if(!strcmp(p,pwd->pw_passwd))
601 	return ajTrue;
602 
603     return ajFalse;
604 }
605 #endif /* NO_SHADOW */
606 
607 
608 
609 
610 #ifdef R_SHADOW
611 /* @header jembossctl_check_pass **********************************************
612 **
613 ******************************************************************************/
jembossctl_check_pass(AjPStr username,AjPStr password,ajint * uid,ajint * gid,AjPStr * home)614 static AjBool jembossctl_check_pass(AjPStr username, AjPStr password,
615 				    ajint *uid,
616 			      ajint *gid, AjPStr *home)
617 {
618     struct spwd *shadow = NULL;
619     struct spwd sresult;
620     struct passwd *pwd  = NULL;
621     struct passwd presult;
622     char *p = NULL;
623     char *sbuf = NULL;
624     char *buf  = NULL;
625 #ifdef _POSIX_C_SOURCE
626     int ret = 0;
627 #endif /* _POSIX_C_SOURCE */
628 
629     if(!(buf=(char*)malloc(R_BUFFER)) || !(sbuf=(char*)malloc(R_BUFFER)))
630 	return ajFalse;
631 
632     shadow = getspnam_r(ajStrGetPtr(username),&sresult,sbuf,R_BUFFER);
633 
634     if(!shadow)                 /* No such username */
635     {
636 	AJFREE(buf);
637 	AJFREE(sbuf);
638         return ajFalse;
639     }
640 
641 
642 #ifdef _POSIX_C_SOURCE
643     ret = getpwnam_r(ajStrGetPtr(username),&presult,buf,R_BUFFER,&pwd);
644 
645     if(ret!=0)
646     {
647 	AJFREE(buf);
648 	AJFREE(sbuf);
649         return ajFalse;
650     }
651 #else /* !_POSIX_C_SOURCE */
652     pwd = getpwnam_r(ajStrGetPtr(username),&presult,buf,R_BUFFER);
653 
654     if(!pwd)
655     {
656 	AJFREE(buf);
657 	AJFREE(sbuf);
658         return ajFalse;
659     }
660 #endif /* !_POSIX_C_SOURCE */
661 
662     *uid = pwd->pw_uid;
663     *gid = pwd->pw_gid;
664 
665     ajStrAssignC(home,pwd->pw_dir);
666 
667     p = crypt(ajStrGetPtr(password),shadow->sp_pwdp);
668 
669     if(!strcmp(p,shadow->sp_pwdp))
670     {
671 	AJFREE(buf);
672 	AJFREE(sbuf);
673         return ajTrue;
674     }
675 
676     AJFREE(buf);
677     AJFREE(sbuf);
678 
679     return ajFalse;
680 }
681 #endif /* R_SHADOW */
682 
683 
684 
685 
686 #ifdef RNO_SHADOW
687 /* @header jembossctl_check_pass **********************************************
688 **
689 ******************************************************************************/
jembossctl_check_pass(AjPStr username,AjPStr password,ajint * uid,ajint * gid,AjPStr * home)690 static AjBool jembossctl_check_pass(AjPStr username, AjPStr password,
691 				    ajint *uid,
692 				    ajint *gid, AjPStr *home)
693 {
694     struct passwd *pwd  = NULL;
695     char *p = NULL;
696     struct passwd result;
697     char *buf = NULL;
698 #if defined(_OSF_SOURCE) || defined(__FreeBSD__)
699     int  ret = 0;
700 #endif /* _OSF_SOURCE || __FreeBSD__ */
701 
702     if(!(buf=(char *)malloc(R_BUFFER)))
703 	return ajFalse;
704 
705 #if defined(_OSF_SOURCE) || defined(__FreeBSD__)
706     ret = getpwnam_r(ajStrGetPtr(username),&result,buf,R_BUFFER,&pwd);
707     if(ret!=0)		 /* No such username */
708     {
709 	AJFREE(buf);
710 	return ajFalse;
711     }
712 #else /* !(_OSF_SOURCE || __FreeBSD__) */
713     pwd = getpwnam_r(ajStrGetPtr(username),&result,buf,R_BUFFER);
714     if(!pwd)		 /* No such username */
715     {
716 	AJFREE(buf);
717 	return ajFalse;
718     }
719 #endif /* !(_OSF_SOURCE || __FreeBSD__) */
720 
721     *uid = pwd->pw_uid;
722     *gid = pwd->pw_gid;
723 
724     ajStrAssignC(home,pwd->pw_dir);
725 
726     p = crypt(ajStrGetPtr(password),pwd->pw_passwd);
727 
728     if(!strcmp(p,pwd->pw_passwd))
729     {
730 	AJFREE(buf);
731 	return ajTrue;
732     }
733 
734     AJFREE(buf);
735 
736     return ajFalse;
737 }
738 #endif /* RNO_SHADOW */
739 
740 
741 
742 
743 #ifdef PAM
744 
745 struct ad_user
746 {
747     char *username;
748     char *password;
749 };
750 
751 
752 
753 
754 /* @header jembossctl_pam_conv ************************************************
755 **
756 ******************************************************************************/
jembossctl_pam_conv(int num_msg,struct pam_message ** msg,struct pam_response ** resp,void * appdata_ptr)757 static int jembossctl_pam_conv(int num_msg, struct pam_message **msg,
758 			       struct pam_response **resp, void *appdata_ptr)
759 {
760     struct ad_user *user;
761     struct pam_response *response;
762     int i;
763 
764     user = (struct ad_user *)appdata_ptr;
765 
766     if(msg == NULL || resp == NULL || user == NULL)
767     	return PAM_CONV_ERR;
768 
769     response= (struct pam_response *)
770     	malloc(num_msg * sizeof(struct pam_response));
771 
772     for(i=0;i<num_msg;++i)
773     {
774 	response[i].resp_retcode = 0;
775 	response[i].resp = NULL;
776 
777 	switch(msg[i]->msg_style)
778 	{
779 	case PAM_PROMPT_ECHO_ON:
780 	    /* Store the login as the response */
781 	    response[i].resp = appdata_ptr ?
782 		(char *)strdup(user->username) : NULL;
783 	    break;
784 
785 	case PAM_PROMPT_ECHO_OFF:
786 	    /* Store the password as the response */
787 	    response[i].resp = appdata_ptr ?
788 		(char *)strdup(user->password) : NULL;
789 	    break;
790 
791 	case PAM_TEXT_INFO:
792 	case PAM_ERROR_MSG:
793 	    break;
794 
795 	default:
796 	    if(response)
797 		free(response);
798 	    return PAM_CONV_ERR;
799 	}
800     }
801 
802     /* On success, return the response structure */
803     *resp= response;
804 
805     return PAM_SUCCESS;
806 }
807 
808 
809 
810 
811 /* @header jembossctl_check_pass **********************************************
812 **
813 ******************************************************************************/
jembossctl_check_pass(AjPStr username,AjPStr password,ajint * uid,ajint * gid,AjPStr * home)814 static AjBool jembossctl_check_pass(AjPStr username,AjPStr password,ajint *uid,
815 				    ajint *gid,AjPStr *home)
816 {
817     struct ad_user user_info;
818 
819     struct pam_cv
820     {
821 	int (*cv)(int,struct pam_message **,struct pam_response **,void *);
822 	void *userinfo;
823     };
824 
825     struct pam_cv conv;
826     pam_handle_t *pamh = NULL;
827     int retval;
828 
829     struct passwd *pwd = NULL;
830 
831     user_info.username = (char *) ajStrGetPtr(username);
832     user_info.password = (char *) ajStrGetPtr(password);
833 
834     conv.cv = jembossctl_pam_conv;
835     conv.userinfo = (void *)&user_info;
836 
837     pwd = getpwnam(ajStrGetPtr(username));
838     if(!pwd)		 /* No such username */
839 	return ajFalse;
840 
841     *uid = pwd->pw_uid;
842     *gid = pwd->pw_gid;
843 
844     ajStrAssignC(home,pwd->pw_dir);
845 
846 #ifndef DEBIAN
847     retval = pam_start("login",ajStrGetPtr(username),
848 		       (struct pam_conv*)&conv,&pamh);
849 #else /* !DEBIAN */
850     retval = pam_start("ssh",ajStrGetPtr(username),
851 		       (struct pam_conv*)&conv,&pamh);
852 #endif /* !DEBIAN */
853 
854     if (retval == PAM_SUCCESS)
855 	retval= pam_authenticate(pamh,PAM_SILENT);
856 
857     if(retval==PAM_SUCCESS)
858 	retval = pam_acct_mgmt(pamh,0);
859 
860     if(pam_end(pamh,retval)!=PAM_SUCCESS)
861     {
862 	pamh = NULL;
863 	return ajFalse;
864     }
865 
866     if(retval==PAM_SUCCESS)
867 	return ajTrue;
868 
869     return ajFalse;
870 }
871 #endif /* PAM */
872 
873 
874 
875 
876 /* @funcstatic jembossctl_up **************************************************
877 **
878 ** Primary username/password check. Return uid/gid/homedir
879 **
880 ** @param [w] buf [char*] socket buffer
881 ** @param [w] uid [int*] uid
882 ** @param [w] gid [int*] gid
883 ** @param [w] home [AjPStr*] home
884 **
885 ** @return [AjBool] true if success
886 ******************************************************************************/
887 
jembossctl_up(char * buf,int * uid,int * gid,AjPStr * home)888 static AjBool jembossctl_up(char *buf, int *uid, int *gid, AjPStr *home)
889 {
890     AjPStr username = NULL;
891     AjPStr password = NULL;
892     AjPStr cstr = NULL;
893     ajint command;
894     AjBool ok = ajFalse;
895     const char *p = NULL;
896 
897     username = ajStrNew();
898     password = ajStrNew();
899     cstr     = ajStrNew();
900 
901     ajStrAssignC(&cstr,buf);
902     if(ajFmtScanS(cstr,"%d%S%S",&command,&username,&password)!=3)
903     {
904 	if(ajStrGetLen(username))
905 	   bzero((void*)username->Ptr,ajStrGetLen(username));
906 	if(ajStrGetLen(password))
907 	   bzero((void*)password->Ptr,ajStrGetLen(password));
908 	jembossctl_zero((char*)buf);
909 
910 	ajStrDel(&username);
911 	ajStrDel(&password);
912 	ajStrDel(&cstr);
913 	return ajFalse;
914     }
915 
916 
917     p = ajStrGetPtr(cstr);
918     while(*p!=' ')
919 	++p;
920     ++p;
921     while(*p!=' ')
922 	++p;
923     ++p;
924     ajStrAssignC(&password,p);
925 
926 
927 #ifndef NO_AUTH
928     ok = jembossctl_check_pass(username,password,uid,gid,home);
929 #else /* NO_AUTH */
930     (void) home;
931 #endif /* NO_AUTH */
932 
933 
934     bzero((void*)username->Ptr,ajStrGetLen(username));
935     bzero((void*)password->Ptr,ajStrGetLen(password));
936     jembossctl_zero((char*)buf);
937 
938     ajStrDel(&username);
939     ajStrDel(&password);
940     ajStrDel(&cstr);
941 
942 
943     if((*uid)<UIDLIMIT || (*gid)<GIDLIMIT)
944 	return ajFalse;
945     if(!(*uid) || !(*gid))
946 	return ajFalse;
947 
948 
949     if(ok)
950 	return ajTrue;
951 
952     return ajFalse;
953 }
954 
955 
956 
957 
958 /* @funcstatic jembossctl_do_batch ********************************************
959 **
960 ** Fork emboss program
961 **
962 ** @param [w] buf [char*] socket buffer
963 ** @param [r] uid [int] uid
964 ** @param [r] gid [int] gid
965 **
966 ** @return [AjBool] true if success
967 ******************************************************************************/
968 
jembossctl_do_batch(char * buf,int uid,int gid)969 static AjBool jembossctl_do_batch(char *buf, int uid, int gid)
970 {
971     AjPStr cl     = NULL;
972     AjPStr prog   = NULL;
973     AjPStr enviro = NULL;
974     AjPStr dir    = NULL;
975 
976     const char *p = NULL;
977     const char *q = NULL;
978     char c  = '\0';
979 
980     /* Fork stuff */
981     char **argp = NULL;
982     char **envp = NULL;
983     int  pid;
984     int  status = 0;
985     int  i=0;
986 
987     int  outpipe[2];
988     int  errpipe[2];
989 
990 #ifdef HAVE_POLL
991     struct pollfd ufds[2];
992     unsigned int  nfds;
993 #else /* !HAVE_POLL */
994     fd_set rec;
995     struct timeval t;
996 #endif /* !HAVE_POLL */
997 
998     int nread = 0;
999 
1000     AjPStr outstd = NULL;
1001     AjPStr errstd = NULL;
1002     int retval    = 0;
1003     unsigned long block = 0;
1004 
1005     FILE *fp;
1006 #if defined (__SVR4) && defined (__sun) && !defined (__GNUC__)
1007     struct tm tbuf;
1008 #endif /* !(__SVR4 && __sun && !__GNUC__) */
1009     struct tm *tp = NULL;
1010     time_t tim;
1011     char timstr[TIMEBUFFER];
1012 
1013     tim = time(0);
1014 
1015     outstd = ajStrNew();
1016     errstd = ajStrNew();
1017 
1018     cl     = ajStrNew();
1019     prog   = ajStrNew();
1020     enviro = ajStrNew();
1021     dir    = ajStrNew();
1022 
1023 
1024     if(!jembossctl_initgroups(buf,gid))
1025     {
1026 	jembossctl_fork_tidy(&cl,&prog,&enviro,&dir,&outstd,&errstd);
1027 	return ajFalse;
1028     }
1029 
1030 
1031     /* Skip over authentication stuff */
1032     p = buf;
1033     while(*p)
1034 	++p;
1035     ++p;
1036 
1037     /* retrieve command line, environment and directory */
1038     ajStrAssignC(&cl,p);
1039     while(*p)
1040 	++p;
1041     ++p;
1042 
1043     ajStrAssignC(&enviro,p);
1044     while(*p)
1045 	++p;
1046     ++p;
1047 
1048     ajStrAssignC(&dir,p);
1049 
1050     jembossctl_zero((char*)buf);
1051 
1052 
1053     p = q = ajStrGetPtr(cl);
1054     while((c=(*p))!=' ' && c && c!='\t' && c!='\n')
1055 	++p;
1056     ajStrAssignSubC(&prog,q,0,p-q-1);
1057 
1058     argp = jembossctl_make_array(cl);
1059     envp = jembossctl_make_array(enviro);
1060 
1061     if(!ajSysFileWhichEnv(&prog,envp))
1062     {
1063 	jembossctl_fork_tidy(&cl,&prog,&enviro,&dir,&outstd,&errstd);
1064 	return ajFalse;
1065     }
1066 
1067 
1068     while(pipe(outpipe)==-1);
1069     while(pipe(errpipe)==-1);
1070 
1071 
1072 #if defined (__SVR4) && defined (__sun)
1073     pid = fork1();
1074 #else /* !(__SVR4 && __sun) */
1075     pid = fork();
1076 #endif /* !(__SVR4 && __sun) */
1077     if(pid == -1)
1078     {
1079 	close(errpipe[0]);
1080 	close(errpipe[1]);
1081 	close(outpipe[0]);
1082 	close(outpipe[1]);
1083 	jembossctl_fork_tidy(&cl,&prog,&enviro,&dir,&outstd,&errstd);
1084 	return ajFalse;
1085     }
1086 
1087 
1088     if(!pid)			/* Child */
1089     {
1090 	dup2(outpipe[1],1);
1091 	dup2(errpipe[1],2);
1092 
1093 	if(setgid(gid)==-1)
1094 	{
1095 	    fprintf(stderr,"setgid failure");
1096 	    fflush(stderr);
1097 	    exit(-1);
1098 	}
1099 
1100 	if(setuid(uid)==-1)
1101 	{
1102 	    fprintf(stderr,"setuid failure");
1103 	    fflush(stderr);
1104 	    exit(-1);
1105 	}
1106 
1107 	if(chdir(ajStrGetPtr(dir))==-1)
1108 	{
1109 	    fprintf(stderr,"chdir failure");
1110 	    fflush(stderr);
1111 	    exit(-1);
1112 	}
1113 
1114 	ajSysExecprogNowaitS(prog,argp,envp);
1115     }
1116 
1117 
1118     /* Tell JNI to continue */
1119     c = 1;
1120     jembossctl_snd((char *)&c,1);
1121 
1122     block = 1;
1123     if(jembossctl_java_block(outpipe[0],block)==-1)
1124     {
1125 	fprintf(stderr,"Cannot unblock 1. %d\n",errno);
1126 	jembossctl_fork_tidy(&cl,&prog,&enviro,&dir,&outstd,&errstd);
1127 	return ajFalse;
1128     }
1129 
1130     if(jembossctl_java_block(errpipe[0],block)==-1)
1131     {
1132 	fprintf(stderr,"Cannot unblock 2. %d\n",errno);
1133 	jembossctl_fork_tidy(&cl,&prog,&enviro,&dir,&outstd,&errstd);
1134 	return ajFalse;
1135     }
1136 
1137     *buf = '\0';
1138 
1139 #ifdef HAVE_POLL
1140     while((retval=waitpid(pid,&status,WNOHANG))!=pid)
1141     {
1142 	if(retval==-1)
1143 	    if(errno!=EINTR)
1144 		break;
1145 
1146 	ufds[0].fd = outpipe[0];
1147 	ufds[1].fd = errpipe[0];
1148 	ufds[0].events = POLLIN | POLLPRI;
1149 	ufds[1].events = POLLIN | POLLPRI;
1150 	nfds = 2;
1151 	if(!(retval=poll(ufds,nfds,1)) || retval==-1)
1152 	    continue;
1153 
1154 	if((ufds[0].revents & POLLIN) || (ufds[0].revents & POLLPRI))
1155 	{
1156 	    while((nread = read(outpipe[0],(void *)buf,JBUFFLEN))==-1
1157 		  && errno==EINTR);
1158 	    buf[nread]='\0';
1159 	    ajStrAppendC(&outstd,buf);
1160 	}
1161 
1162 
1163 	if((ufds[1].revents & POLLIN) || (ufds[1].revents & POLLPRI))
1164 	{
1165 	    while((nread = read(errpipe[0],(void *)buf,JBUFFLEN))==-1
1166 		  && errno==EINTR);
1167 	    buf[nread]='\0';
1168 	    ajStrAppendC(&errstd,buf);
1169 	}
1170     }
1171 
1172 
1173     ufds[0].fd = outpipe[0];
1174     ufds[1].fd = errpipe[0];
1175     ufds[0].events = POLLIN | POLLPRI;
1176     ufds[1].events = POLLIN | POLLPRI;
1177     nfds = 2;
1178 
1179     retval = poll(ufds,nfds,1);
1180 
1181     if(retval>0)
1182 	if((ufds[0].revents & POLLIN) || (ufds[0].revents & POLLPRI))
1183 	{
1184 	    while((nread = read(outpipe[0],(void *)buf,JBUFFLEN))==-1
1185 		  && errno==EINTR);
1186 	    buf[nread] = '\0';
1187 	    ajStrAppendC(&outstd,buf);
1188 	}
1189 
1190     retval = poll(ufds,nfds,1);
1191 
1192     if(retval>0)
1193 	if((ufds[1].revents & POLLIN) || (ufds[1].revents & POLLPRI))
1194 	{
1195 	    while((nread = read(errpipe[0],(void *)buf,JBUFFLEN))==-1
1196 		  && errno==EINTR);
1197 	    buf[nread]='\0';
1198 	    ajStrAppendC(&errstd,buf);
1199 	}
1200 #else /* !HAVE_POLL */
1201     while((retval=waitpid(pid,&status,WNOHANG))!=pid)
1202     {
1203 	if(retval==-1)
1204 	    if(errno!=EINTR)
1205 		break;
1206 
1207 	FD_ZERO(&rec);
1208 	FD_SET(outpipe[0],&rec);
1209 	t.tv_sec = 0;
1210 	t.tv_usec = 1000;
1211 	select(outpipe[0]+1,&rec,NULL,NULL,&t);
1212 	if(FD_ISSET(outpipe[0],&rec))
1213 	{
1214 	    while((nread = read(outpipe[0],(void *)buf,JBUFFLEN))==-1
1215 		  && errno==EINTR);
1216 	    buf[nread]='\0';
1217 	    ajStrAppendC(&outstd,buf);
1218 	}
1219 
1220 	FD_ZERO(&rec);
1221 	FD_SET(errpipe[0],&rec);
1222 	t.tv_sec = 0;
1223 	t.tv_usec = 1000;
1224 	select(errpipe[0]+1,&rec,NULL,NULL,&t);
1225 	if(FD_ISSET(errpipe[0],&rec))
1226 	{
1227 	    while((nread = read(errpipe[0],(void *)buf,JBUFFLEN))==-1
1228 		  && errno==EINTR);
1229 	    buf[nread] = '\0';
1230 	    ajStrAppendC(&errstd,buf);
1231 	}
1232 
1233 
1234     }
1235 
1236 
1237     FD_ZERO(&rec);
1238     FD_SET(outpipe[0],&rec);
1239     t.tv_sec = 0;
1240     t.tv_usec = 0;
1241     select(outpipe[0]+1,&rec,NULL,NULL,&t);
1242     if(FD_ISSET(outpipe[0],&rec))
1243     {
1244 	while((nread = read(outpipe[0],(void *)buf,JBUFFLEN))==-1
1245 	      && errno==EINTR);
1246 	buf[nread] = '\0';
1247 	ajStrAppendC(&outstd,buf);
1248     }
1249 
1250 
1251     FD_ZERO(&rec);
1252     FD_SET(errpipe[0],&rec);
1253     t.tv_sec = 0;
1254     t.tv_usec = 0;
1255     select(errpipe[0]+1,&rec,NULL,NULL,&t);
1256     if(FD_ISSET(errpipe[0],&rec))
1257     {
1258 	while((nread = read(errpipe[0],(void *)buf,JBUFFLEN))==-1
1259 	      && errno==EINTR);
1260 	buf[nread] = '\0';
1261 	ajStrAppendC(&errstd,buf);
1262     }
1263 #endif /* HAVE_POLL */
1264 
1265 
1266     block = 0;
1267     if(jembossctl_java_block(outpipe[0],block)==-1)
1268     {
1269 	fprintf(stderr,"Cannot block 3. %d\n",errno);
1270 	jembossctl_fork_tidy(&cl,&prog,&enviro,&dir,&outstd,&errstd);
1271 	return ajFalse;
1272     }
1273     if(jembossctl_java_block(errpipe[0],block)==-1)
1274     {
1275 	fprintf(stderr,"Cannot block 4. %d\n",errno);
1276 	jembossctl_fork_tidy(&cl,&prog,&enviro,&dir,&outstd,&errstd);
1277 	return ajFalse;
1278     }
1279 
1280 /*
1281     fprintf(stdout,"%s",ajStrGetPtr(outstd));
1282     fprintf(stderr,"%s",ajStrGetPtr(errstd));
1283 */
1284 
1285     close(errpipe[0]);
1286     close(errpipe[1]);
1287     close(outpipe[0]);
1288     close(outpipe[1]);
1289 
1290     i = 0;
1291     while(argp[i])
1292 	AJFREE(argp[i]);
1293     AJFREE(argp);
1294 
1295     i = 0;
1296     while(envp[i])
1297 	AJFREE(envp[i]);
1298     AJFREE(envp);
1299 
1300 
1301     if(setgid(gid)==-1)
1302     {
1303 	fprintf(stderr,"Setgid error (do_batch)\n");
1304 	jembossctl_fork_tidy(&cl,&prog,&enviro,&dir,&outstd,&errstd);
1305 	return ajFalse;
1306     }
1307 
1308 
1309     if(setuid(uid)==-1)
1310     {
1311 	fprintf(stderr,"Setgid error (do_batch)\n");
1312 	jembossctl_fork_tidy(&cl,&prog,&enviro,&dir,&outstd,&errstd);
1313 	return ajFalse;
1314     }
1315 
1316 
1317     if(chdir(ajStrGetPtr(dir))==-1)
1318     {
1319 	fprintf(stderr,"chdir error (do_batch)\n");
1320 	jembossctl_fork_tidy(&cl,&prog,&enviro,&dir,&outstd,&errstd);
1321 	return ajFalse;
1322     }
1323 
1324 
1325 #if defined (__SVR4) && defined (__sun) && !defined (__GNUC__)
1326     tp = localtime_r(&tim,&tbuf);
1327 #else /* !(__SVR4 && __sun !__GNUC__) */
1328     tp = localtime(&tim);
1329 #endif /* !(__SVR4 && __sun !__GNUC__) */
1330     strftime(timstr,TIMEBUFFER,"%a %b %d %H:%M:%S %Z %Y",tp);
1331 
1332 
1333     if(!(fp=fopen(".finished","w")))
1334     {
1335 	fprintf(stderr,"fopen error (do_batch)\n");
1336 	jembossctl_fork_tidy(&cl,&prog,&enviro,&dir,&outstd,&errstd);
1337 	return ajFalse;
1338     }
1339 
1340     fprintf(fp,"%s\n",timstr);
1341     if(fclose(fp))
1342     {
1343 	fprintf(stderr,"fclose error (do_batch)\n");
1344 	jembossctl_fork_tidy(&cl,&prog,&enviro,&dir,&outstd,&errstd);
1345 	return ajFalse;
1346     }
1347 
1348     if(ajStrGetLen(errstd))
1349     {
1350         if(!(fp=fopen("stderrfile","w")))
1351         {
1352             fprintf(stderr,"errfile fopen error (do_batch)\n");
1353             jembossctl_fork_tidy(&cl,&prog,&enviro,&dir,&outstd,&errstd);
1354             return ajFalse;
1355         }
1356 
1357         fprintf(fp,"%s\n",ajStrGetPtr(errstd));
1358 
1359         if(fclose(fp))
1360         {
1361             fprintf(stderr,"errfile fclose error (do_batch)\n");
1362             jembossctl_fork_tidy(&cl,&prog,&enviro,&dir,&outstd,&errstd);
1363             return ajFalse;
1364         }
1365     }
1366 
1367     jembossctl_fork_tidy(&cl,&prog,&enviro,&dir,&outstd,&errstd);
1368 
1369     return ajTrue;
1370 }
1371 
1372 
1373 
1374 
1375 /* @funcstatic jembossctl_do_fork *********************************************
1376 **
1377 ** Fork emboss program
1378 **
1379 ** @param [w] buf [char*] socket buffer
1380 ** @param [r] uid [int] uid
1381 ** @param [r] gid [int] gid
1382 **
1383 ** @return [AjBool] true if success
1384 ******************************************************************************/
1385 
jembossctl_do_fork(char * buf,int uid,int gid)1386 static AjBool jembossctl_do_fork(char *buf, int uid, int gid)
1387 {
1388     AjPStr cl     = NULL;
1389     AjPStr prog   = NULL;
1390     AjPStr enviro = NULL;
1391     AjPStr dir    = NULL;
1392 
1393     const char *p = NULL;
1394     const char *q = NULL;
1395     char c  = '\0';
1396 
1397     /* Fork stuff */
1398     char **argp = NULL;
1399     char **envp = NULL;
1400     int  pid;
1401     int  status = 0;
1402     int  i = 0;
1403 
1404     int  outpipe[2];
1405     int  errpipe[2];
1406 
1407 #ifdef HAVE_POLL
1408     struct pollfd ufds[2];
1409     unsigned int  nfds;
1410 #else /* !HAVE_POLL */
1411     fd_set rec;
1412     struct timeval t;
1413 #endif /* !HAVE_POLL */
1414 
1415     int nread = 0;
1416 
1417     AjPStr outstd = NULL;
1418     AjPStr errstd = NULL;
1419     int retval = 0;
1420     unsigned long block = 0;
1421 
1422 
1423     outstd = ajStrNew();
1424     errstd = ajStrNew();
1425 
1426     cl     = ajStrNew();
1427     prog   = ajStrNew();
1428     enviro = ajStrNew();
1429     dir    = ajStrNew();
1430 
1431 
1432     if(!jembossctl_initgroups(buf,gid))
1433     {
1434 	jembossctl_fork_tidy(&cl,&prog,&enviro,&dir,&outstd,&errstd);
1435 	return ajFalse;
1436     }
1437 
1438 
1439     /* Skip over authentication stuff */
1440     p = buf;
1441     while(*p)
1442 	++p;
1443     ++p;
1444 
1445     /* retrieve command line, environment and directory */
1446     ajStrAssignC(&cl,p);
1447     while(*p)
1448 	++p;
1449     ++p;
1450 
1451     ajStrAssignC(&enviro,p);
1452     while(*p)
1453 	++p;
1454     ++p;
1455 
1456     ajStrAssignC(&dir,p);
1457 
1458     jembossctl_zero((char*)buf);
1459 
1460 
1461     p = q = ajStrGetPtr(cl);
1462     while((c=(*p))!=' ' && c && c!='\t' && c!='\n')
1463 	++p;
1464     ajStrAssignSubC(&prog,q,0,p-q-1);
1465 
1466     argp = jembossctl_make_array(cl);
1467     envp = jembossctl_make_array(enviro);
1468 
1469     if(!ajSysFileWhichEnv(&prog,envp))
1470     {
1471 	jembossctl_fork_tidy(&cl,&prog,&enviro,&dir,&outstd,&errstd);
1472 	return ajFalse;
1473     }
1474 
1475 
1476     while(pipe(outpipe)==-1);
1477     while(pipe(errpipe)==-1);
1478 
1479 
1480 #if defined (__SVR4) && defined (__sun)
1481     pid = fork1();
1482 #else /* !(__SVR4 && __sun) */
1483     pid = fork();
1484 #endif /* !(__SVR4 && __sun) */
1485     if(pid == -1)
1486     {
1487 	close(errpipe[0]);
1488 	close(errpipe[1]);
1489 	close(outpipe[0]);
1490 	close(outpipe[1]);
1491 	jembossctl_fork_tidy(&cl,&prog,&enviro,&dir,&outstd,&errstd);
1492 	return ajFalse;
1493     }
1494 
1495 
1496     if(!pid)			/* Child */
1497     {
1498 	dup2(outpipe[1],1);
1499 	dup2(errpipe[1],2);
1500 
1501 	if(setgid(gid)==-1)
1502 	{
1503 	    fprintf(stderr,"setgid failure");
1504 	    fflush(stderr);
1505 	    exit(-1);
1506 	}
1507 
1508 	if(setuid(uid)==-1)
1509 	{
1510 	    fprintf(stderr,"setuid failure");
1511 	    fflush(stderr);
1512 	    exit(-1);
1513 	}
1514 
1515 	if(chdir(ajStrGetPtr(dir))==-1)
1516 	{
1517 	    fprintf(stderr,"chdir failure");
1518 	    fflush(stderr);
1519 	    exit(-1);
1520 	}
1521 
1522 	ajSysExecprogNowaitS(prog,argp,envp);
1523     }
1524 
1525 
1526     block = 1;
1527     if(jembossctl_java_block(outpipe[0],block)==-1)
1528     {
1529 	fprintf(stderr,"Cannot unblock 5. %d\n",errno);
1530 	jembossctl_fork_tidy(&cl,&prog,&enviro,&dir,&outstd,&errstd);
1531 	return ajFalse;
1532     }
1533 
1534     if(jembossctl_java_block(errpipe[0],block)==-1)
1535     {
1536 	fprintf(stderr,"Cannot unblock 6. %d\n",errno);
1537 	jembossctl_fork_tidy(&cl,&prog,&enviro,&dir,&outstd,&errstd);
1538 	return ajFalse;
1539     }
1540 
1541 
1542     *buf = '\0';
1543 
1544 #ifdef HAVE_POLL
1545     while((retval=waitpid(pid,&status,WNOHANG))!=pid)
1546     {
1547 	if(retval==-1)
1548 	    if(errno!=EINTR)
1549 		break;
1550 
1551 	ufds[0].fd = outpipe[0];
1552 	ufds[1].fd = errpipe[0];
1553 	ufds[0].events = POLLIN | POLLPRI;
1554 	ufds[1].events = POLLIN | POLLPRI;
1555 	nfds = 2;
1556 	if(!(retval=poll(ufds,nfds,1)) || retval==-1)
1557 	    continue;
1558 
1559 	if((ufds[0].revents & POLLIN) || (ufds[0].revents & POLLPRI))
1560 	{
1561 	    while((nread = read(outpipe[0],(void *)buf,JBUFFLEN))==-1
1562 		  && errno==EINTR);
1563 	    buf[nread] = '\0';
1564 	    ajStrAppendC(&outstd,buf);
1565 	}
1566 
1567 
1568 	if((ufds[1].revents & POLLIN) || (ufds[1].revents & POLLPRI))
1569 	{
1570 	    while((nread = read(errpipe[0],(void *)buf,JBUFFLEN))==-1
1571 		  && errno==EINTR);
1572 	    buf[nread] = '\0';
1573 	    ajStrAppendC(&errstd,buf);
1574 	}
1575     }
1576 
1577 
1578     ufds[0].fd = outpipe[0];
1579     ufds[1].fd = errpipe[0];
1580     ufds[0].events = POLLIN | POLLPRI;
1581     ufds[1].events = POLLIN | POLLPRI;
1582     nfds = 2;
1583 
1584     retval = poll(ufds,nfds,1);
1585 
1586     if(retval>0)
1587 	if((ufds[0].revents & POLLIN) || (ufds[0].revents & POLLPRI))
1588 	{
1589 	    while((nread = read(outpipe[0],(void *)buf,JBUFFLEN))==-1
1590 		  && errno==EINTR);
1591 	    buf[nread] = '\0';
1592 	    ajStrAppendC(&outstd,buf);
1593 	}
1594 
1595     retval=poll(ufds,nfds,1);
1596 
1597     if(retval>0)
1598 	if((ufds[1].revents & POLLIN) || (ufds[1].revents & POLLPRI))
1599 	{
1600 	    while((nread = read(errpipe[0],(void *)buf,JBUFFLEN))==-1
1601 		  && errno==EINTR);
1602 	    buf[nread] = '\0';
1603 	    ajStrAppendC(&errstd,buf);
1604 	}
1605 #else /* !HAVE_POLL */
1606     while((retval=waitpid(pid,&status,WNOHANG))!=pid)
1607     {
1608 	if(retval==-1)
1609 	    if(errno!=EINTR)
1610 		break;
1611 
1612 	FD_ZERO(&rec);
1613 	FD_SET(outpipe[0],&rec);
1614 	t.tv_sec = 0;
1615 	t.tv_usec = 1000;
1616 	select(outpipe[0]+1,&rec,NULL,NULL,&t);
1617 	if(FD_ISSET(outpipe[0],&rec))
1618 	{
1619 	    while((nread = read(outpipe[0],(void *)buf,JBUFFLEN))==-1
1620 		  && errno==EINTR);
1621 	    buf[nread] = '\0';
1622 	    ajStrAppendC(&outstd,buf);
1623 	}
1624 
1625 	FD_ZERO(&rec);
1626 	FD_SET(errpipe[0],&rec);
1627 	t.tv_sec = 0;
1628 	t.tv_usec = 1000;
1629 	select(errpipe[0]+1,&rec,NULL,NULL,&t);
1630 	if(FD_ISSET(errpipe[0],&rec))
1631 	{
1632 	    while((nread = read(errpipe[0],(void *)buf,JBUFFLEN))==-1
1633 		  && errno==EINTR);
1634 	    buf[nread] = '\0';
1635 	    ajStrAppendC(&errstd,buf);
1636 	}
1637     }
1638 
1639 
1640     FD_ZERO(&rec);
1641     FD_SET(outpipe[0],&rec);
1642     t.tv_sec = 0;
1643     t.tv_usec = 0;
1644     select(outpipe[0]+1,&rec,NULL,NULL,&t);
1645     if(FD_ISSET(outpipe[0],&rec))
1646     {
1647 	while((nread = read(outpipe[0],(void *)buf,JBUFFLEN))==-1
1648 	      && errno==EINTR);
1649 	buf[nread] = '\0';
1650 	ajStrAppendC(&outstd,buf);
1651     }
1652 
1653 
1654     FD_ZERO(&rec);
1655     FD_SET(errpipe[0],&rec);
1656     t.tv_sec = 0;
1657     t.tv_usec = 0;
1658     select(errpipe[0]+1,&rec,NULL,NULL,&t);
1659     if(FD_ISSET(errpipe[0],&rec))
1660     {
1661 	while((nread = read(errpipe[0],(void *)buf,JBUFFLEN))==-1
1662 	      && errno==EINTR);
1663 	buf[nread] = '\0';
1664 	ajStrAppendC(&errstd,buf);
1665     }
1666 #endif /* !HAVE_POLL */
1667 
1668 
1669     block = 0;
1670     if(jembossctl_java_block(outpipe[0],block)==-1)
1671     {
1672 	fprintf(stderr,"Cannot block 7. %d\n",errno);
1673 	jembossctl_fork_tidy(&cl,&prog,&enviro,&dir,&outstd,&errstd);
1674 	return ajFalse;
1675     }
1676     if(jembossctl_java_block(errpipe[0],block)==-1)
1677     {
1678 	fprintf(stderr,"Cannot block 8. %d\n",errno);
1679 	jembossctl_fork_tidy(&cl,&prog,&enviro,&dir,&outstd,&errstd);
1680 	return ajFalse;
1681     }
1682 
1683 
1684 
1685     fprintf(stdout,"%s",ajStrGetPtr(outstd));
1686     fprintf(stderr,"%s",ajStrGetPtr(errstd));
1687 
1688 
1689     close(errpipe[0]);
1690     close(errpipe[1]);
1691     close(outpipe[0]);
1692     close(outpipe[1]);
1693 
1694     i = 0;
1695     while(argp[i])
1696 	AJFREE(argp[i]);
1697     AJFREE(argp);
1698 
1699     i = 0;
1700     while(envp[i])
1701 	AJFREE(envp[i]);
1702     AJFREE(envp);
1703 
1704     jembossctl_fork_tidy(&cl,&prog,&enviro,&dir,&outstd,&errstd);
1705 
1706     return ajTrue;
1707 }
1708 
1709 
1710 
1711 
1712 /* @funcstatic jembossctl_make_array ******************************************
1713 **
1714 ** Construct argv and env arrays for Ajax.fork
1715 ** N.B. This function converts tabs to spaces and removes
1716 ** excess space characters.
1717 **
1718 ** @param [r] str [const AjPStr] space or doublequote separated tokens
1719 **
1720 ** @return [char**] env or argv array
1721 ******************************************************************************/
1722 
jembossctl_make_array(const AjPStr str)1723 static char** jembossctl_make_array(const AjPStr str)
1724 {
1725     ajint n = 0;
1726     ajint len = 0;
1727 
1728     char **ptr    = NULL;
1729     const char *p = NULL;
1730     const char *q = NULL;
1731     char c;
1732     AjPStr stmp = NULL;
1733     AjPStr buf  = NULL;
1734 
1735 
1736     n = 0;
1737 
1738     stmp = ajStrNewS(str);
1739 
1740     ajStrRemoveWhiteExcess(&stmp);
1741 
1742     p = ajStrGetPtr(stmp);
1743     q = p;
1744 
1745     /*
1746     ** Count the number of tokens
1747     */
1748 
1749     while((c = *p))
1750     {
1751         if(c == '"')
1752         {
1753             ++p;
1754 
1755             while(*p != '"' && *p)
1756                 ++p;
1757 
1758             if(*p)
1759                 ++p;
1760 
1761             if(*p == ' ')
1762             {
1763                 ++n;
1764                 ++p;
1765             }
1766 
1767             continue;
1768         }
1769 
1770         if(c == ' ')
1771             ++n;
1772 
1773         ++p;
1774     }
1775 
1776     if(p != q)
1777         ++n;
1778 
1779 
1780     AJCNEW0(ptr,n+1);
1781 
1782     ptr[n] = NULL;
1783 
1784     /* If there are no tokens return an empty NULL terminated list */
1785     if(!n)
1786     {
1787         ajStrDel(&stmp);
1788         return ptr;
1789     }
1790 
1791 
1792     /*
1793     ** Tokenise and create ptr array strings
1794     */
1795 
1796     buf = ajStrNew();
1797 
1798     p = q;
1799     n = 0;
1800 
1801     while((c = *p))
1802     {
1803 
1804         if(c == '"')
1805         {
1806             ++p;
1807             while(*p != '"' && *p)
1808                 ++p;
1809 
1810             len = p-q;
1811 
1812 
1813             if(*p)
1814                 ++p;
1815 
1816             if(len > 1)
1817                 ajStrAssignSubC(&buf,q,1,len-1);
1818             else
1819                 ajStrAssignC(&buf,"");
1820 
1821             ptr[n++] = ajCharNewS(buf);
1822 
1823             if(*p == ' ')
1824                 ++p;
1825 
1826             q = p;
1827             continue;
1828         }
1829 
1830         while(*p != ' ' && *p)
1831             ++p;
1832 
1833         len = p-q;
1834 
1835         ajStrAssignSubC(&buf,q,0,len-1);
1836         ptr[n++] = ajCharNewS(buf);
1837 
1838         if(*p == ' ')
1839             ++p;
1840 
1841         q = p;
1842     }
1843 
1844 
1845     ajStrDel(&buf);
1846     ajStrDel(&stmp);
1847 
1848     return ptr;
1849 }
1850 
1851 
1852 
1853 
1854 /* @funcstatic jembossctl_do_directory ****************************************
1855 **
1856 ** Make user directory
1857 **
1858 ** @param [w] buf [char*] socket buffer
1859 ** @param [r] uid [int] uid
1860 ** @param [r] gid [int] gid
1861 **
1862 ** @return [AjBool] true if success
1863 ******************************************************************************/
1864 
jembossctl_do_directory(char * buf,int uid,int gid)1865 static AjBool jembossctl_do_directory(char *buf, int uid, int gid)
1866 {
1867     AjPStr dir = NULL;
1868     AjPStr str = NULL;
1869     char *p    = NULL;
1870     char *dbuf = NULL;
1871     int len = 0;
1872 
1873 
1874     dir = ajStrNew();
1875 
1876     if(!jembossctl_initgroups(buf,gid))
1877     {
1878 	fprintf(stderr,"Initgroups failure (do_directory)\n");
1879 	ajStrDel(&dir);
1880 	return ajFalse;
1881     }
1882 
1883     /* Skip over authentication stuff */
1884     p = buf;
1885     while(*p)
1886 	++p;
1887     ++p;
1888 
1889     /* retrieve directory */
1890     ajStrAssignC(&dir,p);
1891 
1892 
1893     jembossctl_zero((char*)buf);
1894 
1895     if(setgid(gid)==-1)
1896     {
1897 	ajStrDel(&dir);
1898 	fprintf(stderr,"setgid error (mkdir)\n");
1899 	return ajFalse;
1900     }
1901 
1902     if(setuid(uid)==-1)
1903     {
1904 	ajStrDel(&dir);
1905 	fprintf(stderr,"setuid error (mkdir)\n");
1906 	return ajFalse;
1907     }
1908 
1909     if(!jembossctl_chdir(ajStrGetPtr(dir)))
1910     {
1911 	ajStrDel(&dir);
1912 	fprintf(stderr,"chdir error (mkdir)\n");
1913 	return ajFalse;
1914     }
1915 
1916 
1917     if(!(dbuf=(char *)malloc((len=ajStrGetLen(dir))+1)))
1918 	return ajFalse;
1919     strcpy(dbuf,ajStrGetPtr(dir));
1920 
1921     if(dbuf[len-1]=='/')
1922 	dbuf[len-1]='\0';
1923 
1924     str = ajStrNew();
1925     ajStrAssignC(&str,dbuf);
1926 
1927     if(mkdir(ajStrGetPtr(str),0751)==-1)
1928     {
1929 	AJFREE(dbuf);
1930 	ajStrDel(&str);
1931 	ajStrDel(&dir);
1932 	fprintf(stderr,"mkdir error (mkdir)\n");
1933 	return ajFalse;
1934     }
1935 
1936 
1937     AJFREE(dbuf);
1938     ajStrDel(&str);
1939     ajStrDel(&dir);
1940 
1941     return ajTrue;
1942 }
1943 
1944 
1945 
1946 
1947 /* @funcstatic jembossctl_do_deletefile ***************************************
1948 **
1949 ** Delete a user file
1950 **
1951 ** @param [w] buf [char*] socket buffer
1952 ** @param [r] uid [int] uid
1953 ** @param [r] gid [int] gid
1954 **
1955 ** @return [AjBool] true if success
1956 ******************************************************************************/
1957 
jembossctl_do_deletefile(char * buf,int uid,int gid)1958 static AjBool jembossctl_do_deletefile(char *buf, int uid, int gid)
1959 {
1960     AjPStr ufile = NULL;
1961     char *p = NULL;
1962 
1963 
1964     ufile = ajStrNew();
1965 
1966     if(!jembossctl_initgroups(buf,gid))
1967     {
1968 	fprintf(stderr,"Initgroups failure (do_deletefile)\n");
1969 	ajStrDel(&ufile);
1970 	return ajFalse;
1971     }
1972 
1973     /* Skip over authentication stuff */
1974     p = buf;
1975     while(*p)
1976 	++p;
1977     ++p;
1978 
1979     /* retrieve user file */
1980     ajStrAssignC(&ufile,p);
1981 
1982     jembossctl_zero((char*)buf);
1983 
1984     if(setgid(gid)==-1)
1985     {
1986 	fprintf(stderr,"setgid error (delete file)\n");
1987 	ajStrDel(&ufile);
1988 	return ajFalse;
1989     }
1990 
1991     if(setuid(uid)==-1)
1992     {
1993 	fprintf(stderr,"setuid error (delete file)\n");
1994 	ajStrDel(&ufile);
1995 	return ajFalse;
1996     }
1997 
1998     if(!jembossctl_chdir(ajStrGetPtr(ufile)))
1999     {
2000 	fprintf(stderr,"setuid error (delete file)\n");
2001 	ajStrDel(&ufile);
2002 	return ajFalse;
2003     }
2004 
2005     if(unlink(ajStrGetPtr(ufile))==-1)
2006     {
2007 	fprintf(stderr,"unlink error (delete file)\n");
2008 	ajStrDel(&ufile);
2009 	return ajFalse;
2010     }
2011 
2012     ajStrDel(&ufile);
2013 
2014     return ajTrue;
2015 }
2016 
2017 
2018 
2019 
2020 /* @funcstatic jembossctl_do_seq **********************************************
2021 **
2022 ** Get sequence attributes (top level)
2023 **
2024 ** @param [w] buf [char*] socket buffer
2025 ** @param [r] uid [int] uid
2026 ** @param [r] gid [int] gid
2027 **
2028 ** @return [AjBool] true if success
2029 ******************************************************************************/
2030 
jembossctl_do_seq(char * buf,int uid,int gid)2031 static AjBool jembossctl_do_seq(char *buf, int uid, int gid)
2032 {
2033     AjPStr usa = NULL;
2034     char *p    = NULL;
2035     AjPSeq seq = NULL;
2036     AjBool ok;
2037 
2038     usa  = ajStrNew();
2039 
2040     if(!jembossctl_initgroups(buf,gid))
2041     {
2042 	fprintf(stderr,"Initgroups failure (do_seq)\n");
2043 	ajStrDel(&usa);
2044 	return ajFalse;
2045     }
2046 
2047     /* Skip over authentication stuff */
2048     p = buf;
2049     while(*p)
2050 	++p;
2051     ++p;
2052 
2053     /* retrieve user file */
2054     ajStrAssignC(&usa,p);
2055 
2056     jembossctl_zero((char*)buf);
2057 
2058     if(setgid(gid)==-1)
2059     {
2060 	fprintf(stderr,"setgid error (seq attr)\n");
2061 	ajStrDel(&usa);
2062 	return ajFalse;
2063     }
2064 
2065     if(setuid(uid)==-1)
2066     {
2067 	fprintf(stderr,"setuid error (seq attr)\n");
2068 	ajStrDel(&usa);
2069 	return ajFalse;
2070     }
2071 
2072 /*
2073 **  Might need a kludge for solaris so leave this code here
2074 **  if(!jembossctl_chdir(ajStrGetPtr(usa)))
2075 **  {
2076 **	fprintf(stderr,"setuid error (seq attr)\n");
2077 **	ajStrDel(&usa);
2078 **	return ajFalse;
2079 **  }
2080 */
2081 
2082     seq = ajSeqNew();
2083 
2084     ok = jembossctl_GetSeqFromUsa(usa,&seq);
2085     if(ok)
2086 	fprintf(stdout,"%d %f %d",(int)ajSeqGetLen(seq),seq->Weight,
2087 		(int)ajSeqIsNuc(seq));
2088     else
2089 	fprintf(stdout,"0 0.0 0");
2090     fflush(stdout);
2091 
2092 
2093     ajStrDel(&usa);
2094     ajSeqDel(&seq);
2095 
2096     if(!ok)
2097 	return ajFalse;
2098 
2099     return ajTrue;
2100 }
2101 
2102 
2103 
2104 
2105 /* @funcstatic jembossctl_do_seqset *******************************************
2106 **
2107 ** Get seqset attributes (top level)
2108 **
2109 ** @param [w] buf [char*] socket buffer
2110 ** @param [r] uid [int] uid
2111 ** @param [r] gid [int] gid
2112 **
2113 ** @return [AjBool] true if success
2114 ******************************************************************************/
2115 
jembossctl_do_seqset(char * buf,int uid,int gid)2116 static AjBool jembossctl_do_seqset(char *buf, int uid, int gid)
2117 {
2118     AjPStr usa = NULL;
2119     char *p    = NULL;
2120     AjBool ok;
2121     AjPSeqset seq = NULL;
2122 
2123 
2124     usa = ajStrNew();
2125     seq = ajSeqsetNew();
2126 
2127     if(!jembossctl_initgroups(buf,gid))
2128     {
2129 	fprintf(stderr,"Initgroups failure (do_seqset)\n");
2130 	ajStrDel(&usa);
2131 	return ajFalse;
2132     }
2133 
2134     /* Skip over authentication stuff */
2135     p = buf;
2136     while(*p)
2137 	++p;
2138     ++p;
2139 
2140     /* retrieve user file */
2141     ajStrAssignC(&usa,p);
2142 
2143     jembossctl_zero((char*)buf);
2144 
2145     if(setgid(gid)==-1)
2146     {
2147 	fprintf(stderr,"setgid error (seqset attrib)\n");
2148 	ajStrDel(&usa);
2149 	return ajFalse;
2150     }
2151 
2152     if(setuid(uid)==-1)
2153     {
2154 	fprintf(stderr,"setuid error (seqset attrib)\n");
2155 	ajStrDel(&usa);
2156 	return ajFalse;
2157     }
2158 
2159     /*
2160     **  Leave this code here for now in case of Solaris weirdness
2161     ** if(!jembossctl_chdir(ajStrGetPtr(usa)))
2162     ** {
2163     **	   fprintf(stderr,"setuid error (seqset attrib)\n");
2164     **	   ajStrDel(&ufile);
2165     **	   return ajFalse;
2166     ** }
2167     */
2168 
2169 
2170     ok = jembossctl_GetSeqsetFromUsa(usa,&seq);
2171     if(ok)
2172 	fprintf(stdout,"%d %f %d",(int)ajSeqsetGetLen(seq),
2173 		ajSeqsetGetTotweight(seq),(int)ajSeqsetIsNuc(seq));
2174     else
2175 	fprintf(stdout,"0 0.0 0");
2176     fflush(stdout);
2177 
2178 
2179     ajStrDel(&usa);
2180     ajSeqsetDel(&seq);
2181 
2182     if(!ok)
2183 	return ajFalse;
2184 
2185     return ajTrue;
2186 }
2187 
2188 
2189 
2190 
2191 /* @funcstatic jembossctl_do_renamefile ***************************************
2192 **
2193 ** Rename a user file
2194 **
2195 ** @param [w] buf [char*] socket buffer
2196 ** @param [r] uid [int] uid
2197 ** @param [r] gid [int] gid
2198 **
2199 ** @return [AjBool] true if success
2200 ******************************************************************************/
2201 
jembossctl_do_renamefile(char * buf,int uid,int gid)2202 static AjBool jembossctl_do_renamefile(char *buf, int uid, int gid)
2203 {
2204     AjPStr ufile    = NULL;
2205     AjPStr u2file   = NULL;
2206     char *p = NULL;
2207 
2208 
2209     ufile  = ajStrNew();
2210     u2file = ajStrNew();
2211 
2212     if(!jembossctl_initgroups(buf,gid))
2213     {
2214 	fprintf(stderr,"Initgroups failure (do_renamefile)\n");
2215 	ajStrDel(&ufile);
2216 	return ajFalse;
2217     }
2218 
2219     /* Skip over authentication stuff */
2220     p = buf;
2221     while(*p)
2222 	++p;
2223     ++p;
2224 
2225     /* retrieve user file */
2226     ajStrAssignC(&ufile,p);
2227 
2228     while(*p)
2229 	++p;
2230     ++p;
2231     /* retrieve new name */
2232     ajStrAssignC(&u2file,p);
2233 
2234     jembossctl_zero((char*)buf);
2235 
2236     if(setgid(gid)==-1)
2237     {
2238 	fprintf(stderr,"setgid error (rename file)\n");
2239 	ajStrDel(&ufile);
2240 	ajStrDel(&u2file);
2241 	return ajFalse;
2242     }
2243 
2244     if(setuid(uid)==-1)
2245     {
2246 	fprintf(stderr,"setuid error (rename file)\n");
2247 	ajStrDel(&ufile);
2248 	ajStrDel(&u2file);
2249 	return ajFalse;
2250     }
2251 
2252     if(!jembossctl_chdir(ajStrGetPtr(ufile)))
2253     {
2254 	fprintf(stderr,"setuid error (rename file)\n");
2255 	ajStrDel(&ufile);
2256 	ajStrDel(&u2file);
2257 	return ajFalse;
2258     }
2259 
2260     if(rename(ajStrGetPtr(ufile),ajStrGetPtr(u2file))==-1)
2261     {
2262 	fprintf(stderr,"unlink error (rename file)\n");
2263 	ajStrDel(&ufile);
2264 	ajStrDel(&u2file);
2265 	return ajFalse;
2266     }
2267 
2268     ajStrDel(&ufile);
2269     ajStrDel(&u2file);
2270 
2271     return ajTrue;
2272 }
2273 
2274 
2275 
2276 
2277 /* @funcstatic jembossctl_do_deletedir ****************************************
2278 **
2279 ** Recursively delete a user directory
2280 **
2281 ** @param [w] buf [char*] socket buffer
2282 ** @param [r] uid [int] uid
2283 ** @param [r] gid [int] gid
2284 **
2285 ** @return [AjBool] true if success
2286 ******************************************************************************/
2287 
jembossctl_do_deletedir(char * buf,int uid,int gid)2288 static AjBool jembossctl_do_deletedir(char *buf, int uid, int gid)
2289 {
2290     AjPStr dir  = NULL;
2291     AjPStr cmnd = NULL;
2292     char *p     = NULL;
2293 
2294 
2295     dir = ajStrNew();
2296 
2297     if(!jembossctl_initgroups(buf,gid))
2298     {
2299 	fprintf(stderr,"Initgroups failure (do_deletedir)\n");
2300 	ajStrDel(&dir);
2301 	return ajFalse;
2302     }
2303 
2304     /* Skip over authentication stuff */
2305     p = buf;
2306     while(*p)
2307 	++p;
2308     ++p;
2309 
2310     /* retrieve user directory */
2311     ajStrAssignC(&dir,p);
2312 
2313     jembossctl_zero((char*)buf);
2314 
2315     if(setgid(gid)==-1)
2316     {
2317 	fprintf(stderr,"setgid error (delete directory)\n");
2318 	ajStrDel(&dir);
2319 	return ajFalse;
2320     }
2321 
2322     if(setuid(uid)==-1)
2323     {
2324 	fprintf(stderr,"setuid error (delete directory)\n");
2325 	ajStrDel(&dir);
2326 	return ajFalse;
2327     }
2328 
2329     if(chdir(ajStrGetPtr(dir))==-1)
2330     {
2331 	fprintf(stderr,"chdir error (delete directory)\n");
2332 	ajStrDel(&dir);
2333 	return ajFalse;
2334     }
2335 
2336     if(!jembossctl_chdir(ajStrGetPtr(dir)))
2337     {
2338 	fprintf(stderr,"jembossctl_chdir error (delete directory)\n");
2339 	ajStrDel(&dir);
2340 	return ajFalse;
2341     }
2342 
2343     ajSysCommandRemovedirS(dir);
2344     if(ajFilenameExists(dir))
2345     {
2346 	fprintf(stderr,"system error (delete directory)\n");
2347 	ajStrDel(&cmnd);
2348 	ajStrDel(&dir);
2349 	return ajFalse;
2350     }
2351 
2352 
2353     ajStrDel(&cmnd);
2354     ajStrDel(&dir);
2355 
2356     return ajTrue;
2357 }
2358 
2359 
2360 
2361 
2362 /* @funcstatic jembossctl_do_listfiles ****************************************
2363 **
2364 ** Return regular files in a directory
2365 **
2366 ** @param [w] buf [char*] socket buffer
2367 ** @param [r] uid [int] uid
2368 ** @param [r] gid [int] gid
2369 ** @param [w] retlist [AjPStr*] file list
2370 **
2371 ** @return [AjBool] true if success
2372 ******************************************************************************/
2373 
jembossctl_do_listfiles(char * buf,int uid,int gid,AjPStr * retlist)2374 static AjBool jembossctl_do_listfiles(char *buf, int uid, int gid,
2375 				      AjPStr *retlist)
2376 {
2377     AjPStr dir  = NULL;
2378     AjPStr full = NULL;
2379 
2380     char *p = NULL;
2381     DIR  *dirp;
2382 #if defined (HAVE64) && !defined(AJ_MACOSXLF) && !defined(AJ_HPUXLF) && !defined(AJ_FreeBSDLF) && !defined(AJ_AIXLF)
2383     struct dirent64 *dp;
2384 #else /* !(HAVE64 && !AJ_MACOSXLF && !AJ_HPUXLF && !AJ_FreeBSDLF && !AJ_AIXLF) */
2385     struct dirent *dp;
2386 #endif /* !(HAVE64 && !AJ_MACOSXLF && !AJ_HPUXLF && !AJ_FreeBSDLF && !AJ_AIXLF) */
2387 
2388 #if defined (HAVE64) && !defined(AJ_MACOSXLF) && !defined(AJ_HPUXLF) && !defined(AJ_FreeBSDLF) && !defined(AJ_AIXLF)
2389     struct stat64 sbuf;
2390 #else  /* !(HAVE64 && !AJ_MACOSXLF && !AJ_HPUXLF && !AJ_FreeBSDLF && !AJ_AIXLF) */
2391     struct stat sbuf;
2392 #endif  /* !(HAVE64 && !AJ_MACOSXLF && !AJ_HPUXLF && !AJ_FreeBSDLF && !AJ_AIXLF) */
2393 
2394     AjPList list = NULL;
2395     AjPStr  tstr = NULL;
2396 #if defined (__SVR4) && defined (__sun) && defined (_POSIX_C_SOURCE)
2397     int ret = 0;
2398 #endif /* __SVR4 && __sun && _POSIX_C_SOURCE */
2399 #if defined (__SVR4) && defined (__sun)
2400     char *dbuf = NULL;
2401 
2402     if(!(dbuf = malloc(sizeof(struct dirent)+PATH_MAX)))
2403     {
2404 	fprintf(stderr,"Readdir buffer failure (do_listfiles)\n");
2405 	return ajFalse;
2406     }
2407 #endif /* __SVR4 && __sun */
2408 
2409     dir  = ajStrNew();
2410     full = ajStrNew();
2411 
2412     if(!jembossctl_initgroups(buf,gid))
2413     {
2414 	fprintf(stderr,"Initgroups failure (do_listfiles)\n");
2415 	ajStrDel(&dir);
2416 	ajStrDel(&full);
2417 	return ajFalse;
2418     }
2419 
2420     /* Skip over authentication stuff */
2421     p = buf;
2422     while(*p)
2423 	++p;
2424     ++p;
2425 
2426     /* retrieve user file */
2427     ajStrAssignC(&dir,p);
2428 
2429     jembossctl_zero((char*)buf);
2430 
2431     if(setgid(gid)==-1)
2432     {
2433 	fprintf(stderr,"setgid error (list files)\n");
2434 	ajStrDel(&dir);
2435 	ajStrDel(&full);
2436 	return ajFalse;
2437     }
2438 
2439     if(setuid(uid)==-1)
2440     {
2441 	fprintf(stderr,"setuid error (list files)\n");
2442 	ajStrDel(&dir);
2443 	ajStrDel(&full);
2444 	return ajFalse;
2445     }
2446 
2447     if(chdir(ajStrGetPtr(dir))==-1)
2448     {
2449 	fprintf(stderr,"chdir error (list files)\n");
2450 	ajStrDel(&dir);
2451 	ajStrDel(&full);
2452 	return ajFalse;
2453     }
2454 
2455 
2456     if(!(dirp=opendir(ajStrGetPtr(dir))))
2457     {
2458 	fprintf(stderr,"opendir error (list files)\n");
2459 	ajStrDel(&dir);
2460 	ajStrDel(&full);
2461 	return ajFalse;
2462     }
2463 
2464     ajDirnameFix(&dir);
2465 
2466     list = ajListNew();
2467 
2468 #if defined (__SVR4) && defined (__sun) && \
2469     defined (_POSIX_C_SOURCE) && defined (HAVE64)
2470     for(ret=readdir64_r(dirp,(struct dirent64 *)dbuf,&dp);dp;
2471 	ret=readdir64_r(dirp,(struct dirent64 *)dbuf,&dp))
2472 #else /* !(__SVR4 && __sun && _POSIX_C_SOURCE && HAVE64) */
2473 #if defined (__SVR4) && defined (__sun) && defined (_POSIX_C_SOURCE)
2474     for(ret=readdir_r(dirp,(struct dirent *)dbuf,&dp);dp;
2475 	ret=readdir_r(dirp,(struct dirent *)dbuf,&dp))
2476 #else /* !(__SVR4 && __sun && _POSIX_C_SOURCE) */
2477 #if defined (__SVR4) && defined (__sun) && !defined (__GNUC__)
2478     for(dp=readdir_r(dirp,(struct dirent *)dbuf);dp;
2479 	dp=readdir_r(dirp,(struct dirent *)dbuf))
2480 #else /* !(__SVR4 && __sun && !__GNUC__) */
2481 #if defined (HAVE64) && !defined(AJ_MACOSXLF) && !defined(AJ_HPUXLF) && \
2482     !defined(AJ_FreeBSDLF) && !defined(AJ_AIXLF)
2483     for(dp=readdir64(dirp);dp;dp=readdir64(dirp))
2484 #else /* !(HAVE64 && !AJ_MACOSXLF && !AJ_HPUXLF && !AJ_FreeBSDLF && !AJ_AIXLF) */
2485     for(dp=readdir(dirp);dp;dp=readdir(dirp))
2486 #endif /* !(HAVE64 && !AJ_MACOSXLF && !AJ_HPUXLF && !AJ_FreeBSDLF && !AJ_AIXLF) */
2487 #endif /* !(__SVR4 && __sun && !__GNUC__) */
2488 #endif /* !(__SVR4 && __sun && _POSIX_C_SOURCE) */
2489 #endif /* !(__SVR4 && __sun && _POSIX_C_SOURCE && HAVE64) */
2490     {
2491 #if defined (__SVR4) && defined (__sun) && \
2492     defined (_POSIX_C_SOURCE) && defined (HAVE64)
2493 	if(ret)
2494 	    break;
2495 #endif /* __SVR4 && __sun && _POSIX_C_SOURCE && HAVE64 */
2496 
2497 	if(*(dp->d_name)=='.')
2498 	    continue;
2499 	ajFmtPrintS(&full,"%S%s",dir,dp->d_name);
2500 
2501 
2502 #if defined (HAVE64) && !defined(AJ_MACOSXLF) && !defined(AJ_HPUXLF) && \
2503     !defined(AJ_FreeBSDLF) && !defined(AJ_AIXLF)
2504 	if(stat64(ajStrGetPtr(full),&sbuf)==-1)
2505 	    continue;
2506 #else /* !(HAVE64 && !AJ_MACOSXLF && !AJ_HPUXLF && !AJ_FreeBSDLF && !AJ_AIXLF) */
2507 	if(stat(ajStrGetPtr(full),&sbuf)==-1)
2508 	    continue;
2509 #endif /* !(HAVE64 && !AJ_MACOSXLF && !AJ_HPUXLF && !AJ_FreeBSDLF && !AJ_AIXLF) */
2510 
2511 	if(sbuf.st_mode & S_IFREG)
2512 	{
2513 	    tstr = ajStrNew();
2514 	    ajStrAppendC(&tstr,dp->d_name);
2515 	    ajListPush(list,(void *)tstr);
2516 	}
2517     }
2518 
2519     ajListSort(list, &ajStrVcmp);
2520 
2521     while(ajListPop(list,(void **)&tstr))
2522     {
2523 	ajStrAppendS(retlist,tstr);
2524 	ajStrAppendC(retlist,"\n");
2525 	ajStrDel(&tstr);
2526     }
2527 
2528 
2529     ajListFree(&list);
2530 
2531     ajStrDel(&full);
2532     ajStrDel(&dir);
2533 
2534 
2535 #if defined (__SVR4) && defined (__sun)
2536     AJFREE(dbuf);
2537 #endif /* __SVR4 && __sun */
2538 
2539     return ajTrue;
2540 }
2541 
2542 
2543 
2544 
2545 /* @funcstatic jembossctl_do_listdirs *****************************************
2546 **
2547 ** Return directoriy files within a directory
2548 **
2549 ** @param [w] buf [char*] socket buffer
2550 ** @param [r] uid [int] uid
2551 ** @param [r] gid [int] gid
2552 ** @param [w] retlist [AjPStr*] file list
2553 **
2554 ** @return [AjBool] true if success
2555 ******************************************************************************/
2556 
jembossctl_do_listdirs(char * buf,int uid,int gid,AjPStr * retlist)2557 static AjBool jembossctl_do_listdirs(char *buf, int uid, int gid,
2558 				     AjPStr *retlist)
2559 {
2560     AjPStr dir     = NULL;
2561     AjPStr full    = NULL;
2562 
2563     char *p = NULL;
2564     DIR  *dirp;
2565     time_t t;
2566 
2567 #if defined (HAVE64) && !defined(AJ_MACOSXLF) && !defined(AJ_HPUXLF) && \
2568     !defined(AJ_FreeBSDLF) && !defined(AJ_AIXLF)
2569     struct dirent64 *dp;
2570 #else /* !(HAVE64 && !AJ_MACOSXLF && !AJ_HPUXLF && !AJ_FreeBSDLF && !AJ_AIXLF) */
2571     struct dirent *dp;
2572 #endif /* !(HAVE64 && !AJ_MACOSXLF && !AJ_HPUXLF && !AJ_FreeBSDLF && !AJ_AIXLF) */
2573 
2574 #if defined (HAVE64) && !defined(AJ_MACOSXLF) && !defined(AJ_HPUXLF) && \
2575     !defined(AJ_FreeBSDLF) && !defined(AJ_AIXLF)
2576     struct stat64 sbuf;
2577 #else /* !(HAVE64 && !AJ_MACOSXLF && !AJ_HPUXLF && !AJ_FreeBSDLF && !AJ_AIXLF) */
2578     struct stat sbuf;
2579 #endif /* !(HAVE64 && !AJ_MACOSXLF && !AJ_HPUXLF && !AJ_FreeBSDLF && !AJ_AIXLF) */
2580 
2581 
2582     AjPList list = NULL;
2583     AjPStr  tstr = NULL;
2584 #if defined (__SVR4) && defined (__sun) && defined (_POSIX_C_SOURCE)
2585     int ret = 0;
2586 #endif /* __SVR4 && __sun && _POSIX_C_SOURCE */
2587 #if defined (__SVR4) && defined (__sun)
2588     char *dbuf = NULL;
2589 
2590     if(!(dbuf=malloc(sizeof(struct dirent)+PATH_MAX)))
2591     {
2592 	fprintf(stderr,"Readdir buffer failure (do_listdirs)\n");
2593 	return ajFalse;
2594     }
2595 #endif /* __SVR4 && __sun */
2596 
2597 
2598     dir  = ajStrNew();
2599     full = ajStrNew();
2600 
2601     if(!jembossctl_initgroups(buf,gid))
2602     {
2603 	fprintf(stderr,"Initgroups failure (do_listdirs)\n");
2604 	ajStrDel(&dir);
2605 	ajStrDel(&full);
2606 	return ajFalse;
2607     }
2608 
2609 
2610 
2611     /* Skip over authentication stuff */
2612     p = buf;
2613     while(*p)
2614 	++p;
2615     ++p;
2616 
2617 
2618     /* retrieve directory */
2619     ajStrAssignC(&dir,p);
2620 
2621     jembossctl_zero((char*)buf);
2622 
2623 
2624 
2625     if(setgid(gid)==-1)
2626     {
2627 	fprintf(stderr,"setgid error (list dirs)\n");
2628 	ajStrDel(&dir);
2629 	ajStrDel(&full);
2630 	return ajFalse;
2631     }
2632 
2633 
2634     if(setuid(uid)==-1)
2635     {
2636 	fprintf(stderr,"setuid error (list dirs)\n");
2637 	ajStrDel(&dir);
2638 	ajStrDel(&full);
2639 	return ajFalse;
2640     }
2641 
2642 
2643     if(chdir(ajStrGetPtr(dir))==-1)
2644     {
2645 	fprintf(stderr,"chdir error (list dirs)\n");
2646 	ajStrDel(&dir);
2647 	ajStrDel(&full);
2648 	return ajFalse;
2649     }
2650 
2651 
2652     if(!(dirp=opendir(ajStrGetPtr(dir))))
2653     {
2654 	fprintf(stderr,"opendir error (list dirs)\n");
2655 	ajStrDel(&dir);
2656 	ajStrDel(&full);
2657 	return ajFalse;
2658     }
2659 
2660     ajDirnameFix(&dir);
2661 
2662     list = ajListNew();
2663 
2664 
2665 
2666 #if defined (__SVR4) && defined (__sun) && \
2667     defined (_POSIX_C_SOURCE) && defined (HAVE64)
2668     for(ret=readdir64_r(dirp,(struct dirent64 *)dbuf,&dp);dp;
2669 	ret=readdir64_r(dirp,(struct dirent64 *)dbuf,&dp))
2670 #else /* !(__SVR4 && __sun && _POSIX_C_SOURCE && HAVE64) */
2671 #if defined (__SVR4) && defined (__sun) && defined (_POSIX_C_SOURCE)
2672     for(ret=readdir_r(dirp,(struct dirent *)dbuf,&dp);dp;
2673 	ret=readdir_r(dirp,(struct dirent *)dbuf,&dp))
2674 #else /* !(__SVR4 && __sun && _POSIX_C_SOURCE) */
2675 #if defined (__SVR4) && defined (__sun) && !defined (__GNUC__)
2676     for(dp=readdir_r(dirp,(struct dirent *)dbuf);dp;
2677 	dp=readdir_r(dirp,(struct dirent *)dbuf))
2678 #else /* !(__SVR4 && __sun && !__GNUC__) */
2679 #if defined (HAVE64) && !defined(AJ_MACOSXLF) && !defined(AJ_HPUXLF) && \
2680     !defined(AJ_FreeBSDLF) && !defined(AJ_AIXLF)
2681     for(dp=readdir64(dirp);dp;dp=readdir64(dirp))
2682 #else /* !(HAVE64 && !AJ_MACOSXLF && !AJ_HPUXLF && !AJ_FreeBSDLF && !AJ_AIXLF) */
2683     for(dp=readdir(dirp);dp;dp=readdir(dirp))
2684 #endif /* !(HAVE64 && !AJ_MACOSXLF && !AJ_HPUXLF && !AJ_FreeBSDLF && !AJ_AIXLF) */
2685 #endif /* !(__SVR4 && __sun && !__GNUC__) */
2686 #endif /* !(__SVR4 && __sun && _POSIX_C_SOURCE) */
2687 #endif /* !(__SVR4 && __sun && _POSIX_C_SOURCE && HAVE64) */
2688     {
2689 #if defined (__SVR4) && defined (__sun) && \
2690     defined (_POSIX_C_SOURCE) && defined (HAVE64)
2691 	if(ret)
2692 	    break;
2693 #endif /* __SVR4 && __sun && _POSIX_C_SOURCE && HAVE64 */
2694 
2695 	if(*(dp->d_name)=='.')
2696 	    continue;
2697 
2698 	ajFmtPrintS(&full,"%S%s",dir,dp->d_name);
2699 
2700 #if defined (HAVE64) && !defined(AJ_MACOSXLF) && !defined(AJ_HPUXLF) && \
2701     !defined(AJ_FreeBSDLF) && !defined(AJ_AIXLF)
2702 	if(stat64(ajStrGetPtr(full),&sbuf)==-1)
2703 	    continue;
2704 #else /* !(HAVE64 && !AJ_MACOSXLF && !AJ_HPUXLF && !AJ_FreeBSDLF && !AJ_AIXLF) */
2705 	if(stat(ajStrGetPtr(full),&sbuf)==-1)
2706 	    continue;
2707 #endif /* !(HAVE64 && !AJ_MACOSXLF && !AJ_HPUXLF && !AJ_FreeBSDLF && !AJ_AIXLF) */
2708 	if(sbuf.st_mode & S_IFDIR)
2709 	{
2710 	    tstr = ajStrNew();
2711 	    ajStrAppendC(&tstr,dp->d_name);
2712 	    ajListPush(list,(void *)tstr);
2713 	}
2714     }
2715 
2716 
2717     if(ajListGetLength(list) > 1)
2718     {
2719 	ajListPop(list,(void **)&tstr);
2720 	ajListPush(list,(void *)tstr);
2721 	t = jembossctl_Datestr(tstr);
2722 	if(t)
2723 	    ajListSort(list, &jembossctl_date);
2724 	else
2725 	    ajListSort(list, &ajStrVcmp);
2726     }
2727 
2728 
2729 
2730     while(ajListPop(list,(void **)&tstr))
2731     {
2732 	ajStrAppendS(retlist,tstr);
2733 	ajStrAppendC(retlist,"\n");
2734 	ajStrDel(&tstr);
2735     }
2736 
2737     ajListFree(&list);
2738 
2739     ajStrDel(&full);
2740     ajStrDel(&dir);
2741 
2742 #if defined (__SVR4) && defined (__sun)
2743     AJFREE(dbuf);
2744 #endif /* __SVR4 && __sun */
2745 
2746     return ajTrue;
2747 }
2748 
2749 
2750 
2751 
2752 /* @funcstatic jembossctl_do_getfile ******************************************
2753 **
2754 ** Get a user file
2755 **
2756 ** @param [w] buf [char*] socket buffer
2757 ** @param [r] uid [int] uid
2758 ** @param [r] gid [int] gid
2759 ** @param [w] fbuf [unsigned char**] file
2760 ** @param [w] size [int*] uid
2761 **
2762 ** @return [AjBool] true if success
2763 ******************************************************************************/
2764 
jembossctl_do_getfile(char * buf,int uid,int gid,unsigned char ** fbuf,int * size)2765 static AjBool jembossctl_do_getfile(char *buf, int uid, int gid,
2766 			      unsigned char **fbuf, int *size)
2767 {
2768     AjPStr file    = NULL;
2769     AjPStr message = NULL;
2770 
2771     char *p = NULL;
2772     char *q = NULL;
2773 #if defined (HAVE64) && !defined(AJ_MACOSXLF) && !defined(AJ_HPUXLF) && \
2774     !defined(AJ_FreeBSDLF) && !defined(AJ_AIXLF)
2775     struct stat64 sbuf;
2776 #else /* !(HAVE64 && !AJ_MACOSXLF && !AJ_HPUXLF && !AJ_FreeBSDLF && !AJ_AIXLF) */
2777     struct stat sbuf;
2778 #endif /* !(HAVE64 && !AJ_MACOSXLF && !AJ_HPUXLF && !AJ_FreeBSDLF && !AJ_AIXLF) */
2779     int n = 0;
2780     int sofar = 0;
2781     int pos = 0;
2782     int fd;
2783     int sum = 0;
2784     unsigned long block = 0;
2785     long then = 0L;
2786     long now  = 0L;
2787     struct timeval tv;
2788 
2789     file = ajStrNew();
2790 
2791     if(!jembossctl_initgroups(buf,gid))
2792     {
2793 	message = ajStrNew();
2794 	ajFmtPrintS(&message,"-1");
2795 	if(jembossctl_snd(ajStrGetPtr(message),ajStrGetLen(message)+1)==-1)
2796 	{
2797 	    fprintf(stderr,"get file send error\n");
2798 	    return ajFalse;
2799 	}
2800 	ajStrDel(&message);
2801 
2802 	fprintf(stderr,"Initgroups failure (do_getfile)\n");
2803 	ajStrDel(&file);
2804 	return ajFalse;
2805     }
2806 
2807     /* Skip over authentication stuff */
2808     p = buf;
2809     while(*p)
2810 	++p;
2811     ++p;
2812 
2813     /* retrieve file name */
2814     ajStrAssignC(&file,p);
2815 
2816     jembossctl_zero((char*)buf);
2817 
2818     if(setgid(gid)==-1)
2819     {
2820 	message = ajStrNew();
2821 	ajFmtPrintS(&message,"-1");
2822 
2823 	if(jembossctl_snd(ajStrGetPtr(message),ajStrGetLen(message)+1)==-1)
2824 	{
2825 	    fprintf(stderr,"get file send error\n");
2826 	    ajStrDel(&file);
2827 	    ajStrDel(&message);
2828 	    return ajFalse;
2829 	}
2830 	ajStrDel(&message);
2831 
2832 	fprintf(stderr,"setgid error (get file)\n");
2833 	ajStrDel(&file);
2834 	return ajFalse;
2835     }
2836 
2837     if(setuid(uid)==-1)
2838     {
2839 	message = ajStrNew();
2840 	ajFmtPrintS(&message,"-1");
2841 
2842 	if(jembossctl_snd(ajStrGetPtr(message),ajStrGetLen(message)+1)==-1)
2843 	{
2844 	    fprintf(stderr,"get file send error\n");
2845 	    ajStrDel(&file);
2846 	    ajStrDel(&message);
2847 	    return ajFalse;
2848 	}
2849 	ajStrDel(&message);
2850 
2851 	fprintf(stderr,"setuid error (get file)\n");
2852 	ajStrDel(&file);
2853 	return ajFalse;
2854     }
2855 
2856 
2857     if(!jembossctl_chdir(ajStrGetPtr(file)))
2858     {
2859 	message = ajStrNew();
2860 	ajFmtPrintS(&message,"-1");
2861 
2862 	if(jembossctl_snd(ajStrGetPtr(message),ajStrGetLen(message)+1)==-1)
2863 	{
2864 	    fprintf(stderr,"get file send error\n");
2865 	    ajStrDel(&file);
2866 	    ajStrDel(&message);
2867 	    return ajFalse;
2868 	}
2869 	ajStrDel(&message);
2870 
2871 	fprintf(stderr,"chdir error (get file)\n");
2872 	ajStrDel(&file);
2873 	return ajFalse;
2874     }
2875 
2876 
2877 #if defined (HAVE64) && !defined(AJ_MACOSXLF) && !defined(AJ_HPUXLF) && \
2878     !defined(AJ_FreeBSDLF) && !defined(AJ_AIXLF)
2879     if(stat64(ajStrGetPtr(file),&sbuf)==-1)
2880     {
2881 	fprintf(stderr,"stat error (get file)\n");
2882 	n = *size = 0;
2883     }
2884 #else /* !(HAVE64 && !AJ_MACOSXLF && !AJ_HPUXLF && !AJ_FreeBSDLF && !AJ_AIXLF) */
2885     if(stat(ajStrGetPtr(file),&sbuf)==-1)
2886     {
2887 	fprintf(stderr,"stat error (get file)\n");
2888 	n = *size = 0;
2889     }
2890 #endif /* !(HAVE64 && !AJ_MACOSXLF && !AJ_HPUXLF && !AJ_FreeBSDLF && !AJ_AIXLF) */
2891     else
2892 	n = *size = sbuf.st_size;
2893 
2894 
2895     message = ajStrNew();
2896     ajFmtPrintS(&message,"%d",n);
2897     if(jembossctl_snd(ajStrGetPtr(message),ajStrGetLen(message)+1)==-1)
2898     {
2899 	fprintf(stderr,"get file send error\n");
2900 	ajStrDel(&file);
2901 	ajStrDel(&message);
2902 	return ajFalse;
2903     }
2904 
2905     if(!n)
2906     {
2907 	ajStrDel(&file);
2908 	ajStrDel(&message);
2909 	return ajFalse;
2910     }
2911 
2912     if(!(*fbuf=(unsigned char*)malloc(n)))
2913     {
2914 	fprintf(stderr,"malloc error (get file)\n");
2915 	ajStrDel(&message);
2916 	ajStrDel(&file);
2917 	return ajFalse;
2918     }
2919 
2920     if((fd=open(ajStrGetPtr(file),O_RDONLY))==-1)
2921     {
2922 	fprintf(stderr,"open error (get file)\n");
2923 	ajStrDel(&message);
2924 	ajStrDel(&file);
2925 	return ajFalse;
2926     }
2927 
2928     block = 1;
2929     if(jembossctl_java_block(fd,block)==-1)
2930     {
2931 	fprintf(stderr,"Cannot unblock 9. %d\n",errno);
2932 	ajStrDel(&file);
2933 	ajStrDel(&message);
2934 	return ajFalse;
2935     }
2936 
2937 
2938     gettimeofday(&tv,NULL);
2939     then = tv.tv_sec;
2940 
2941     p = q = (char *)*fbuf;
2942     while(sum!=n)
2943     {
2944 	gettimeofday(&tv,NULL);
2945 	now = tv.tv_sec;
2946 	if(now-then >= TIMEOUT)
2947 	{
2948 	    fprintf(stderr,"getfile TIMEOUT\n");
2949 	    ajStrDel(&file);
2950 	    ajStrDel(&message);
2951 	    return ajFalse;
2952 	}
2953 
2954 	while((sofar=read(fd,p,n-(p-q)))==-1 && errno==EINTR);
2955 	if(sofar > 0)
2956 	{
2957 	    sum += sofar;
2958 	    p   += sofar;
2959 	    gettimeofday(&tv,NULL);
2960 	    then = tv.tv_sec;
2961 	}
2962     }
2963 
2964 
2965     block = 0;
2966     if(jembossctl_java_block(fd,block)==-1)
2967     {
2968 	fprintf(stderr,"Cannot block 10. %d\n",errno);
2969 	ajStrDel(&file);
2970 	ajStrDel(&message);
2971 	return ajFalse;
2972     }
2973 
2974 
2975     if(close(fd)==-1)
2976     {
2977 	fprintf(stderr,"close error (get file)\n");
2978 	ajStrDel(&message);
2979 	ajStrDel(&file);
2980 	return ajFalse;
2981     }
2982 
2983 
2984     gettimeofday(&tv,NULL);
2985     then = tv.tv_sec;
2986 
2987 
2988     while(pos+JBUFFLEN < n)
2989     {
2990 	gettimeofday(&tv,NULL);
2991 	now = tv.tv_sec;
2992 	if(now-then >= TIMEOUT)
2993 	{
2994 	    fprintf(stderr,"getfile TIMEOUT\n");
2995 	    ajStrDel(&file);
2996 	    ajStrDel(&message);
2997 	    return ajFalse;
2998 	}
2999 
3000 	sofar = fwrite((void*)&(*fbuf)[pos],1,JBUFFLEN,stdout);
3001 	if(sofar > 0)
3002 	{
3003 	    pos += sofar;
3004 	    gettimeofday(&tv,NULL);
3005 	    then = tv.tv_sec;
3006 	}
3007     }
3008 
3009     if(n)
3010 	if(n-pos)
3011 	{
3012 	    while(pos!=n)
3013 	    {
3014 		gettimeofday(&tv,NULL);
3015 		now = tv.tv_sec;
3016 		if(now-then >= TIMEOUT)
3017 		{
3018 		    fprintf(stderr,"getfile TIMEOUT\n");
3019 		    ajStrDel(&file);
3020 		    ajStrDel(&message);
3021 		    return ajFalse;
3022 		}
3023 
3024 		sofar = fwrite((void *)&(*fbuf)[pos],1,n-pos,stdout);
3025 		if(sofar > 0)
3026 		{
3027 		    pos += sofar;
3028 		    gettimeofday(&tv,NULL);
3029 		    then = tv.tv_sec;
3030 		}
3031 	    }
3032 
3033 	}
3034 
3035 
3036     /* Temporary fix to allow ajjava to finish receiving file before term */
3037     tv.tv_sec = 0;
3038     tv.tv_usec = 100000;
3039     select(0,NULL,NULL,NULL,&tv);
3040 
3041     ajStrDel(&file);
3042     ajStrDel(&message);
3043 
3044     return ajTrue;
3045 }
3046 
3047 
3048 
3049 
3050 /* @funcstatic jembossctl_do_putfile ******************************************
3051 **
3052 ** Put a user file
3053 **
3054 ** @param [w] buf [char*] socket buffer
3055 ** @param [r] uid [int] uid
3056 ** @param [r] gid [int] gid
3057 **
3058 ** @return [AjBool] true if success
3059 ******************************************************************************/
3060 
jembossctl_do_putfile(char * buf,int uid,int gid)3061 static AjBool jembossctl_do_putfile(char *buf, int uid, int gid)
3062 {
3063     int sofar = 0;
3064     int size;
3065     char *p = NULL;
3066     int mlen;
3067     int fd;
3068     unsigned char *fbuf = NULL;
3069     AjPStr file;
3070     struct timeval tv;
3071     long then;
3072     long now;
3073 
3074     AjPStr message;
3075     int rval=0;
3076     unsigned long block = 0;
3077     int sum = 0;
3078     int got = 0;
3079 
3080 
3081     message = ajStrNewC("OK");
3082     file    = ajStrNew();
3083 
3084     if(!jembossctl_initgroups(buf,gid))
3085     {
3086 	fprintf(stderr,"Initgroups failure (do_putfile)\n");
3087 	ajStrDel(&file);
3088 	ajStrDel(&message);
3089 	return ajFalse;
3090     }
3091 
3092     /* Skip over authentication stuff */
3093     p = buf;
3094     while(*p)
3095 	++p;
3096     ++p;
3097 
3098     /* retrieve file name */
3099     ajStrAssignC(&file,p);
3100 
3101     jembossctl_zero((char*)buf);
3102 
3103     if(jembossctl_snd(ajStrGetPtr(message),2)==-1)
3104     {
3105 	fprintf(stderr,"jctl OK1 error (jembossctl_do_putfile)\n");
3106 	ajStrDel(&file);
3107 	ajStrDel(&message);
3108 	return ajFalse;
3109     }
3110 
3111 
3112 
3113     rval = jembossctl_rcv(buf);
3114     if(rval==-1)
3115     {
3116 	fprintf(stderr,"jctl recv error (jembossctl_do_putfile)\n");
3117 	ajStrDel(&file);
3118 	ajStrDel(&message);
3119 	return ajFalse;
3120     }
3121 
3122     if(sscanf(buf,"%d",&size)!=1)
3123     {
3124 	fprintf(stderr,"jctl file size read  error (jembossctl_do_putfile)\n");
3125 	ajStrDel(&file);
3126 	ajStrDel(&message);
3127 	return ajFalse;
3128     }
3129 
3130 
3131     if(jembossctl_snd(ajStrGetPtr(message),2)==-1)
3132     {
3133 	fprintf(stderr,"jctl OK2 error (jembossctl_do_putfile)\n");
3134 	ajStrDel(&file);
3135 	ajStrDel(&message);
3136 	return ajFalse;
3137     }
3138 
3139 
3140 
3141     if(size)
3142     {
3143 	if(!(fbuf=(unsigned char *)malloc(size)))
3144 	{
3145 	    fprintf(stderr,"jctl malloc error (jembossctl_do_putfile)\n");
3146 	    ajStrDel(&message);
3147 	    ajStrDel(&file);
3148 	    return ajFalse;
3149 	}
3150     }
3151 
3152 
3153     gettimeofday(&tv,NULL);
3154     then = tv.tv_sec;
3155 
3156     while(sofar != size)
3157     {
3158 	gettimeofday(&tv,NULL);
3159 	now = tv.tv_sec;
3160 	if(now-then>PUTTIMEOUT)
3161 	{
3162 	    fprintf(stderr,"jctl timeout error (jembossctl_do_putfile)\n");
3163 	    ajStrDel(&file);
3164 	    ajStrDel(&message);
3165 	    return ajFalse;
3166 	}
3167 
3168 
3169 
3170 	mlen = jembossctl_rcv(buf);
3171 	if(mlen==-1)
3172 	{
3173 	    fprintf(stderr,"jctl recv error (jembossctl_do_putfile)\n");
3174 	    ajStrDel(&file);
3175 	    ajStrDel(&message);
3176 	    return ajFalse;
3177 	}
3178 
3179 	if(mlen>0)
3180 	{
3181 	    memcpy((void *)&fbuf[sofar],(const void *)buf,mlen);
3182 	    sofar += mlen;
3183 	    gettimeofday(&tv,NULL);
3184 	    then = tv.tv_sec;
3185 	}
3186     }
3187 
3188 
3189 
3190 
3191 
3192     if(setgid(gid)==-1)
3193     {
3194 	fprintf(stderr,"setgid error (put file)\n");
3195 	if(size)
3196 	    AJFREE(fbuf);
3197 	ajStrDel(&file);
3198 	ajStrDel(&message);
3199 	return ajFalse;
3200     }
3201 
3202     if(setuid(uid)==-1)
3203     {
3204 	fprintf(stderr,"setuid error (put file)\n");
3205 	if(size)
3206 	    AJFREE(fbuf);
3207 	ajStrDel(&file);
3208 	ajStrDel(&message);
3209 	return ajFalse;
3210     }
3211 
3212     if(!jembossctl_chdir(ajStrGetPtr(file)))
3213     {
3214 	fprintf(stderr,"chdir error (put file)\n");
3215 	if(size)
3216 	    AJFREE(fbuf);
3217 	ajStrDel(&file);
3218 	ajStrDel(&message);
3219 	return ajFalse;
3220     }
3221 
3222 
3223     if((fd=open(ajStrGetPtr(file),O_CREAT|O_WRONLY|O_TRUNC,0644))<0)
3224     {
3225 	fprintf(stderr,"jctl open error (jembossctl_do_putfile)\n");
3226 	if(size)
3227 	    AJFREE(fbuf);
3228 	ajStrDel(&file);
3229 	ajStrDel(&message);
3230 	return ajFalse;
3231     }
3232 
3233 
3234     block = 1;
3235     if(jembossctl_java_block(fd,block)==-1)
3236     {
3237 	fprintf(stderr,"Cannot unblock 11. %d\n",errno);
3238 	if(size)
3239 	    AJFREE(fbuf);
3240 	ajStrDel(&file);
3241 	ajStrDel(&message);
3242 	return ajFalse;
3243     }
3244 
3245 
3246     gettimeofday(&tv,NULL);
3247     then = tv.tv_sec;
3248 
3249     while(sum<size)
3250     {
3251 	gettimeofday(&tv,NULL);
3252 	now = tv.tv_sec;
3253 	if(now-then>PUTTIMEOUT)
3254 	{
3255 	    fprintf(stderr,"jctl timeout error (jembossctl_do_putfile)\n");
3256 	    ajStrDel(&file);
3257 	    ajStrDel(&message);
3258 	    return ajFalse;
3259 	}
3260 
3261 	if((got=write(fd,(void *)fbuf,size))>0)
3262 	{
3263 	    sum += got;
3264 	    gettimeofday(&tv,NULL);
3265 	    then = tv.tv_sec;
3266 	}
3267     }
3268 
3269     block = 0;
3270     if(jembossctl_java_block(fd,block)==-1)
3271     {
3272 	fprintf(stderr,"Cannot unblock 12. %d\n",errno);
3273 	if(size)
3274 	    AJFREE(fbuf);
3275 	ajStrDel(&file);
3276 	ajStrDel(&message);
3277 	return ajFalse;
3278     }
3279 
3280     if(close(fd)<0)
3281     {
3282 	fprintf(stderr,"jctl close error (jembossctl_do_putfile)\n");
3283 	if(size)
3284 	    AJFREE(fbuf);
3285 	ajStrDel(&file);
3286 	ajStrDel(&message);
3287 	return ajFalse;
3288     }
3289 
3290     if(size)
3291 	AJFREE(fbuf);
3292 
3293     ajStrDel(&file);
3294     ajStrDel(&message);
3295 
3296 
3297     return ajTrue;
3298 }
3299 
3300 
3301 
3302 
3303 /* @funcstatic jembossctl_tidy_strings ****************************************
3304 **
3305 ** Deallocate memory
3306 **
3307 ** @param [w] tstr [AjPStr*] temp string
3308 ** @param [w] home [AjPStr*] home directory
3309 ** @param [w] retlist [AjPStr*] filename list
3310 ** @param [w] buf [char*] socket buffer
3311 **
3312 ** @return [void]
3313 ******************************************************************************/
3314 
jembossctl_tidy_strings(AjPStr * tstr,AjPStr * home,AjPStr * retlist,char * buf)3315 static void jembossctl_tidy_strings(AjPStr *tstr, AjPStr *home,
3316 				    AjPStr *retlist,
3317 				    char *buf)
3318 {
3319     ajStrDel(tstr);
3320     ajStrDel(home);
3321     ajStrDel(retlist);
3322     AJFREE(buf);
3323 
3324     return;
3325 }
3326 
3327 
3328 
3329 
3330 /* @funcstatic jembossctl_fork_tidy *******************************************
3331 **
3332 ** Deallocate fork memory
3333 **
3334 ** @param [w] cl [AjPStr*] command line
3335 ** @param [w] prog [AjPStr*] program name
3336 ** @param [w] enviro [AjPStr*] environment
3337 ** @param [w] dir [AjPStr*] directory
3338 ** @param [w] outstd [AjPStr*] stdout
3339 ** @param [w] errstd [AjPStr*] stderr
3340 **
3341 ** @return [void]
3342 ******************************************************************************/
3343 
jembossctl_fork_tidy(AjPStr * cl,AjPStr * prog,AjPStr * enviro,AjPStr * dir,AjPStr * outstd,AjPStr * errstd)3344 static void jembossctl_fork_tidy(AjPStr *cl, AjPStr *prog, AjPStr *enviro,
3345 			   AjPStr *dir, AjPStr *outstd, AjPStr *errstd)
3346 {
3347     ajStrDel(cl);
3348     ajStrDel(prog);
3349     ajStrDel(enviro);
3350     ajStrDel(dir);
3351     ajStrDel(outstd);
3352     ajStrDel(errstd);
3353 
3354     return;
3355 }
3356 
3357 
3358 
3359 
3360 /* @funcstatic jembossctl_check_buffer ****************************************
3361 **
3362 ** Sanity check on socket commands
3363 **
3364 ** @param [u] buf [char*] socket buffer
3365 ** @param [r] mlen [int] buffer length
3366 **
3367 ** @return [AjBool] true if sane
3368 ******************************************************************************/
3369 
jembossctl_check_buffer(char * buf,int mlen)3370 static AjBool jembossctl_check_buffer(char *buf, int mlen)
3371 {
3372     const char *p;
3373     int str1len;
3374     int command;
3375     int count;
3376     char *tbuf;
3377 
3378     if(mlen==JBUFFLEN)
3379 	return ajFalse;
3380 
3381     tbuf = (char *)buf;
3382     tbuf[mlen]='\0';
3383 
3384     /* get the first string and check for reasonable length */
3385     p = buf;
3386     while(*p)
3387 	++p;
3388 
3389     /* Command, username & password shouldn't be >50 characters */
3390     str1len = p-buf+1;
3391     if(str1len > 50)
3392 	return ajFalse;
3393 
3394     if(sscanf(buf,"%d",&command)!=1)
3395 	return ajFalse;
3396 
3397     if(command<COMM_AUTH || command>SEQSET_ATTRIB)
3398 	return ajFalse;
3399 
3400     if(command==COMM_AUTH)
3401 	return ajTrue;
3402 
3403     count = str1len;
3404 
3405     while(*p && count<JBUFFLEN)
3406     {
3407 	++p;
3408 	++count;
3409     }
3410 
3411     if(count==JBUFFLEN)
3412 	return ajFalse;
3413 
3414     /* All commands except the fork have two strings */
3415     if((command != EMBOSS_FORK) && (command!=BATCH_FORK) &&
3416        (command!=RENAME_FILE))
3417 	return ajTrue;
3418 
3419     /* Check for valid third string */
3420     ++p;
3421     ++count;
3422     while(*p && count<JBUFFLEN)
3423     {
3424 	++p;
3425 	++count;
3426     }
3427 
3428     if(count==JBUFFLEN)
3429 	return ajFalse;
3430 
3431     if(command==RENAME_FILE)
3432         return ajTrue;
3433 
3434     /* Check for valid fourth string */
3435     ++p;
3436     ++count;
3437     while(*p && count<JBUFFLEN)
3438     {
3439 	++p;
3440 	++count;
3441     }
3442 
3443     if(count==JBUFFLEN)
3444 	return ajFalse;
3445 
3446     return ajTrue;
3447 }
3448 
3449 
3450 
3451 
3452 /* @funcstatic jembossctl_chdir ***********************************************
3453 **
3454 ** If a filename is given (e.g. delete) then first chdir to the directory
3455 **
3456 ** @param [r] file [const char*] file name
3457 **
3458 ** @return [AjBool] true if success
3459 ******************************************************************************/
3460 
jembossctl_chdir(const char * file)3461 static AjBool jembossctl_chdir(const char *file)
3462 {
3463     char *p;
3464     AjPStr str = NULL;
3465     int ret;
3466     char *buf;
3467     int  len = 0;
3468 
3469     if(!(buf=(char *)malloc((len=strlen(file))+1)))
3470 	return ajFalse;
3471     strcpy(buf,file);
3472 
3473     if(buf[len-1]=='/')
3474 	buf[len-1] = '\0';
3475 
3476     str = ajStrNew();
3477     if(!(p=strrchr(buf,(int)'/')))
3478 	ajStrAssignC(&str,".");
3479     else
3480 	ajStrAssignSubC(&str,buf,0,p-buf);
3481 
3482     ret = chdir(ajStrGetPtr(str));
3483     ajStrDel(&str);
3484     AJFREE(buf);
3485 
3486     if(ret==-1)
3487 	return ajFalse;
3488 
3489     return ajTrue;
3490 }
3491 
3492 
3493 
3494 
3495 /* @funcstatic jembossctl_initgroups ******************************************
3496 **
3497 ** Initialise groups
3498 **
3499 ** @param [r] buf [const char*] socket buffer
3500 ** @param [r] gid [int] gid
3501 **
3502 ** @return [AjBool] true if success
3503 ******************************************************************************/
3504 
jembossctl_initgroups(const char * buf,int gid)3505 static AjBool jembossctl_initgroups(const char *buf, int gid)
3506 {
3507     AjPStr str  = NULL;
3508     AjPStr user = NULL;
3509 
3510     str  = ajStrNewC(buf);
3511     user = ajStrNew();
3512     ajFmtScanS(str,"%*d%S",&user);
3513     ajStrDel(&str);
3514 
3515     if(initgroups(ajStrGetPtr(user),gid)==-1)
3516     {
3517 	ajStrDel(&user);
3518 	return ajFalse;
3519     }
3520     ajStrDel(&user);
3521 
3522     return ajTrue;
3523 }
3524 
3525 
3526 
3527 
3528 /* @funcstatic jembossctl_zero ************************************************
3529 **
3530 ** Wipe username/password
3531 **
3532 ** @param [w] buf [char*] socket buffer
3533 **
3534 ** @return [void]
3535 ******************************************************************************/
3536 
jembossctl_zero(char * buf)3537 static void jembossctl_zero(char *buf)
3538 {
3539     char *p;
3540 
3541     p = buf;
3542     while(*p)
3543 	*p++ = '\0';
3544 
3545     return;
3546 }
3547 
3548 
3549 
3550 
3551 /* @funcstatic jembossctl_pipe_read *******************************************
3552 **
3553 ** Read a byte stream from stdin (unblocked)
3554 **
3555 ** @param [w] buf [char *] buffer to read
3556 ** @param [r] n [int] number of bytes to read
3557 ** @param [r] seconds [int] time-out
3558 **
3559 ** @return [int] 0=success  -1=failure
3560 ** @@
3561 ******************************************************************************/
3562 
jembossctl_pipe_read(char * buf,int n,int seconds)3563 static int jembossctl_pipe_read(char *buf, int n, int seconds)
3564 {
3565 #ifdef HAVE_POLL
3566     struct pollfd ufds;
3567     unsigned int  nfds;
3568 #else /* !HAVE_POLL */
3569     fd_set fdr;
3570     fd_set fdw;
3571     struct timeval tfd;
3572 #endif /* !HAVE_POLL */
3573 
3574     int  sum;
3575     int  got = 0;
3576     int  ret = 0;
3577     char *p;
3578     int  rchan = 0;
3579     unsigned long block = 0;
3580     long then = 0;
3581     long now  = 0;
3582     struct timeval tv;
3583 
3584     gettimeofday(&tv,NULL);
3585     then = tv.tv_sec;
3586 
3587 
3588     block = 1;
3589     if(jembossctl_java_block(rchan,block)==-1)
3590     {
3591 	fprintf(stderr,"Cannot unblock 13. %d\n",errno);
3592 	return -1;
3593     }
3594 
3595 
3596     p   = buf;
3597     sum = 0;
3598 
3599 
3600 #ifdef HAVE_POLL
3601     while(sum!=n)
3602     {
3603 	gettimeofday(&tv,NULL);
3604 	now = tv.tv_sec;
3605 	if(now-then >= seconds)
3606 	{
3607 	    fprintf(stderr,"jembossctl_pipe_read timeout\n");
3608 	    return -1;
3609 	}
3610 
3611 	/* Check pipe is readable */
3612 	ufds.fd = rchan;
3613 	ufds.events = POLLIN | POLLPRI;
3614 	nfds = 1;
3615 
3616 	ret=poll(&ufds,nfds,1);
3617 
3618 	if(ret && ret!=-1)
3619 	{
3620 	    if((ufds.revents & POLLIN) || (ufds.revents & POLLPRI))
3621 	    {
3622 		while((got=read(rchan,p,n-(p-buf)))==-1 && errno==EINTR);
3623 		if(got == -1)
3624 		{
3625 		    fprintf(stderr,"jembossctl_pipe_read read error\n");
3626 		    return -1;
3627 		}
3628 		sum += got;
3629 		p += got;
3630 		gettimeofday(&tv,NULL);
3631 		then = tv.tv_sec;
3632 	    }
3633 	}
3634     }
3635 #else /* !HAVE_POLL */
3636     while(sum!=n)
3637     {
3638 	gettimeofday(&tv,NULL);
3639 	now = tv.tv_sec;
3640 	if(now-then >= seconds)
3641 	{
3642 	    fprintf(stderr,"jembossctl_pipe_read timeout\n");
3643 	    return -1;
3644 	}
3645 
3646 	/* Check pipe is readable */
3647 	tfd.tv_sec  = 0;
3648 	tfd.tv_usec = 1000;
3649 	FD_ZERO(&fdr);
3650 	FD_SET(rchan,&fdr);
3651 	fdw = fdr;
3652 
3653 	ret = select(rchan+1,&fdr,&fdw,NULL,&tfd);
3654 
3655 	if(ret && ret!=-1 && FD_ISSET(rchan,&fdr))
3656 	{
3657 	    while((got=read(rchan,p,n-(p-buf)))==-1 && errno==EINTR);
3658 	    if(got == -1)
3659 	    {
3660 		fprintf(stderr,"jembossctl_pipe_read read error\n");
3661 		return -1;
3662 	    }
3663 	    sum += got;
3664 	    p += got;
3665 	    gettimeofday(&tv,NULL);
3666 	    then = tv.tv_sec;
3667 	}
3668     }
3669 #endif /* !HAVE_POLL */
3670 
3671     block = 0;
3672     if(jembossctl_java_block(rchan,block)==-1)
3673     {
3674 	fprintf(stderr,"Cannot block 14. %d\n",errno);
3675 	return -1;
3676     }
3677 
3678     return 0;
3679 }
3680 
3681 
3682 
3683 
3684 /* @funcstatic jembossctl_pipe_write ******************************************
3685 **
3686 ** Write a byte stream to stdout (unblocked)
3687 **
3688 ** @param [r] buf [const char *] buffer to write
3689 ** @param [r] n [int] number of bytes to write
3690 ** @param [r] seconds [int] time-out
3691 **
3692 ** @return [int] 0=success  -1=failure
3693 ** @@
3694 ******************************************************************************/
3695 
jembossctl_pipe_write(const char * buf,int n,int seconds)3696 static int jembossctl_pipe_write(const char *buf, int n, int seconds)
3697 {
3698 #ifdef HAVE_POLL
3699     struct pollfd ufds;
3700     unsigned int  nfds;
3701 #else /* !HAVE_POLL */
3702     fd_set fdr;
3703     fd_set fdw;
3704     struct timeval tfd;
3705 #endif /* !HAVE_POLL */
3706 
3707     int  written;
3708     int  sent = 0;
3709     int  ret  = 0;
3710     const char *p;
3711     int tchan = 1;
3712     unsigned long block = 0;
3713     long then = 0;
3714     long now  = 0;
3715     struct timeval tv;
3716 
3717     gettimeofday(&tv,NULL);
3718     then = tv.tv_sec;
3719 
3720 
3721     block = 1;
3722     if(jembossctl_java_block(tchan,block)==-1)
3723     {
3724 	fprintf(stderr,"Cannot unblock 15. %d\n",errno);
3725 	return -1;
3726     }
3727 
3728 
3729     p = buf;
3730     written = 0;
3731 
3732 #ifdef HAVE_POLL
3733     while(written!=n)
3734     {
3735 	gettimeofday(&tv,NULL);
3736 	now = tv.tv_sec;
3737 	if(now-then >= seconds)
3738 	{
3739 	    fprintf(stderr,"jembossctl_pipe_write timeout\n");
3740 	    return -1;
3741 	}
3742 
3743 	/* Check pipe is writeable */
3744 	ufds.fd = tchan;
3745 	ufds.events = POLLOUT;
3746 	nfds = 1;
3747 	ret=poll(&ufds,nfds,1);
3748 
3749 	if(ret && ret!=-1 && (ufds.revents & POLLOUT))
3750 	{
3751 	    while((sent=write(tchan,p,n-(p-buf)))==-1 && errno==EINTR);
3752 	    if(sent == -1)
3753 	    {
3754 		fprintf(stderr,"jembossctl_pipe_write send error\n");
3755 		return -1;
3756 	    }
3757 	    written += sent;
3758 	    p += sent;
3759 	    gettimeofday(&tv,NULL);
3760 	    then = tv.tv_sec;
3761 	}
3762     }
3763 #else /* !HAVE_POLL */
3764     while(written!=n)
3765     {
3766 	gettimeofday(&tv,NULL);
3767 	now = tv.tv_sec;
3768 	if(now-then >= seconds)
3769 	{
3770 	    fprintf(stderr,"jembossctl_pipe_write timeout\n");
3771 	    return -1;
3772 	}
3773 
3774 	/* Check pipe is writeable */
3775 	tfd.tv_sec  = 0;
3776 	tfd.tv_usec = 1000;
3777 	FD_ZERO(&fdw);
3778 	FD_SET(tchan,&fdw);
3779 	fdr = fdw;
3780 
3781 	ret = select(tchan+1,&fdr,&fdw,NULL,&tfd);
3782 
3783 	if(ret && ret!=-1 && FD_ISSET(tchan,&fdw))
3784 	{
3785 	    while((sent=write(tchan,p,n-(p-buf)))==-1 && errno==EINTR);
3786 	    if(sent == -1)
3787 	    {
3788 		fprintf(stderr,"jembossctl_pipe_write send error\n");
3789 		return -1;
3790 	    }
3791 	    written += sent;
3792 	    p += sent;
3793 	    gettimeofday(&tv,NULL);
3794 	    then = tv.tv_sec;
3795 	}
3796     }
3797 #endif /* !HAVE_POLL */
3798 
3799     block = 0;
3800     if(jembossctl_java_block(tchan,block)==-1)
3801     {
3802 	fprintf(stderr,"Cannot block 16. %d\n",errno);
3803 	return -1;
3804     }
3805 
3806     return 0;
3807 }
3808 
3809 
3810 
3811 
3812 /* @funcstatic jembossctl_snd *************************************************
3813 **
3814 ** Mimic socket write using pipes
3815 **
3816 ** @param [r] buf [const char *] buffer to write
3817 ** @param [r] len [int] number of bytes to write
3818 **
3819 ** @return [int] 0=success  -1=failure
3820 ** @@
3821 ******************************************************************************/
3822 
jembossctl_snd(const char * buf,int len)3823 static int jembossctl_snd(const char *buf,int len)
3824 {
3825 
3826     if(jembossctl_pipe_write((char *)&len,sizeof(int),TIMEOUT)==-1)
3827     {
3828 	fprintf(stderr,"jembossctl_snd error\n");
3829 	return -1;
3830     }
3831 
3832     if(jembossctl_pipe_write(buf,len,TIMEOUT)==-1)
3833     {
3834 	fprintf(stderr,"jembossctl_snd error\n");
3835 	return -1;
3836     }
3837 
3838     return 0;
3839 }
3840 
3841 
3842 
3843 
3844 /* @funcstatic jembossctl_rcv *************************************************
3845 **
3846 ** Mimic socket read using pipes
3847 **
3848 ** @param [w] buf [char *] buffer for read
3849 **
3850 ** @return [int] 0=success  -1=failure
3851 ** @@
3852 ******************************************************************************/
3853 
jembossctl_rcv(char * buf)3854 static int jembossctl_rcv(char *buf)
3855 {
3856     int len;
3857 
3858     if(jembossctl_pipe_read((char *)&len,sizeof(int),TIMEOUT)==-1)
3859     {
3860 	fprintf(stderr,"jembossctl_rcv error\n");
3861 	return -1;
3862     }
3863 
3864     if(jembossctl_pipe_read(buf,len,TIMEOUT)==-1)
3865     {
3866 	fprintf(stderr,"jembossctl_rcv error\n");
3867 	return -1;
3868     }
3869 
3870     return len;
3871 }
3872 
3873 
3874 
3875 
3876 /* @funcstatic jembossctl_java_block ******************************************
3877 **
3878 ** File descriptor block/unblock
3879 **
3880 ** @param [r] chan [int] file descriptor
3881 ** @param [r] flag [unsigned long] block=1 unblock=0
3882 **
3883 ** @return [int] 0=success  -1=failure
3884 ** @@
3885 ******************************************************************************/
3886 
jembossctl_java_block(int chan,unsigned long flag)3887 static int jembossctl_java_block(int chan, unsigned long flag)
3888 {
3889 
3890     if(ioctl(chan,FIONBIO,&flag)==-1)
3891     {
3892 #ifdef __sgi
3893 	if(errno==ENOSYS)
3894 	    return 0;
3895 #endif /* __sgi */
3896 #ifdef __hpux
3897 	if(errno==ENOTTY)
3898 	    return 0;
3899 #endif /* __hpux */
3900 	return -1;
3901     }
3902 
3903     return 0;
3904 }
3905 
3906 
3907 
3908 
3909 /* @funcstatic jembossctl_Datestr *********************************************
3910 **
3911 ** Test string for valid Jemboss date. Return time_t
3912 ** or 0 if invalid string
3913 **
3914 ** @param [r] s [const AjPStr] potential date string
3915 **
3916 ** @return [time_t] failure=0
3917 ** @@
3918 ******************************************************************************/
3919 
jembossctl_Datestr(const AjPStr s)3920 static time_t jembossctl_Datestr(const AjPStr s)
3921 {
3922     AjPStr tmp = NULL;
3923     struct tm tm;
3924     char *p    = NULL;
3925     AjPStr mon = NULL;
3926     ajint day = 0;
3927     ajint hr  = 0;
3928     ajint min = 0;
3929     ajint sec = 0;
3930     ajint yr  = 0;
3931 #ifdef __ppc__
3932     ajint i;
3933     static char *ms[] =
3934     {
3935 	"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct",
3936 	"Nov","Dec"
3937     };
3938     static char *jtz="GMT";
3939 #endif /* __ppc__ */
3940 
3941     tmp = ajStrNew();
3942     ajStrAssignS(&tmp,s);
3943 
3944     p = tmp->Ptr;
3945 
3946     while(*p)
3947     {
3948 	if(*p == '_' || *p==':')
3949 	    *p=' ';
3950 	++p;
3951     }
3952 
3953     mon = ajStrNew();
3954     if(ajFmtScanS(tmp,"%*s %*s %S %d %d %d %d %*s %d",&mon,&day,&hr,&min,
3955 		  &sec,&yr) !=  6)
3956     {
3957 	ajStrDel(&mon);
3958 	return 0;
3959     }
3960 
3961 
3962 #ifndef __ppc__
3963     ajFmtPrintS(&tmp,"%S %d %d:%d:%d %d",mon,day,hr,min,sec,yr);
3964     ajStrDel(&mon);
3965 
3966     p = strptime(ajStrGetPtr(tmp),"%B %d %T %Y",&tm);
3967     ajStrDel(&tmp);
3968 
3969     if(!p)
3970 	return 0;
3971 #else /* __ppc__ */
3972     i = 0;
3973     while(i<=11)
3974     {
3975 	if(!strcmp(ajStrGetPtr(mon),ms[i]))
3976 	    break;
3977 	++i;
3978     }
3979     if(i==12)
3980 	i=11;
3981 
3982     tm.tm_mon    = i;
3983     tm.tm_mday   = day;
3984     tm.tm_sec    = sec;
3985     tm.tm_min    = min;
3986     tm.tm_hour   = hr;
3987     tm.tm_year   = yr - 1900;
3988     tm.tm_isdst  = 0;
3989     tm.tm_gmtoff = 0;
3990     tm.tm_zone = jtz;
3991 #endif /* __ppc__ */
3992 
3993     return mktime(&tm);
3994 }
3995 
3996 
3997 
3998 
3999 /* @funcstatic jembossctl_date ************************************************
4000 **
4001 ** Date comparison for ajListSort
4002 **
4003 ** @param [r] str1 [const void*] date string
4004 ** @param [r] str2 [const void*] date string
4005 **
4006 ** @return [int] comparison
4007 ** @@
4008 ******************************************************************************/
4009 
jembossctl_date(const void * str1,const void * str2)4010 static int jembossctl_date(const void* str1, const void* str2)
4011 {
4012     AjPStr a;
4013     AjPStr b;
4014 
4015     a = *(AjPStr const *)str1;
4016     b = *(AjPStr const *)str2;
4017 
4018     return (int)(jembossctl_Datestr(b) - jembossctl_Datestr(a));
4019 }
4020 
4021 
4022 
4023 
4024 /* @funcstatic jembossctl_GetSeqFromUsa ***************************************
4025 **
4026 ** Return a sequence given a USA
4027 **
4028 ** @param [r] thys [const AjPStr] usa
4029 ** @param [w] seq [AjPSeq*] sequence
4030 ** @return [AjBool] ajTrue on success
4031 ******************************************************************************/
4032 
jembossctl_GetSeqFromUsa(const AjPStr thys,AjPSeq * seq)4033 static AjBool jembossctl_GetSeqFromUsa(const AjPStr thys, AjPSeq *seq)
4034 {
4035     AjPSeqin seqin;
4036     AjBool ok;
4037 
4038     ajNamInit("emboss");
4039 
4040     seqin = ajSeqinNew();
4041     seqin->Input->Multi = ajFalse;
4042     seqin->Input->Text  = ajFalse;
4043 
4044     ajSeqinUsa (&seqin, thys);
4045     ok = ajSeqRead(*seq, seqin);
4046     ajSeqinDel (&seqin);
4047 
4048     if(!ok)
4049 	return ajFalse;
4050 
4051     return ajTrue;
4052 }
4053 
4054 
4055 
4056 
4057 /* @funcstatic jembossctl_GetSeqsetFromUsa ************************************
4058 **
4059 ** Return a seqset given a usa
4060 **
4061 ** @param [r] thys [const AjPStr] usa
4062 ** @param [w] seq [AjPSeqset*] seqset
4063 ** @return [AjBool] ajTrue on success
4064 ******************************************************************************/
4065 
jembossctl_GetSeqsetFromUsa(const AjPStr thys,AjPSeqset * seq)4066 static AjBool jembossctl_GetSeqsetFromUsa(const AjPStr thys, AjPSeqset *seq)
4067 {
4068     AjPSeqin seqin;
4069     AjBool ok;
4070 
4071     ajNamInit("emboss");
4072 
4073     seqin = ajSeqinNew();
4074     seqin->Input->Multi = ajTrue;
4075     seqin->Input->Text  = ajFalse;
4076 
4077     ajSeqinUsa (&seqin, thys);
4078     ok = ajSeqsetRead(*seq, seqin);
4079     ajSeqinDel (&seqin);
4080 
4081     if(!ok)
4082 	return ajFalse;
4083 
4084     return ajTrue;
4085 }
4086 
4087 
4088 
4089 
4090 #else /* !HAVE_JAVA */
4091 
4092 #include <stdio.h>
4093 
4094 
4095 
4096 
4097 /* @header main ***************************************************************
4098 **
4099 ******************************************************************************/
main(void)4100 int main(void)
4101 {
4102     exit(-1);
4103 }
4104 
4105 #endif /* !HAVE_JAVA */
4106