1 (* Copyright 2001, 2002 b8_bavard, b8_fee_carabine, INRIA *)
3 This file is part of mldonkey.
5 mldonkey is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 mldonkey is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with mldonkey; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 open CommonInteractive
36 open Gettext
(* open last as most modules redefine _s and _b *)
38 let _s x
= _s "DriverMain" x
39 let _b x
= _b "DriverMain" x
41 let log_prefix = "[dMain]"
44 lprintf_nl2
log_prefix fmt
47 lprintf2
log_prefix fmt
55 DriverInteractive.hdd_check
();
56 CommonUploads.upload_credit_timer
();
57 CommonInteractive.force_download_quotas
();
58 CommonResult.dummy_result
.result_time
<- last_time
();
60 CommonSwarming.verify_some_chunks
()
62 CommonClient.clear_upload_slots
()
64 let hourly_timer timer
=
66 CommonWeb.load_web_infos
false false;
67 if !CommonWeb.hours
mod !!compaction_delay
= 0 then Gc.compact
();
68 if !!backup_options_delay
<> 0
69 && !CommonWeb.hours
mod !!backup_options_delay
= 0 then
70 CommonComplexOptions.backup_options
();
71 DriverControlers.check_calendar
();
72 CommonFile.propose_filenames
()
74 let ten_second_timer timer
=
76 List.iter
(fun file
->
78 ) !!CommonComplexOptions.done_files
80 let second_timer timer
=
84 lprintf_nl (_b "Exception %s") (Printexc2.to_string e
));
86 CommonUploads.refill_upload_slots
()
88 lprintf_nl (_b "Exception %s") (Printexc2.to_string e
));
89 CommonUploads.shared_files_timer
();
92 let start_interfaces () =
94 (* option_hook(s) are not called when ini files are created the first time
95 force re-load of allowed_ips to call option_hook which fills the IP blocklist *)
97 match !created_new_base_directory
with
99 | Some dir
-> allowed_ips
=:= !!allowed_ips
102 if !!http_port
<> 0 then begin
104 ignore
(DriverControlers.create_http_handler
());
106 lprintf_nl (_b "Exception %s while starting HTTP interface")
107 (Printexc2.to_string e
);
110 if !!telnet_port
<> 0 then begin
112 ignore
(find_port
"telnet server" !!telnet_bind_addr
113 telnet_port
DriverControlers.telnet_handler
);
115 lprintf_nl (_b "Exception %s while starting Telnet interface")
116 (Printexc2.to_string e
);
119 if !!gui_port
<> 0 then begin
121 ignore
(find_port
"gui server" !!gui_bind_addr
122 gui_port gui_handler
);
124 lprintf_nl (_b "Exception %s while starting GUI interface")
125 (Printexc2.to_string e
);
128 if !!gift_port
<> 0 then begin
130 ignore
(find_port
"gift server" !!gui_bind_addr
131 gift_port gift_handler
);
133 lprintf_nl (_b "Exception %s while starting GUI interface")
134 (Printexc2.to_string e
);
137 add_infinite_option_timer update_gui_delay
DriverInterface.update_gui_info
;
138 add_infinite_timer
1. second_timer
141 let save_mlsubmit_reg () =
143 (* Generate the mlsubmit.reg file *)
145 let file = Printf.sprintf
147 "Windows Registry Editor Version 5.00
149 [HKEY_CLASSES_ROOT\\ed2k]
150 @=\"URL: ed2k Protocol\"
151 \"URL Protocol\"=\"\"
153 [HKEY_CLASSES_ROOT\\ed2k\\shell]
155 [HKEY_CLASSES_ROOT\\ed2k\\shell\\open]
157 [HKEY_CLASSES_ROOT\\ed2k\\shell\\open\\command]
158 @=\"\\\"IEXPLORE.EXE\\\" \\\"http://%s:%s@%s:%d/submit?q=dllink+%%1\\\"\"
161 "admin" "" (Ip.to_string
(client_ip None
)) !!http_port
163 File.from_string
(Filename.concat file_basedir
"mlsubmit.reg") file;
165 (* Generate the mldonkey_submit file *)
167 let file = Printf.sprintf
171 # Submit an eDonkey download request to mldonkey
173 # Argument(s): An ed2k URI of the form:
175 # ed2k://|file|<filename>|<filesize>|<MD4-sum|
178 ($#ARGV >= 0) || die \"Usage: mldonkey_submit <ed2kURI> ...\n\";
180 $vars{'HTTPURL'} = \"http://%s:%d\";
181 $vars{'HTTPUSER'} = \"%s\";
182 $vars{'HTTPPASS'} = \"%s\";
184 my $ua = LWP::UserAgent->new;
186 while (my $uri = shift @ARGV) {
187 $_ = URI::Escape::uri_unescape($uri);
188 if (/^ed2k:\\/\\/\\|file\\|[^|]+\\|(\\d+)\\|([\\dabcdef]+)\\|$/) {
191 my $req = HTTP::Request->new(
192 GET => \"$vars{'HTTPURL'}/submit?q=dllink+$uri\"
194 if (($vars{'HTTPUSER'}) && ($vars{'HTTPPASS'})) {
195 $req->authorization_basic($vars{'HTTPUSER'},
198 my $response = $ua->request($req);
199 if (!($response->is_success)) {
200 print $response->error_as_HTML;
204 print \"Not an ed2k URI: $_\n\";
209 (Ip.to_string
(client_ip None
)) !!http_port
212 File.from_string
(Filename.concat file_basedir
"mldonkey_submit") file;
213 Unix2.chmod
(Filename.concat file_basedir
"mldonkey_submit") 0o755
217 DriverInterface.install_hooks
();
219 (**** LOAD OPTIONS ****)
221 let exists_downloads_ini =
222 Sys.file_exists
(options_file_name downloads_ini
) in
223 let exists_users_ini =
224 Sys.file_exists
(options_file_name users_ini
)
226 if not
exists_users_ini && exists_downloads_ini then
228 lprintf_nl "No config file (users.ini) found. Importing users from downloads.ini.";
229 ( try Unix2.copy
"downloads.ini" "users.ini" with _
-> () );
232 let ini_files_exist = Sys.file_exists
(options_file_name downloads_ini
) in
235 Options.load downloads_ini
;
236 Options.load users_ini
;
237 DriverInteractive.hdd_check
()
239 lprintf_nl "Exception %s during options load" (Printexc2.to_string e
);
242 (* Here, we try to update options when a new version of mldonkey is
243 used. For example, we can add new web_infos... *)
244 CommonOptions.update_options
();
246 CommonMessages.load_message_file
();
247 if !!html_mods
then begin
248 if !!html_mods_style
> 0 && !!html_mods_style
< Array.length
CommonMessages.styles
then
249 commands_frame_height
=:= CommonMessages.styles
.(!!html_mods_style
).CommonMessages.frame_height
;
250 CommonMessages.colour_changer
();
252 networks_iter_all
(fun r
->
253 (* lprintf "(n) loading network config file\n"; *)
254 List.iter
(fun opfile
->
258 Options.save_with_help opfile
260 r
.network_config_file
264 (**** PARSE ARGUMENTS ***)
266 let more_args = ref [] in
269 more_args := !more_args
270 @ (Options.simple_args
"" downloads_ini
);
271 more_args := !more_args
272 @ (Options.simple_args
"" users_ini
);
274 networks_iter_all
(fun r
->
275 List.iter
(fun opfile
->
276 let prefix = r
.network_shortname ^
"-" in
277 let args = simple_args
prefix opfile
in
278 let args = List2.tail_map
(fun (arg
, spec
, help
) ->
279 (Printf.sprintf
"-%s" arg
, spec
, help
)) args
281 more_args := !more_args @ args
282 ) r
.network_config_file
286 "-v", Arg.Unit
(fun _
->
287 lprintf_nl "%s" (CommonGlobals.version
());
288 exit
0), _s " : print version number and exit";
289 "-exit", Arg.Unit
(fun _
-> exit
0), ": exit immediatly";
290 "-format", Arg.String
(fun file ->
291 ignore
(CommonMultimedia.get_info
file)),
292 _s " <filename> : check file format";
293 "-test_ip", Arg.String
(fun ip
->
294 lprintf_nl "%s = %s" ip
(Ip.to_string
(Ip.of_string ip
));
295 exit
0), _s "<ip> : undocumented";
296 "-check_impl", Arg.Unit
(fun _
->
297 CommonNetwork.check_network_implementations
();
298 CommonClient.check_client_implementations
();
299 CommonServer.check_server_implementations
();
300 CommonFile.check_file_implementations
();
301 (* CommonResult.check_result_implementations (); *)
304 _s " : display information on the implementations";
305 "-stdout", Arg.Unit
(fun _
->
306 lprintf_original_output
:= (Some stdout
);
309 _s ": keep output to stdout after startup";
310 "-stderr", Arg.Unit
(fun _
->
311 lprintf_original_output
:= (Some stderr
);
314 _s ": keep output to stderr after startup";
315 "-daemon", Arg.Unit
(fun _
->
316 (* Removed due to savannah bug #11514 . *)
317 lprintf_nl "\n\nOption -daemon was removed.\nUse 'mlnet > /dev/null 2>&1 &' instead. Exiting...";
318 exit
64), _s " : this argument was removed, core will exit";
319 "-find_port", Arg.Set find_other_port
,
320 _s " : find another port when one is already used";
321 "-pid", Arg.String
(fun s
-> pid := s
;
323 _s ": directory for pid file";
324 "-useradd", Arg.Rest
(fun s
->
325 (match String2.split s ' '
with
326 | user
:: pass
:: _
->
327 if user2_user_exists user
then
329 user2_user_set_password
(user2_user_find user
) pass
;
330 Printf.printf
"%sPassword of user %s changed\n%!" (log_time
()) user
334 user2_user_add user
(Md4.Md4.string pass
) ();
335 Printf.printf
"%sUser %s added\n%!" (log_time
()) user
337 Options.save_with_help_private users_ini
;
338 Printf.printf
"%sSaved changes to users.ini\n%!" (log_time
())
339 | _
-> raise
(Arg.Bad
"invalid syntax"));
340 exit
0), _s "\"<user> <pass>\" : create user/change password";
346 (* Files.dump_file file; exit 0 *)
349 if not
ini_files_exist && not
(keep_console_output
()) then log_file
=:= "mlnet.log";
351 (**** CREATE DIRS ****)
354 Unix2.safe_mkdir s
.shdir_dirname
;
355 if s
.shdir_strategy
= "incoming_directories" ||
356 s
.shdir_strategy
= "incoming_files" then
357 Unix2.can_write_to_directory s
.shdir_dirname
358 ) !!CommonComplexOptions.shared_directories
;
359 Unix2.safe_mkdir
"searches";
360 Unix2.can_write_to_directory
"searches";
361 Unix2.safe_mkdir
"web_infos";
362 Unix2.can_write_to_directory
"web_infos";
363 Unix2.safe_mkdir
!!temp_directory
;
364 Unix2.can_write_to_directory
!!temp_directory
368 let t = Unix.localtime
(Unix.time
()) in
369 if (t.Unix.tm_year
<=104) then
371 lprintf_nl (_b "\n\n\nYour system has a system date earlier than 2004, please correct it.");
372 lprintf_nl (_b "MLdonkey can not work with such a system date, exiting...");
373 CommonGlobals.exit_properly
71
376 ( let resolve_name hostname
=
378 ignore
(Ip.from_name hostname
);
383 ["mldonkey.sf.net"; "www.google.com"]
385 DriverInteractive.dns_works
:= List.exists
resolve_name hostnames;
387 if not
!DriverInteractive.dns_works
then lprintf
"
388 The core therefore is unable to get eDonkey serverlists and loading
389 .torrent files via dllink from websites is also impossible.
390 If you are using MLDonkey in a chroot environment you should
391 consider reading this article to get DNS support back:
392 http://mldonkey.sourceforge.net/Chroot\n\n");
394 let real_glibc_version = MlUnix.glibc_version_num
() in
395 if real_glibc_version <> Autoconf.glibc_version
396 && real_glibc_version <> "" then
399 This core is running with glibc %s but it was compiled with glibc %s.
400 This can lead to unexpected behaviour. Consider compiling the core yourself
401 or getting a binary compiled with glibc %s.\n\n")
402 real_glibc_version Autoconf.glibc_version
Autoconf.glibc_version
405 if Autoconf.magic
then begin
406 (if Sys.file_exists
"./magic/magic" then
407 try Unix.putenv
"MAGIC" "./magic/magic" with _ -> ());
408 if Magic.M.magic_works
() then
410 Autoconf.magic_works
:= true;
411 lprintf_nl (_b "Libmagic file-type recognition database present")
415 Autoconf.magic_works
:= false;
416 lprintf_nl (_b "Libmagic file-type recognition database not present")
420 if not
!Charset.Locale.conversion_enabled
then
421 lprintf_nl (_b "Self-test failed, charset conversion disabled.");
425 add_infinite_option_timer download_sample_rate
CommonFile.sample_timer
;
427 (* lprintf "(1) CommonComplexOptions.load\n"; *)
428 CommonComplexOptions.load
();
429 CommonUploads.load
();
432 (* lprintf "(2) CommonComplexOptions.load done\n"; *)
434 let old_save_results = !!save_results
in
436 CommonComplexOptions.save
();
437 CommonUploads.save
();
438 save_results
=:= old_save_results;
441 CommonGlobals.is_startup_phase
:= false;
443 (* before activating network modules load all local files from web_infos/
444 to avoid security holes, especially for IP blocking *)
445 Hashtbl.iter
(fun key w
->
446 let file = Filename.concat
"web_infos" (Filename.basename w
.url
) in
447 if Sys.file_exists
file then
449 lprintf_nl "loading %s from %s" w
.kind
file;
450 ((List.assoc w
.kind
!CommonWeb.file_kinds
).f w
.url
) file;
451 w
.state
<- Some FileLoaded
;
457 lprintf_nl (_b "Check http://mldonkey.sf.net for updates");
458 networks_iter
(fun r
-> network_load_complex_options r
);
459 lprintf_nl (_b "enabling networks: ");
460 if (upnp_port_forwarding
()) then
461 UpnpClient.init_maps
();
462 let add_upnp_port p s
=
463 lprintf_nl "using port %d (%s)" p s
;
464 if ((upnp_port_forwarding
())) then
465 match String2.split_simplify s ' '
with
466 | [ "client_port" ; tcpudp
]
467 | [ "tracker_port" ; tcpudp
]
468 | [ "dht_port" ; tcpudp
]
469 | [ "overnet_port" ; tcpudp
]
470 | [ "kademlia_port" ; tcpudp
] ->
471 if (String2.contains tcpudp
"TCP") then
473 UpnpClient.maps_add_item
1 p p
1 "" ;
474 lprintf_nl "add upnp port forwarding %d TCP" p
;
476 if (String2.contains tcpudp
"UDP") then
478 UpnpClient.maps_add_item
1 p p
0 "" ;
479 lprintf_nl "add upnp port forwarding %d UDP" p
;
483 networks_iter
(fun r
->
484 lprintf_nl (_b "---- enabling %s ----") r
.network_name
;
486 List.iter
(fun (p
,s
) -> if p
<> 0 then add_upnp_port p s
) (network_ports r
);
487 (* are there drawbacks to start recover_temp unconditionally here ? *)
488 if !!recover_temp_on_startup
then
489 network_recover_temp r
;
491 lprintf_nl (_b "---- enabling interfaces ----");
492 List.iter
(fun (p
,s
) -> if p
<> 0 then lprintf_nl "using port %d (%s)" p s
)
493 (network_ports
(network_find_by_name
"Global Shares"));
494 lprintf
(_b "%s[dMain] disabled networks: ") (log_time
());
495 let found = ref false in
496 networks_iter_all
(fun r
->
497 if not
(network_is_enabled r
) then
500 lprintf
(_b "%s ") r
.network_name
502 if not
!found then lprintf
(_b "none");
504 if (upnp_port_forwarding
()) then
505 UpnpClient.job_start
();
506 networks_iter_all
(fun n
-> network_update_options n
);
507 CommonOptions.start_running_plugins
:= true;
508 CommonInteractive.force_download_quotas
();
510 TcpBufferedSocket.set_max_connections_per_second
511 (fun _ -> !!max_connections_per_second
);
513 add_infinite_option_timer save_options_delay
(fun timer
->
514 DriverInteractive.save_config
());
517 add_infinite_timer
60. minute_timer;
518 add_infinite_timer
10. ten_second_timer;
519 add_infinite_timer
3600. hourly_timer;
520 add_infinite_timer
0.1 CommonUploads.upload_download_timer
;
521 add_infinite_timer
!!buffer_writes_delay
(fun _ -> Unix32.flush
());
523 if !!share_scan_interval
<> 0 then
524 add_infinite_timer
((float_of_int
!!share_scan_interval
) *. 60.)
525 (fun _ -> CommonShared.shared_check_files
());
526 CommonShared.shared_check_files
();
528 history_timeflag
:= (Unix.time
());
529 update_download_history
();
530 update_upload_history
();
531 history_h_timeflag
:= (Unix.time
());
532 update_h_download_history
();
533 update_h_upload_history
();
534 history_size_for_h_graph
:= history_size
* !!html_mods_vd_gfx_h_intervall
/ 60;
535 history_h_step
:= 60 * !!html_mods_vd_gfx_h_intervall
;
537 add_infinite_timer
(float_of_int history_step
) (fun timer
->
538 history_timeflag
:= (Unix.time
());
539 update_download_history
();
540 update_upload_history
());
542 add_infinite_timer
(float_of_int
!history_h_step
) (fun timer
->
543 history_h_timeflag
:= (Unix.time
());
544 update_h_download_history
();
545 update_h_upload_history
());
547 if Autoconf.system
= "mingw" then
548 add_infinite_timer
1. (fun timer
->
549 MlUnix.set_console_title
(DriverInteractive.console_topic
()));
552 CommonShared.shared_add_directory
553 !!CommonComplexOptions.shared_directories
;
555 add_infinite_timer
1800. (fun timer
->
556 DriverInteractive.browse_friends
());
558 Options.prune_file downloads_ini
;
559 Options.prune_file users_ini
;
560 add_timer
1. (fun _ -> try CommonWeb.load_web_infos
true false with _ -> ());
561 if !!telnet_port
<> 0 then lprintf_nl (_b "To command: telnet %s %d")
562 (if !!telnet_bind_addr
= Ip.any
then "127.0.0.1"
563 else Ip.to_string
!!telnet_bind_addr
) !!telnet_port
;
564 if !!http_port
<> 0 then begin
565 lprintf_nl (_b "Or with browser: http://%s:%d")
566 (if !!http_bind_addr
= Ip.any
then "127.0.0.1"
567 else Ip.to_string
!!http_bind_addr
) !!http_port
;
568 lprintf_nl (_b "For a GUI check out http://sancho-gui.sourceforge.net")
570 if !!gui_port
<> 0 then lprintf_nl (_b "Connect to IP %s, port %d")
571 (if !!gui_bind_addr
= Ip.any
then "127.0.0.1"
572 else Ip.to_string
!!gui_bind_addr
) !!gui_port
;
573 lprintf_nl (_b "If you connect from a remote machine adjust allowed_ips");
574 if Autoconf.system
= "cygwin" && not
(keep_console_output
()) then lprintf
(_b "%s") win_message
;
576 add_init_hook
(fun _ ->
577 if not
!gui_included
&& ( !!start_gui
|| !!ask_for_gui
) then
579 let _ = Sys.getenv
("DISPLAY") in
580 if !!start_gui
&& Sys.file_exists
!!mldonkey_gui
then
581 ignore
(Sys.command
(Printf.sprintf
"%s &" !!mldonkey_gui
))
583 let asker = Filename.concat
!!mldonkey_bin
"mlguistarter" in
584 if !!ask_for_gui
&& Sys.file_exists
!!mldonkey_gui
&&
585 Sys.file_exists
asker then
586 ignore
(Sys.command
(Printf.sprintf
"%s %s&" asker !!mldonkey_gui
));
588 lprintf_nl (_b "Not running under X, not trying to start the GUI")
592 if !!run_as_group
<> "" then begin
594 let new_gr = Unix.getgrnam
!!run_as_group
in
595 MlUnix.setgid
new_gr.Unix.gr_gid
;
596 let gr = Unix.getgrgid
(Unix.getgid
()) in
597 lprintf_nl (_b "mldonkey is now running as group %s") gr.Unix.gr_name
;
599 lprintf_nl (_b "Exception %s trying to set group_gid [%s]")
600 (Printexc2.to_string e
) !!run_as_group
;
604 if !!run_as_groupgid
<> 0 then begin
606 MlUnix.setgid
!!run_as_groupgid
;
607 lprintf_nl (_b "mldonkey is now running as gid %d") !!run_as_groupgid
;
609 lprintf_nl (_b "Exception %s trying to set group_gid [%d]")
610 (Printexc2.to_string e
) !!run_as_groupgid
;
614 if !!run_as_user
<> "" then begin
616 let new_pw = Unix.getpwnam
!!run_as_user
in
617 MlUnix.setuid
new_pw.Unix.pw_uid
;
618 let pw = Unix.getpwuid
(Unix.getuid
()) in
619 lprintf_nl (_b "mldonkey is now running as user %s") pw.Unix.pw_name
;
621 lprintf_nl (_b "Exception %s trying to set user_uid [%s]")
622 (Printexc2.to_string e
) !!run_as_user
;
626 if !!run_as_useruid
<> 0 then begin
628 MlUnix.setuid
!!run_as_useruid
;
629 lprintf_nl (_b "mldonkey is now running as uid %d") !!run_as_useruid
;
631 lprintf_nl (_b "Exception %s trying to set user_uid [%d]")
632 (Printexc2.to_string e
) !!run_as_useruid
;
636 if !!create_mlsubmit
then save_mlsubmit_reg ();
637 DriverInteractive.initialization_completed
:= true;
638 DriverInteractive.save_config
();
640 if not
Autoconf.windows
then
641 MlUnix.set_signal
Sys.sigchld
642 (Sys.Signal_handle
(fun _ -> if !verbose
then lprintf_nl (_b "Received SIGCHLD, doing nothing")));
644 if not
Autoconf.windows
then
645 MlUnix.set_signal
Sys.sighup
646 (Sys.Signal_handle
(fun _ -> lprintf_nl (_b "Received SIGHUP, closing all files and client/server sockets, start IP discovery");
647 networks_iter
(fun r
-> CommonNetwork.network_reset r
); (* stop_all_bt *)
648 CommonServer.disconnect_all_servers
();
649 CommonClient.disconnect_all_clients
();
650 Unix32.close_all
(); (* close all files *)
654 if not
Autoconf.windows
then
655 MlUnix.set_signal
Sys.sigpipe
656 (Sys.Signal_handle
(fun _ -> if !verbose
then lprintf_nl (_b "Received SIGPIPE, doing nothing")));
658 MlUnix.set_signal
Sys.sigint
659 (Sys.Signal_handle
(fun _ -> lprintf_nl (_b "Received SIGINT, stopping MLDonkey...");
660 CommonInteractive.clean_exit
0));
662 MlUnix.set_signal
Sys.sigterm
663 (Sys.Signal_handle
(fun _ -> lprintf_nl (_b "Received SIGTERM, stopping MLDonkey...");
664 CommonInteractive.clean_exit
0));
666 if not
Autoconf.windows
then
667 MlUnix.set_signal
Sys.sigusr1
668 (Sys.Signal_handle
(fun _ -> lprintf_nl (_b "Received SIGUSR1, saving options...");
669 DriverInteractive.save_config
()));
671 if not
Autoconf.windows
then
672 MlUnix.set_signal
Sys.sigusr2
673 (Sys.Signal_handle
(fun _ -> lprintf_n (_b "Received SIGUSR2, starting garbage collection...");
678 if !verbose
then lprintf_nl (_b "Activated system signal handling")
681 let security_space_oc = ref None
in
683 (* Create a 'config_files_security_space' megabytes file to protect some space
684 for config files at the end. *)
686 let oc = Unix.openfile security_space_filename
[Unix.O_WRONLY
; Unix.O_CREAT
] 0o600
in
688 let s = String.make
len ' '
in
689 let pos = ref zero
in
690 for i
= 1 to !!config_files_security_space
do
691 for j
= 1 to 32 do (* 32 = 1 MB / 32kB *)
692 ignore
(Unix2.c_seek64
oc !pos Unix.SEEK_SET
);
693 Unix2.really_write
oc s 0 len;
694 pos := !pos ++ (Int64.of_int
len)
697 ignore
(Unix2.c_seek64
oc zero
Unix.SEEK_SET
);
698 (try Unix.lockf
oc Unix.F_LOCK
(!!config_files_security_space
* 1024 * 1024) with _ -> ());
699 security_space_oc := Some
oc
701 lprintf_nl (_b "Cannot create Security space file: %s") (Printexc2.to_string e
);
702 lprintf_nl (_b " not enough space on device or bad permissions");
703 lprintf_nl (_b "Exiting...");
706 Unix32.external_start
();
710 Filename.concat
!pid pid_filename
,
711 Printf.sprintf
"%s\n" (string_of_int
(Unix.getpid
()))
713 Unix2.tryopen_write
pid_file (fun oc -> output_string
oc s);
714 CommonGlobals.do_at_exit
(fun _ -> try Sys.remove
pid_file with _ -> ());
716 lprintf_nl (_b "Starting with pid %s") (string_of_int
(Unix.getpid
()))
719 (* When a core is spawned from a gui, the only way to know the startup has
720 succeeded is the string token "Core started". *)
721 if not
(keep_console_output
()) then
724 Printf.eprintf
"%s[dMain] Core started\n%!" (log_time
());
728 lprintf_nl (_b "Core started");
729 core_included
:= true;
731 CommonGlobals.do_at_exit
(fun _ ->
732 (* If we have an error with too many file-descriptors,
733 just close all of them *)
735 BasicSocket.close_all
();
737 lprintf_nl "Exception %s in do_at_exit while closing sockets."
738 (Printexc2.to_string e
);
740 DriverGraphics.G.remove_files
();
741 (* In case we have no more space on filesystem for
742 config files, remove the security space file *)
743 (match !security_space_oc with
745 | Some
oc -> Unix.close
oc);
746 (try Sys.remove security_space_filename
with _ -> ());
747 CommonComplexOptions.allow_saving_ini_files
:= true;
748 DriverInteractive.save_config
();
749 CommonComplexOptions.save_sources
();
750 CommonComplexOptions.backup_options
();
752 Unix32.external_exit
();
753 lprintf_nl (_b "Core stopped")
756 if not
(keep_console_output
()) then
757 if !!log_file
= "" then
759 lprintf_nl (_b "Option log_file is empty, disable logging completely...");
760 lprintf_nl (_b "Disabling output to console, to enable: stdout true");