1 
2 /******************************************************************************
3 * MODULE     : init_texmacs.cpp
4 * DESCRIPTION: Initialization of TeXmacs
5 * COPYRIGHT  : (C) 1999  Joris van der Hoeven
6 *******************************************************************************
7 * This software falls under the GNU general public license version 3 or later.
8 * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
9 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
10 ******************************************************************************/
11 
12 #include "boot.hpp"
13 #include "file.hpp"
14 #include "sys_utils.hpp"
15 #include "analyze.hpp"
16 #include "convert.hpp"
17 #include "merge_sort.hpp"
18 #include "drd_std.hpp"
19 #include "language.hpp"
20 #include <unistd.h>
21 #ifdef __MINGW32__
22 #include <time.h>
23 #endif
24 
25 tree texmacs_settings = tuple ();
26 int  install_status   = 0;
27 bool use_which        = false;
28 bool use_locate       = false;
29 
30 extern void setup_tex (); // from Plugins/Metafont/tex_init.cpp
31 extern void init_tex  (); // from Plugins/Metafont/tex_init.cpp
32 
33 /******************************************************************************
34 * Subroutines for paths
35 ******************************************************************************/
36 
37 static url
get_env_path(string which)38 get_env_path (string which) {
39   return url ("$" * which);
40 }
41 
42 static void
set_env_path(string which,url val)43 set_env_path (string which, url val) {
44   //cout << which << " := " << val << "\n";
45   if ((!is_none (val)) && (val->t != ""))
46     set_env (which, as_string (val));
47 }
48 
49 static url
get_env_path(string which,url def)50 get_env_path (string which, url def) {
51   url val= get_env_path (which);
52   if (is_none (val) || (val->t == "")) {
53     set_env_path (which, def);
54     return def;
55   }
56   return val;
57 }
58 
59 static url
plugin_path(string which)60 plugin_path (string which) {
61   url base= "$TEXMACS_HOME_PATH:/etc/TeXmacs:$TEXMACS_PATH:/usr/share/TeXmacs";
62   url search= base * "plugins" * url_wildcard ("*") * which;
63   return expand (complete (search, "r"));
64 }
65 
66 scheme_tree
plugin_list()67 plugin_list () {
68   bool flag;
69   array<string> a= read_directory ("$TEXMACS_PATH/plugins", flag);
70   a << read_directory ("/etc/TeXmacs/plugins", flag);
71   a << read_directory ("$TEXMACS_HOME_PATH/plugins", flag);
72   a << read_directory ("/usr/share/TeXmacs/plugins", flag);
73   merge_sort (a);
74   int i, n= N(a);
75   tree t (TUPLE);
76   for (i=0; i<n; i++)
77     if ((a[i] != ".") && (a[i] != "..") && ((i==0) || (a[i] != a[i-1])))
78       t << a[i];
79   return t;
80 }
81 
82 /******************************************************************************
83 * Initialize main paths
84 ******************************************************************************/
85 
86 static void
init_main_paths()87 init_main_paths () {
88 #ifdef __MINGW32__
89   if (is_none (get_env_path ("TEXMACS_HOME_PATH", get_env ("APPDATA") * "/TeXmacs"))) {
90 #else
91   if (is_none (get_env_path ("TEXMACS_HOME_PATH", "~/.TeXmacs"))) {
92 #endif
93     boot_error << "\n";
94     boot_error << "Installation problem: please send a bug report.\n";
95     boot_error << "'TEXMACS_HOME_PATH' could not be set to '~/.TeXmacs'.\n";
96     boot_error << "You may try to set this environment variable manually\n";
97     boot_error << "\n";
98     FAILED ("installation problem");
99     exit (1);
100   }
101 }
102 
103 /******************************************************************************
104 * Directory for temporary files
105 ******************************************************************************/
106 
107 static string main_tmp_dir= "$TEXMACS_HOME_PATH/system/tmp";
108 
109 static void
110 make_dir (url which) {
111   if (!is_directory (which)) {
112     make_dir (head (which));
113     mkdir (which);
114   }
115 }
116 
117 static url
118 url_temp_dir_sub () {
119 #ifdef __MINGW32__
120   static url tmp_dir=
121     url_system (main_tmp_dir) * url_system (as_string (time (NULL)));
122 #else
123   static url tmp_dir=
124     url_system (main_tmp_dir) * url_system (as_string ((int) getpid ()));
125 #endif
126   return (tmp_dir);
127 }
128 
129 url
130 url_temp_dir () {
131   static url u;
132   if (u == url_none()) {
133     u= url_temp_dir_sub ();
134     make_dir (u);
135   }
136   return u;
137 }
138 
139 bool
140 process_running (int pid) {
141   string cmd= "ps -p " * as_string (pid);
142   string ret= eval_system (cmd);
143   return occurs ("texmacs", ret) && occurs (as_string (pid), ret);
144 }
145 
146 static void
147 clean_temp_dirs () {
148   bool err= false;
149   array<string> a= read_directory (main_tmp_dir, err);
150 #ifndef __MINGW32__
151   for (int i=0; i<N(a); i++)
152     if (is_int (a[i]))
153       if (!process_running (as_int (a[i])))
154         if (a[i] != as_string ((int) getpid ()))
155           system ("rm -rf", url (main_tmp_dir) * url (a[i]));
156 #else
157   /* delete the directories after 7 days */
158   time_t ts = as_int (basename (url_temp_dir_sub ())) - (3600 * 24 * 7 );
159   for (int i=0; i<N(a); i++)
160     if (is_int (a[i])) {
161       time_t td= as_int (a[i]);
162       if (td < ts) {
163         url cur = url (main_tmp_dir) * url (a[i]);
164         array<string> f= read_directory (cur, err);
165         for (int j=0; j<N(f); j++) remove (cur * url (f[j]));
166         _rmdir (as_charp (as_string (cur)));
167       }
168     }
169 #endif
170 }
171 
172 /******************************************************************************
173 * Make user directories
174 ******************************************************************************/
175 
176 static void
177 init_user_dirs () {
178   make_dir ("$TEXMACS_HOME_PATH");
179   make_dir ("$TEXMACS_HOME_PATH/bin");
180   make_dir ("$TEXMACS_HOME_PATH/doc");
181   make_dir ("$TEXMACS_HOME_PATH/doc/about");
182   make_dir ("$TEXMACS_HOME_PATH/doc/about/changes");
183   make_dir ("$TEXMACS_HOME_PATH/fonts");
184   make_dir ("$TEXMACS_HOME_PATH/fonts/enc");
185   make_dir ("$TEXMACS_HOME_PATH/fonts/error");
186   make_dir ("$TEXMACS_HOME_PATH/fonts/pk");
187   make_dir ("$TEXMACS_HOME_PATH/fonts/tfm");
188   make_dir ("$TEXMACS_HOME_PATH/fonts/truetype");
189   make_dir ("$TEXMACS_HOME_PATH/fonts/type1");
190   make_dir ("$TEXMACS_HOME_PATH/fonts/unpacked");
191   make_dir ("$TEXMACS_HOME_PATH/fonts/virtual");
192   make_dir ("$TEXMACS_HOME_PATH/langs");
193   make_dir ("$TEXMACS_HOME_PATH/langs/mathematical");
194   make_dir ("$TEXMACS_HOME_PATH/langs/mathematical/syntax");
195   make_dir ("$TEXMACS_HOME_PATH/langs/natural");
196   make_dir ("$TEXMACS_HOME_PATH/langs/natural/dic");
197   make_dir ("$TEXMACS_HOME_PATH/langs/natural/hyphen");
198   make_dir ("$TEXMACS_HOME_PATH/langs/programming");
199   make_dir ("$TEXMACS_HOME_PATH/misc");
200   make_dir ("$TEXMACS_HOME_PATH/misc/patterns");
201   make_dir ("$TEXMACS_HOME_PATH/misc/pixmaps");
202   make_dir ("$TEXMACS_HOME_PATH/packages");
203   make_dir ("$TEXMACS_HOME_PATH/plugins");
204   make_dir ("$TEXMACS_HOME_PATH/progs");
205   make_dir ("$TEXMACS_HOME_PATH/server");
206   make_dir ("$TEXMACS_HOME_PATH/styles");
207   make_dir ("$TEXMACS_HOME_PATH/system");
208   make_dir ("$TEXMACS_HOME_PATH/system/bib");
209   make_dir ("$TEXMACS_HOME_PATH/system/cache");
210   make_dir ("$TEXMACS_HOME_PATH/system/database");
211   make_dir ("$TEXMACS_HOME_PATH/system/database/bib");
212   make_dir ("$TEXMACS_HOME_PATH/system/tmp");
213   make_dir ("$TEXMACS_HOME_PATH/texts");
214   make_dir ("$TEXMACS_HOME_PATH/users");
215   change_mode ("$TEXMACS_HOME_PATH/server", 7 << 6);
216   change_mode ("$TEXMACS_HOME_PATH/system", 7 << 6);
217   change_mode ("$TEXMACS_HOME_PATH/users", 7 << 6);
218   clean_temp_dirs ();
219 }
220 
221 /******************************************************************************
222 * Detection of guile
223 ******************************************************************************/
224 
225 static void
226 init_guile () {
227   url guile_path= "$TEXMACS_PATH/progs:$GUILE_LOAD_PATH";
228   if (!exists (guile_path * "init-texmacs.scm")) {
229     boot_error << "\n";
230     boot_error << "Installation problem: please send a bug report.\n";
231     boot_error << "The initialization file init-texmacs.scm"
232                << " could not be found.\n";
233     boot_error << "Please check the values of the environment variables\n";
234     boot_error << "TEXMACS_PATH and GUILE_LOAD_PATH."
235                << " init-texmacs.scm should\n";
236     boot_error << "be readable and in the directory $TEXMACS_PATH/progs\n";
237     boot_error << "or in the directory $GUILE_LOAD_PATH\n";
238     boot_error << "\n";
239     FAILED ("guile could not be found");
240   }
241 
242   /*
243   if (!exists ("$GUILE_LOAD_PATH/ice-9/boot-9.scm")) {
244     int i;
245     string guile_data    = var_eval_system ("guile-config info datadir");
246     string guile_version = var_eval_system ("guile --version");
247     for (i=0; i<N(guile_version); i++)
248       if (guile_version[i] == '\n') break;
249     guile_version= guile_version (0, i);
250     for (i=N(guile_version); i>0; i--)
251       if (guile_version[i-1] == ' ') break;
252     guile_version= guile_version (i, N (guile_version));
253     if (guile_version == "") {
254       var_eval_system ("guile-config info top_srcdir");
255       for (i=N(guile_version); i>0; i--)
256 	if (guile_version[i-1] == '-') break;
257       guile_version= guile_version (i, N (guile_version));
258       for (i=0; i<N(guile_version); i++)
259 	if ((guile_version[i] == '/') || (guile_version[i] == '\\')) {
260 	  guile_version= guile_version (0, i);
261 	  break;
262 	}
263     }
264     url guile_dir= url_system (guile_data) * url ("guile", guile_version);
265     guile_path= guile_path | guile_dir;
266     set_env_path ("GUILE_LOAD_PATH", guile_path);
267     if (!exists ("$GUILE_LOAD_PATH/ice-9/boot-9.scm")) {
268       failed_error << "\nGUILE_LOAD_PATH=" << guile_path << "\n";
269       FAILED ("guile seems not to be installed on your system");
270     }
271   }
272   */
273 
274   guile_path= guile_path | "$TEXMACS_HOME_PATH/progs" | plugin_path ("progs");
275   set_env_path ("GUILE_LOAD_PATH", guile_path);
276 }
277 
278 /******************************************************************************
279 * Set additional environment variables
280 ******************************************************************************/
281 
282 static void
283 init_env_vars () {
284   // Handle binary, library and guile paths for plugins
285   url bin_path= get_env_path ("PATH") | plugin_path ("bin");
286   set_env_path ("PATH", bin_path);
287   url lib_path= get_env_path ("LD_LIBRARY_PATH") | plugin_path ("lib");
288   set_env_path ("LD_LIBRARY_PATH", lib_path);
289 
290   // Get TeXmacs style and package paths
291   url style_root=
292     get_env_path ("TEXMACS_STYLE_ROOT",
293 		  "$TEXMACS_HOME_PATH/styles:$TEXMACS_PATH/styles" |
294 		  plugin_path ("styles"));
295   url package_root=
296     get_env_path ("TEXMACS_PACKAGE_ROOT",
297 		  "$TEXMACS_HOME_PATH/packages:$TEXMACS_PATH/packages" |
298 		  plugin_path ("packages"));
299   url all_root= style_root | package_root;
300   url style_path=
301     get_env_path ("TEXMACS_STYLE_PATH",
302                   search_sub_dirs (all_root));
303   url text_root=
304     get_env_path ("TEXMACS_TEXT_ROOT",
305 		  "$TEXMACS_HOME_PATH/texts:$TEXMACS_PATH/texts" |
306 		  plugin_path ("texts"));
307   url text_path=
308     get_env_path ("TEXMACS_TEXT_PATH",
309                   search_sub_dirs (text_root));
310 
311   // Get other data paths
312   (void) get_env_path ("TEXMACS_FILE_PATH",text_path | style_path);
313   (void) set_env_path ("TEXMACS_DOC_PATH",
314 		       get_env_path ("TEXMACS_DOC_PATH") |
315 		       "$TEXMACS_HOME_PATH/doc:$TEXMACS_PATH/doc" |
316 		       plugin_path ("doc"));
317   (void) set_env_path ("TEXMACS_SECURE_PATH",
318 		       get_env_path ("TEXMACS_SECURE_PATH") |
319 		       "$TEXMACS_PATH:$TEXMACS_HOME_PATH");
320   (void) get_env_path ("TEXMACS_PATTERN_PATH",
321 		       "$TEXMACS_HOME_PATH/misc/patterns" |
322 		       url ("$TEXMACS_PATH/misc/patterns") |
323 		       plugin_path ("misc/patterns"));
324   (void) get_env_path ("TEXMACS_PIXMAP_PATH",
325 		       "$TEXMACS_HOME_PATH/misc/pixmaps" |
326 		       url ("$TEXMACS_PATH/misc/pixmaps/modern/32x32/settings") |
327 		       url ("$TEXMACS_PATH/misc/pixmaps/modern/32x32/table") |
328 		       url ("$TEXMACS_PATH/misc/pixmaps/modern/24x24/main") |
329 		       url ("$TEXMACS_PATH/misc/pixmaps/modern/20x20/mode") |
330 		       url ("$TEXMACS_PATH/misc/pixmaps/modern/16x16/focus") |
331 		       url ("$TEXMACS_PATH/misc/pixmaps/traditional/--x17") |
332 		       plugin_path ("misc/pixmaps"));
333   (void) get_env_path ("TEXMACS_DIC_PATH",
334 		       "$TEXMACS_HOME_PATH/langs/natural/dic" |
335 		       url ("$TEXMACS_PATH/langs/natural/dic") |
336 		       plugin_path ("langs/natural/dic"));
337 #ifdef OS_WIN32
338   set_env ("TEXMACS_SOURCE_PATH", "");
339 #else
340   set_env ("TEXMACS_SOURCE_PATH", TEXMACS_SOURCES);
341 #endif
342 }
343 
344 /******************************************************************************
345 * Miscellaneous initializations
346 ******************************************************************************/
347 
348 static void
349 init_misc () {
350   // Test whether 'which' works
351 #if defined(__MINGW__) || defined(__MINGW32__) || defined (OS_WIN32)
352   use_which = false;
353 #else
354   use_which = (var_eval_system ("which texmacs 2> /dev/null") != "");
355 #endif
356   //string loc= var_eval_system ("locate bin/locate 2> /dev/null");
357   //use_locate= (search_forwards ("bin/locate", loc) > 0);
358 
359   // Set extra environment variables for Cygwin
360 #ifdef OS_CYGWIN
361   set_env ("CYGWIN", "check_case:strict");
362   set_env ("COMSPEC", "");
363   set_env ("ComSpec", "");
364 #endif
365 
366 }
367 
368 static void
369 setup_inkscape_extension () {
370 debug_boot << "attempt install of inkscape extension \n ";
371 #if defined(__MINGW__) || defined(__MINGW32__) || defined (OS_WIN32)
372   url ink_ext = url ("$APPDATA/inkscape/extensions");
373 #else
374   url ink_ext = "~/.config/inkscape/extensions/";
375 #endif
376   if ( exists (ink_ext)) {
377     url f1 = url (ink_ext * "texmacs.inx");
378     url f2 = url (ink_ext * "texmacs_reedit.py");
379     url f3 = url (ink_ext * "texmacs_latex.sty");
380     url plug_source = url ("$TEXMACS_PATH/misc/inkscape_extension/");
381     debug_boot << "installing or updating inkscape extension\n";
382     copy (url (plug_source * "texmacs.inx"), f1);
383     copy (url (plug_source * "texmacs_reedit.py"), f2);
384     copy (url (plug_source * "texmacs_latex.sty"), f3);
385     if (!(exists (f1) && exists (f2))) {
386       debug_boot << "automatic install of inkscape extension failed\n; ";
387       debug_boot << "see documentation for manual install\n";
388     }
389   }
390 }
391 
392 /******************************************************************************
393 * Deprecated initializations
394 ******************************************************************************/
395 
396 static void
397 init_deprecated () {
398 #ifndef OS_WIN32
399   // Check for Macaulay 2
400   if (get_env ("M2HOME") == "")
401     if (exists_in_path ("M2")) {
402       string where= concretize (resolve_in_path ("M2"));
403       string s    = var_eval_system ("grep 'M2HOME=' " * where);
404       string dir  = s (search_forwards ("=", s) + 1, N(s));
405       if (dir != "") set_env ("M2HOME", dir);
406     }
407 #endif
408 }
409 
410 /******************************************************************************
411 * Subroutines for the TeXmacs settings
412 ******************************************************************************/
413 
414 string
415 get_setting (string var, string def) {
416   int i, n= N (texmacs_settings);
417   for (i=0; i<n; i++)
418     if (is_tuple (texmacs_settings[i], var, 1)) {
419       return scm_unquote (as_string (texmacs_settings[i][1]));
420     }
421   return def;
422 }
423 
424 void
425 set_setting (string var, string val) {
426   int i, n= N (texmacs_settings);
427   for (i=0; i<n; i++)
428     if (is_tuple (texmacs_settings[i], var, 1)) {
429       texmacs_settings[i][1]= scm_quote (val);
430       return;
431     }
432   texmacs_settings << tuple (var, scm_quote (val));
433 }
434 
435 /******************************************************************************
436 * First installation
437 ******************************************************************************/
438 
439 void
440 setup_texmacs () {
441   url settings_file= "$TEXMACS_HOME_PATH/system/settings.scm";
442   debug_boot << "Welcome to TeXmacs " TEXMACS_VERSION "\n";
443   debug_boot << HRULE;
444 
445   set_setting ("VERSION", TEXMACS_VERSION);
446   setup_tex ();
447   setup_inkscape_extension ();
448 
449   string s= scheme_tree_to_block (texmacs_settings);
450   //cout << "settings_t= " << texmacs_settings << "\n";
451   //cout << "settings_s= " << s << "\n";
452   if (save_string (settings_file, s) || load_string (settings_file, s, false)) {
453     failed_error << HRULE;
454     failed_error << "I could not save or reload the file\n\n";
455     failed_error << "\t" << settings_file << "\n\n";
456     failed_error << "Please give me full access control over this file and\n";
457     failed_error << "rerun 'TeXmacs'.\n";
458     failed_error << HRULE;
459     FAILED ("unable to write settings");
460   }
461 
462   debug_boot << HRULE;
463   debug_boot << "Installation completed successfully !\n";
464   debug_boot << "I will now start up the editor\n";
465   debug_boot << HRULE;
466 }
467 
468 /******************************************************************************
469 * Initialization of TeXmacs
470 ******************************************************************************/
471 
472 void
473 init_texmacs () {
474   //cout << "Initialize -- Succession status table\n";
475   init_succession_status_table ();
476   //cout << "Initialize -- Succession standard DRD\n";
477   init_std_drd ();
478   //cout << "Initialize -- Main paths\n";
479   init_main_paths ();
480   //cout << "Initialize -- User dirs\n";
481   init_user_dirs ();
482   //cout << "Initialize -- User preferences\n";
483   load_user_preferences ();
484   //cout << "Initialize -- Guile\n";
485   init_guile ();
486   //cout << "Initialize -- Environment variables\n";
487   init_env_vars ();
488   //cout << "Initialize -- Miscellaneous\n";
489   init_misc ();
490   //cout << "Initialize -- Deprecated\n";
491   init_deprecated ();
492 }
493 
494 /******************************************************************************
495 * Initialization of built-in plug-ins
496 ******************************************************************************/
497 
498 void
499 init_plugins () {
500   install_status= 0;
501   url old_settings= "$TEXMACS_HOME_PATH/system/TEX_PATHS";
502   url new_settings= "$TEXMACS_HOME_PATH/system/settings.scm";
503   string s;
504   if (load_string (new_settings, s, false)) {
505     if (load_string (old_settings, s, false)) {
506       setup_texmacs ();
507       install_status= 1;
508     }
509     else get_old_settings (s);
510   }
511   else texmacs_settings= block_to_scheme_tree (s);
512   if (get_setting ("VERSION") != TEXMACS_VERSION) {
513     init_upgrade ();
514     url ch ("$TEXMACS_HOME_PATH/doc/about/changes/changes-recent.en.tm");
515     install_status= exists (ch)? 2: 0;
516   }
517   init_tex ();
518 }
519