1 /*
2  * $Id: main.c,v 1.10 2003/02/16 12:43:37 isizaka Exp isizaka $
3  *
4  * This file is part of "Ngraph for X11".
5  *
6  * Copyright (C) 2002, Satoshi ISHIZAKA. isizaka@msa.biglobe.ne.jp
7  *
8  * "Ngraph for X11" is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * "Ngraph for X11" 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
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21  *
22  */
23 
24 /**
25  *
26  * $Log: main.c,v $
27  * Revision 1.10  2003/02/16 12:43:37  isizaka
28  * for release 6.13.18
29  *
30  * Revision 1.9  2002/07/06 08:57:25  isizaka
31  * change to GPL.
32  *
33  * Revision 1.8  2001/03/23 12:17:43  isizaka
34  * for 6.3.13
35  *
36  * Revision 1.7  1999/07/31 11:12:30  isizaka
37  * about stderr
38  *
39  * Revision 1.6  1999/05/31 10:33:13  isizaka
40  * for release 6.03.03
41  *
42  * Revision 1.5  1999/05/08 13:31:30  isizaka
43  * for release 6.03.02
44  *
45  * Revision 1.4  1999/04/15 12:14:26  isizaka
46  * for release 6.03.01
47  *
48  * Revision 1.3  1999/04/11 06:08:57  isizaka
49  * *** empty log message ***
50  *
51  * Revision 1.2  1999/03/20 12:32:54  isizaka
52  * minor change
53  *
54  * Revision 1.1  1999/03/17 13:27:48  isizaka
55  * Initial revision
56  *
57  *
58  **/
59 
60 #include <Xm/XmAll.h>
61 #include <sys/stat.h>
62 #include <sys/types.h>
63 #include <stdio.h>
64 #include <stdlib.h>
65 #include <string.h>
66 #include <fcntl.h>
67 #include <unistd.h>
68 #include <stdarg.h>
69 
70 #include "ngraph.h"
71 #include "object.h"
72 #include "ioutil.h"
73 #include "nstring.h"
74 #include "config.h"
75 
76 #define TRUE  1
77 #define FALSE 0
78 
79 #define SYSCONF "[Ngraph]"
80 #ifndef LIBDIR
81 #define LIBDIR "/usr/local/lib/Ngraph"
82 #endif
83 
84 int consolecol=80;
85 int consolerow=25;
86 
87 
88 char **mainenviron;
89 char *systemname;
90 int consolefdout;
91 int consolefdin;
92 int consoleac=FALSE;
93 
94 void *addobjectroot(void);
95 void *addint(void);
96 void *adddouble(void);
97 void *addstring(void);
98 void *addiarray(void);
99 void *adddarray(void);
100 void *addsarray(void);
101 void *addsystem(void);
102 void *addshell(void);
103 void *adddraw(void);
104 void *addfile(void);
105 void *addmath(void);
106 void *addfit(void);
107 void *addgra(void);
108 void *addgra2(void);
109 void *addgra2null(void);
110 void *addgra2file(void);
111 void *addgra2prn(void);
112 void *addmerge(void);
113 void *addlegend(void);
114 void *addline(void);
115 void *addcurve(void);
116 void *addrectangle(void);
117 void *addarc(void);
118 void *addpolygon(void);
119 void *addmark(void);
120 void *addtext(void);
121 void *addaxis(void);
122 void *addagrid(void);
123 void *addprm(void);
124 
125 void *addgra2x11(void);
126 void *addmenu(void);
127 void *adddialog(void);
128 
129 void resizeconsole(int col,int row);
130 
131 XtAppContext Application=NULL;
132 Display *Disp=NULL;
133 char *AppName="Ngraph";
134 char *AppClass="Ngraph";
135 extern Widget TopLevel;
136 static String fallbacks[] = {
137   "Ngraph*title: Ngraph",
138   NULL
139 };
140 
Xerrorhandler(Display * d,XErrorEvent * e)141 int Xerrorhandler(Display *d,XErrorEvent *e)
142 {
143   char buf[256];
144 
145   XGetErrorText(d,e->error_code,buf,sizeof(buf));
146   fprintf(stderr,"%s\n",buf);
147   return 0;
148 }
149 
OpenApplication()150 int OpenApplication()
151 {
152   int argc;
153   char *argv[2];
154 
155   if (Application==NULL) {
156     XtToolkitInitialize();
157     Application=XtCreateApplicationContext();
158     XtSetLanguageProc(NULL,NULL,NULL);
159     XtAppSetFallbackResources(Application,fallbacks);
160   }
161   if (Disp==NULL) {
162     argc=1;
163     argv[0]="Ngraph";
164     argv[1]="NULL";
165     Disp=XtOpenDisplay(Application,NULL,AppName,AppClass,NULL,0,&argc,argv);
166     if (Disp==NULL) {
167       fprintf(stderr,"Cannot open display.\n");
168       return FALSE;
169     }
170     XSetErrorHandler(Xerrorhandler);
171   }
172   return TRUE;
173 }
174 
putconsole(char * s)175 int putconsole(char *s)
176 {
177   int len;
178 
179   len=strlen(s);
180   write(consolefdout,s,len);
181   write(consolefdout,"\n",1);
182   return len+1;
183 }
184 
printfconsole(char * fmt,...)185 int printfconsole(char *fmt,...)
186 {
187   int len;
188   char buf[1024];
189   va_list ap;
190 
191   va_start(ap,fmt);
192   len=vsprintf(buf,fmt,ap);
193   va_end(ap);
194   write(consolefdout,buf,len);
195   return len;
196 }
197 
interruptconsole(void)198 int interruptconsole(void)
199 {
200   return FALSE;
201 }
202 
inputynconsole(char * mes)203 int inputynconsole(char *mes)
204 {
205   int len;
206   char buf[10];
207 
208   len=strlen(mes);
209   write(consolefdout,mes,len);
210   do {
211     read(consolefdin,buf,1);
212   } while ((buf[0]!='y') && (buf[0]!='Y') && (buf[0]!='n') && (buf[0]!='N'));
213   if ((buf[0]=='y') || (buf[0]=='Y')) return TRUE;
214   return FALSE;
215 }
216 
displaydialogconsole(char * str)217 void displaydialogconsole(char *str)
218 {
219   putconsole(str);
220 }
221 
displaystatusconsole(char * str)222 void displaystatusconsole(char *str)
223 {
224 }
225 
226 char *terminal=NULL;
227 struct savedstdio consolesave;
228 int consolefd[3];
229 int pipefd=-1;
230 pid_t consolepid=-1;
231 
resizeconsole(int col,int row)232 void resizeconsole(int col,int row)
233 {
234 }
235 
nallocconsole()236 int nallocconsole()
237 {
238   int fd[3],fdi[2],fdo[2],len,i;
239   pid_t pid;
240   char buf[256],ttyname[256];
241   char *s,*s2;
242   char **argv;
243   struct objlist *sys;
244   char *sysname;
245   char *version;
246 
247   if (consoleac) return FALSE;
248   if (terminal==NULL) return FALSE;
249   if (pipe(fdi)==-1) return FALSE;
250   if (pipe(fdo)==-1) {
251     close(fdi[0]);
252     close(fdi[1]);
253     return FALSE;
254   }
255   if ((pid=fork())==-1) {
256     close(fdi[0]);
257     close(fdi[1]);
258     close(fdo[0]);
259     close(fdo[1]);
260     return FALSE;
261   } else if (pid==0) {
262     sprintf(buf,"%s %d %d %d %d",terminal,fdi[0],fdi[1],fdo[0],fdo[1]);
263     argv=NULL;
264     s=buf;
265     while ((s2=getitok2(&s,&len," \t"))!=NULL) {
266       arg_add(&argv,s2);
267     }
268     execvp(argv[0],argv);
269     exit(1);
270   }
271   close(fdi[1]);
272   close(fdo[0]);
273   sys=chkobject("system");
274   getobj(sys,"name",0,0,NULL,&sysname);
275   getobj(sys,"version",0,0,NULL,&version);
276   sprintf(buf,"%c]2;Ngraph shell%c%s version %s. Script interpreter.\n",
277                0x1b,0x07,sysname,version);
278   write(fdo[1],buf,strlen(buf)+1);
279   pipefd=fdo[1];
280   consolepid=pid;
281   i=0;
282   while ((read(fdi[0],buf,1)==1) && (buf[0]!='\0')) {
283     ttyname[i]=buf[0];
284     i++;
285   }
286   ttyname[i]='\0';
287   close(fdi[0]);
288   if (i==0) return FALSE;
289   fd[0]=open(ttyname,O_RDONLY);
290   fd[1]=open(ttyname,O_WRONLY);
291   fd[2]=open(ttyname,O_WRONLY);
292   consolefd[0]=dup(0);
293   close(0);
294   dup2(fd[0],0);
295   consolefd[1]=dup(1);
296   close(1);
297   dup2(fd[1],1);
298   consolefd[2]=dup(2);
299   close(2);
300   dup2(fd[2],2);
301   close(fd[0]);
302   close(fd[1]);
303   close(fd[2]);
304   consolefdin=dup(0);
305   consolefdout=dup(2);
306   consoleac=TRUE;
307   savestdio(&consolesave);
308   putstderr=putconsole;
309   printfstderr=printfconsole;
310   ninterrupt=interruptconsole;
311   inputyn=inputynconsole;
312   ndisplaydialog=displaydialogconsole;
313   ndisplaystatus=displaystatusconsole;
314   return TRUE;
315 }
316 
nfreeconsole()317 void nfreeconsole()
318 {
319   char buf[1];
320 
321   if (consoleac) {
322     close(0);
323     if (consolefd[0]!=-1) {
324       dup2(consolefd[0],0);
325       close(consolefd[0]);
326     }
327     close(1);
328     if (consolefd[1]!=-1) {
329       dup2(consolefd[1],1);
330       close(consolefd[1]);
331     }
332     close(2);
333     if (consolefd[2]!=-1) {
334       dup2(consolefd[2],2);
335       close(consolefd[2]);
336     }
337     buf[0]='\0';
338     write(pipefd,buf,1);
339     close(pipefd);
340     pipefd=-1;
341     consolepid=-1;
342     close(consolefdin);
343     close(consolefdout);
344     consolefdin=0;
345     consolefdout=2;
346     consoleac=FALSE;
347     loadstdio(&consolesave);
348   }
349 }
350 
nforegroundconsole()351 void nforegroundconsole()
352 {
353 }
354 
main(int argc,char ** argv,char ** environ)355 int main(int argc,char **argv,char **environ)
356 {
357   char *homedir,*libdir,*home,*lib,*inifile,*loginshell;
358   char *inst;
359   struct objlist *sys,*obj,*lobj;
360   int i,id;
361   char *sarg[2];
362   struct narray sarray;
363   FILE *fp;
364   char *tok,*str,*s2;
365   char *f1,*endptr;
366   int len,val;
367   int allocnow,allocconsole;
368   struct narray iarray;
369   char *arg;
370 
371   mainenviron=environ;
372 
373   ignorestdio(NULL);
374   inputyn=vinputyn;
375   ninterrupt=vinterrupt;
376   printfstderr=seprintf;
377   putstderr=seputs;
378   consolefdin=0;
379   consolefdout=2;
380 
381   if ((lib=getenv("NGRAPHLIB"))!=NULL) {
382     if ((libdir=(char *)memalloc(strlen(lib)+1))==NULL) exit(1);
383     strcpy(libdir,lib);
384   } else {
385     if ((libdir=(char *)memalloc(strlen(LIBDIR)+1))==NULL) exit(1);
386     strcpy(libdir,LIBDIR);
387   }
388   if ((home=getenv("NGRAPHHOME"))!=NULL) {
389     if ((homedir=(char *)memalloc(strlen(home)+1))==NULL) exit(1);
390     strcpy(homedir,home);
391   } else if ((home=getenv("HOME"))!=NULL) {
392     if ((homedir=(char *)memalloc(strlen(home)+1))==NULL) exit(1);
393     strcpy(homedir,home);
394   } else {
395     if ((homedir=(char *)memalloc(strlen(libdir)+1))==NULL) exit(1);
396     strcpy(homedir,libdir);
397   }
398 
399   if (addobjectroot()==NULL) exit(1);
400   if (addsystem()==NULL) exit(1);
401 
402   newobj(getobject("system"));
403   if ((sys=getobject("system"))==NULL) exit(1);
404   inst=chkobjinst(sys,0);
405   if (_putobj(sys,"lib_dir",inst,libdir)) exit(1);
406   if (_putobj(sys,"home_dir",inst,homedir)) exit(1);
407   if (_getobj(sys,"lib_dir",inst,&libdir)==-1) exit(1);
408   if (_getobj(sys,"home_dir",inst,&homedir)==-1) exit(1);
409   if (_getobj(sys,"name",inst,&systemname)==-1) exit(1);
410 
411   if (addshell()==NULL) exit(1);
412 
413   if (addgra()==NULL) exit(1);
414   if (addgra2()==NULL) exit(1);
415   if (addgra2null()==NULL) exit(1);
416   if (addgra2file()==NULL) exit(1);
417   if (addgra2prn()==NULL) exit(1);
418 
419   if (addgra2x11()==NULL) exit(1);
420 
421   if (addint()==NULL) exit(1);
422   if (adddouble()==NULL) exit(1);
423   if (addstring()==NULL) exit(1);
424   if (addiarray()==NULL) exit(1);
425   if (adddarray()==NULL) exit(1);
426   if (addsarray()==NULL) exit(1);
427   if (addmath()==NULL) exit(1);
428   if (addfit()==NULL) exit(1);
429   if (addprm()==NULL) exit(1);
430 
431   if (adddraw()==NULL) exit(1);
432   if (addagrid()==NULL) exit(1);
433   if (addaxis()==NULL) exit(1);
434   if (addfile()==NULL) exit(1);
435   if (addmerge()==NULL) exit(1);
436   if (addlegend()==NULL) exit(1);
437   if (addrectangle()==NULL) exit(1);
438   if (addline()==NULL) exit(1);
439   if (addcurve()==NULL) exit(1);
440   if (addarc()==NULL) exit(1);
441   if (addpolygon()==NULL) exit(1);
442   if (addmark()==NULL) exit(1);
443   if (addtext()==NULL) exit(1);
444 
445   if (addmenu()==NULL) exit(1);
446   if (adddialog()==NULL) exit(1);
447 
448   loginshell=NULL;
449   if ((fp=openconfig(SYSCONF))!=NULL) {
450      while ((tok=getconfig(fp,&str))!=NULL) {
451       s2=str;
452       if (strcmp(tok,"login_shell")==0) {
453         f1=getitok2(&s2,&len," \t,");
454         if (_putobj(sys,"login_shell",inst,f1)) exit(1);
455       } else if (strcmp(tok,"create_object")==0) {
456         while ((f1=getitok2(&s2,&len," \t,"))!=NULL) {
457           newobj(getobject(f1));
458           memfree(f1);
459         }
460       } else if (strcmp(tok,"alloc_console")==0) {
461         f1=getitok2(&s2,&len," \t,");
462         val=strtol(f1,&endptr,10);
463         if (endptr[0]=='\0') {
464           if (val==0) allocconsole=FALSE;
465           else allocconsole=TRUE;
466         }
467         memfree(f1);
468       } else if (strcmp(tok,"console_size")==0) {
469         f1=getitok2(&s2,&len," \x09,");
470         val=strtol(f1,&endptr,10);
471         if (endptr[0]=='\0') consolecol=val;
472         memfree(f1);
473         f1=getitok2(&s2,&len," \x09,");
474         val=strtol(f1,&endptr,10);
475         if (endptr[0]=='\0') consolerow=val;
476         memfree(f1);
477       } else if (strcmp(tok,"terminal")==0) {
478         terminal=getitok2(&s2,&len,"");
479       }
480       memfree(tok);
481       memfree(str);
482     }
483     closeconfig(fp);
484   }
485 
486   putstderr=putconsole;
487   printfstderr=printfconsole;
488   inputyn=inputynconsole;
489   ndisplaydialog=displaydialogconsole;
490   ndisplaystatus=displaystatusconsole;
491   if (allocconsole) nallocconsole();
492   if (isatty(0) && isatty(1) && isatty(2)) {
493     consoleac=TRUE;
494     if (!allocconsole) {
495       consolefdin=dup(0);
496       consolefdout=dup(2);
497     }
498   } else consoleac=FALSE;
499 
500   inifile=NULL;
501   id=newobj((obj=getobject("shell")));
502   for (i=1;i<argc;i++) {
503     if (argv[i][0]=='-') {
504       if (argv[i][1]=='i') {
505         i++;
506         if (i<argc) {
507           if ((inifile=(char *)memalloc(strlen(argv[i])+1))==NULL) exit(1);
508           strcpy(inifile,argv[i]);
509           changefilename(inifile);
510         } else break;
511       } else break;
512     } else break;
513   }
514   if (inifile==NULL) {
515     if (findfilename(homedir,CONFTOP,systemname))
516       inifile=getfilename(homedir,CONFTOP,systemname);
517     else if (findfilename(libdir,CONFTOP,systemname))
518       inifile=getfilename(libdir,CONFTOP,systemname);
519   }
520   if (inifile!=NULL) {
521     arrayinit(&sarray,sizeof(char *));
522     if (arrayadd(&sarray,&inifile)==NULL) exit(1);
523     for (;i<argc;i++)
524       if (arrayadd(&sarray,&(argv[i]))==NULL) exit(1);
525     sarg[0]=(char *)&sarray;
526     sarg[1]=NULL;
527     exeobj(obj,"shell",id,1,sarg);
528     arraydel(&sarray);
529     memfree(inifile);
530   }
531   if (getobj(sys,"login_shell",0,0,NULL,&loginshell)) exit(1);
532   do {
533     if (_putobj(sys,"login_shell",inst,NULL)) exit(1);
534     if (loginshell==NULL) {
535       allocnow=nallocconsole();
536       exeobj(obj,"shell",id,0,NULL);
537       if (allocnow) nfreeconsole();
538     } else {
539       arrayinit(&iarray,sizeof(int));
540       arg=loginshell;
541       if (getobjilist2(&arg,&lobj,&iarray,TRUE)) return -1;
542       arraydel(&iarray);
543       if (lobj==obj) allocnow=nallocconsole();
544       else allocnow=FALSE;
545       sexeobj(loginshell);
546       if (allocnow) nfreeconsole();
547     }
548     memfree(loginshell);
549     if (getobj(sys,"login_shell",0,0,NULL,&loginshell)) exit(1);
550   } while (loginshell!=NULL);
551   if (consoleac && (consolepid!=-1)) nfreeconsole();
552   memfree(terminal);
553   delobj(getobject("system"),0);
554   return 0;
555 }
556