source: MondoRescue/branches/stable/mondo/src/mondoarchive/main.c@ 1140

Last change on this file since 1140 was 1140, checked in by Bruno Cornec, 17 years ago

Try to fix some valgrind reports (note that this version still doesn't work)

  • Property svn:keywords set to Id
File size: 13.1 KB
Line 
1/***************************************************************************
2* $Id: main.c 1140 2007-02-12 01:05:43Z bruno $
3*/
4
5
6/**
7 * @file
8 * The main file for mondoarchive.
9 */
10
11/************************* #include statements *************************/
12#include <pthread.h>
13#include <stdio.h>
14#include <stdlib.h>
15#include <sys/types.h>
16#include <sys/stat.h>
17#include <unistd.h>
18
19#include "my-stuff.h"
20#include "../common/mondostructures.h"
21#include "../common/libmondo.h"
22#include "mondo-cli-EXT.h"
23
24#include "mr_str.h"
25#include "mr_msg.h"
26#include "mr_file.h"
27
28// for CVS
29//static char cvsid[] = "$Id: main.c 1140 2007-02-12 01:05:43Z bruno $";
30
31/************************* external variables *************************/
32extern void set_signals(int);
33extern int g_current_media_number;
34extern void register_pid(pid_t, char *);
35extern int g_currentY;
36extern bool g_text_mode;
37extern char *g_boot_mountpt;
38extern bool g_remount_cdrom_at_end, g_remount_floppy_at_end;
39extern char *g_mondo_home;
40extern char *g_tmpfs_mountpt;
41extern char *g_erase_tmpdir_and_scratchdir;
42extern char *g_cdrw_drive_is_here;
43static char *g_cdrom_drive_is_here = NULL;
44static char *g_dvd_drive_is_here = NULL;
45extern double g_kernel_version;
46
47/***************** global vars, used only by main.c ******************/
48bool g_skip_floppies;
49long diffs;
50char *ps_options = "auxww";
51char *ps_proc_id = "$2";
52
53extern t_bkptype g_backup_media_type;
54extern int g_loglevel;
55
56/****************** subroutines used only by main.c ******************/
57
58
59/**
60 * Print a "don't panic" message to the log and a message about the logfile to the screen.
61 */
62void welcome_to_mondoarchive()
63{
64 mr_msg(0, "Mondo Archive v%s --- http://www.mondorescue.org",
65 PACKAGE_VERSION);
66 mr_msg(0, "running on %s architecture", get_architecture());
67 mr_msg(0,
68 "-----------------------------------------------------------");
69 mr_msg(0,
70 "NB: Mondo logs almost everything, so don't panic if you see");
71 mr_msg(0,
72 "some error messages. Please read them carefully before you");
73 mr_msg(0,
74 "decide to break out in a cold sweat. Despite (or perhaps");
75 mr_msg(0,
76 "because of) the wealth of messages. some users are inclined");
77 mr_msg(0,
78 "to stop reading this log. If Mondo stopped for some reason,");
79 mr_msg(0,
80 "chances are it's detailed here. More than likely there's a");
81 mr_msg(0,
82 "message at the very end of this log that will tell you what");
83 mr_msg(0,
84 "is wrong. Please read it! -Devteam");
85 mr_msg(0,
86 "-----------------------------------------------------------");
87
88 mr_msg(0, "Zero...");
89 mr_msg(1, "One...");
90 mr_msg(2, "Two...");
91 mr_msg(3, "Three...");
92 mr_msg(4, "Four...");
93 mr_msg(5, "Five...");
94 mr_msg(6, "Six...");
95 mr_msg(7, "Seven...");
96 mr_msg(8, "Eight...");
97 printf("See %s for details of backup run.\n", MONDO_LOGFILE);
98}
99
100
101extern char *g_magicdev_command;
102
103/**
104 * Do whatever is necessary to insure a successful backup on the Linux distribution
105 * of the day.
106 */
107void distro_specific_kludges_at_start_of_mondoarchive()
108{
109 mr_msg(2, "Unmounting old ramdisks if necessary");
110 stop_magicdev_if_necessary(); // for RH+Gnome users
111 run_program_and_log_output
112 ("umount `mount | grep shm | grep mondo | cut -d' ' -f3`", 2);
113 unmount_supermounts_if_necessary(); // for Mandrake users whose CD-ROMs are supermounted
114 // stop_autofs_if_necessary(); // for Xandros users
115 mount_boot_if_necessary(); // for Gentoo users with non-mounted /boot partitions
116 clean_up_KDE_desktop_if_necessary(); // delete various misc ~/.* files that get in the way
117}
118
119
120
121/**
122 * Undo whatever was done by distro_specific_kludges_at_start_of_mondoarchive().
123 */
124void distro_specific_kludges_at_end_of_mondoarchive()
125{
126// char tmp[500];
127 mr_msg(2, "Restarting magicdev if necessary");
128 sync();
129 restart_magicdev_if_necessary(); // for RH+Gnome users
130
131 mr_msg(2, "Restarting autofs if necessary");
132 sync();
133 // restart_autofs_if_necessary(); // for Xandros users
134
135 mr_msg(2, "Restarting supermounts if necessary");
136 sync();
137 remount_supermounts_if_necessary(); // for Mandrake users
138
139 mr_msg(2, "Unmounting /boot if necessary");
140 sync();
141 unmount_boot_if_necessary(); // for Gentoo users
142
143// mr_msg( 2, "Cleaning up KDE desktop");
144// clean_up_KDE_desktop_if_necessary();
145}
146
147/*-----------------------------------------------------------*/
148
149
150
151/**
152 * Backup/verify the user's data.
153 * What did you think it did, anyway? :-)
154 */
155int main(int argc, char *argv[])
156{
157 struct s_bkpinfo *bkpinfo;
158 struct stat stbuf;
159 char *tmp;
160 int res, retval;
161 char *say_at_end;
162
163/* Make sure I'm root; abort if not */
164 if (getuid() != 0) {
165 fprintf(stderr, "Please run as root.\r\n");
166 exit(127);
167 }
168
169/* If -V, -v or --version then echo version no. and quit */
170 if (argc == 2
171 && (!strcmp(argv[argc - 1], "-v") || !strcmp(argv[argc - 1], "-V")
172 || !strcmp(argv[argc - 1], "--version"))) {
173 printf("mondoarchive v%s\nSee man page for help\n", PACKAGE_VERSION);
174 exit(0);
175 }
176
177/* Initialize variables */
178
179 malloc_libmondo_global_strings();
180 malloc_string(tmp);
181 malloc_string(say_at_end);
182
183 res = 0;
184 retval = 0;
185 diffs = 0;
186 say_at_end[0] = '\0';
187 printf("Initializing...\n");
188
189 /* initialize log file with time stamp */
190 unlink(MONDO_LOGFILE);
191 mr_msg_init(MONDO_LOGFILE,4);
192 mr_msg(0, "Time started: %s", mr_date());
193
194 bkpinfo = mr_malloc(sizeof(struct s_bkpinfo));
195
196 /* make sure PATH environmental variable allows access to mkfs, fdisk, etc. */
197 strncpy(tmp, getenv("PATH"), MAX_STR_LEN - 1);
198 tmp[MAX_STR_LEN - 1] = '\0';
199 if (strlen(tmp) >= MAX_STR_LEN - 33) {
200 fatal_error
201 ("Your PATH environmental variable is too long. Please shorten it.");
202 }
203 strcat(tmp, ":/sbin:/usr/sbin:/usr/local/sbin");
204 setenv("PATH", tmp, 1);
205
206 /* Add the ARCH environment variable for ia64 purposes */
207 strncpy(tmp, get_architecture(), MAX_STR_LEN - 1);
208 tmp[MAX_STR_LEN - 1] = '\0';
209 setenv("ARCH", tmp, 1);
210
211 /* Add MONDO_SHARE + others environment variable for mindi */
212 setenv_mondo_share();
213
214 if (stat(MONDO_CACHE, &stbuf) != 0) {
215 mr_mkdir(MONDO_CACHE,0x755);
216 }
217
218 /* BERLIOS: Hardcoded to be improved */
219 unlink(MONDO_CACHE"/mindi.conf");
220 unlink(MONDO_CACHE"/mondorestore.cfg");
221
222 /* Configure the bkpinfo structure, global file paths, etc. */
223 g_main_pid = getpid();
224 mr_msg(9, "This");
225
226 register_pid(g_main_pid, "mondo");
227 set_signals(TRUE); // catch SIGTERM, etc.
228 run_program_and_log_output("dmesg -n1", TRUE);
229
230 mr_msg(9, "Next");
231 welcome_to_mondoarchive();
232 distro_specific_kludges_at_start_of_mondoarchive();
233 g_kernel_version = get_kernel_version();
234
235 if (argc == 4 && !strcmp(argv[1], "getfattr")) {
236 g_loglevel = 10;
237 g_text_mode = TRUE;
238 setup_newt_stuff();
239 if (!strstr(argv[2], "filelist")) {
240 printf("Sorry - filelist goes first\n");
241 finish(1);
242 } else {
243 finish(get_fattr_list(argv[2], argv[3]));
244 }
245 finish(0);
246 }
247 if (argc == 4 && !strcmp(argv[1], "setfattr")) {
248 g_loglevel = 10;
249// chdir("/tmp");
250 g_text_mode = TRUE;
251 setup_newt_stuff();
252 finish(set_fattr_list(argv[2], argv[3]));
253 }
254
255 if (argc == 3 && !strcmp(argv[1], "wildcards")) {
256 g_loglevel = 10;
257 g_text_mode = TRUE;
258 setup_newt_stuff();
259 turn_wildcard_chars_into_literal_chars(tmp, argv[2]);
260 printf("in=%s; out=%s\n", argv[2], tmp);
261 finish(1);
262 }
263
264 if (argc == 4 && !strcmp(argv[1], "getfacl")) {
265 g_loglevel = 10;
266 g_text_mode = TRUE;
267 setup_newt_stuff();
268 if (!strstr(argv[2], "filelist")) {
269 printf("Sorry - filelist goes first\n");
270 finish(1);
271 } else {
272 finish(get_acl_list(argv[2], argv[3]));
273 }
274 finish(0);
275 }
276 if (argc == 4 && !strcmp(argv[1], "setfacl")) {
277 g_loglevel = 10;
278// chdir("/tmp");
279 g_text_mode = TRUE;
280 setup_newt_stuff();
281 finish(set_acl_list(argv[2], argv[3]));
282 }
283
284 if (argc > 2 && !strcmp(argv[1], "find-cd")) {
285 g_loglevel = 10;
286 g_text_mode = TRUE;
287 setup_newt_stuff();
288 if (find_cdrw_device(tmp)) {
289 printf("Failed to find CDR-RW drive\n");
290 } else {
291 printf("CD-RW is at %s\n", tmp);
292 }
293 tmp[0] = '\0';
294 if (find_cdrom_device(tmp, atoi(argv[2]))) {
295 printf("Failed to find CD-ROM drive\n");
296 } else {
297 printf("CD-ROM is at %s\n", tmp);
298 }
299 finish(0);
300 }
301
302 if (argc > 2 && !strcmp(argv[1], "find-dvd")) {
303 g_loglevel = 10;
304 g_text_mode = TRUE;
305 setup_newt_stuff();
306 if (find_dvd_device(tmp, atoi(argv[2]))) {
307 printf("Failed to find DVD drive\n");
308 } else {
309 printf("DVD is at %s\n", tmp);
310 }
311 finish(0);
312 }
313
314 if (argc > 2 && !strcmp(argv[1], "disksize")) {
315 printf("%s --> %ld\n", argv[2], get_phys_size_of_drive(argv[2]));
316 finish(0);
317 }
318 if (argc > 2 && !strcmp(argv[1], "test-dev")) {
319 if (is_dev_an_NTFS_dev(argv[2])) {
320 printf("%s is indeed an NTFS dev\n", argv[2]);
321 } else {
322 printf("%s is _not_ an NTFS dev\n", argv[2]);
323 }
324 finish(0);
325 }
326
327 if (pre_param_configuration(bkpinfo)) {
328 fatal_error
329 ("Pre-param initialization phase failed. Please review the error messages above, make the specified changes, then try again. Exiting...");
330 }
331 sprintf(g_erase_tmpdir_and_scratchdir, "rm -Rf %s %s", bkpinfo->tmpdir,
332 bkpinfo->scratchdir);
333
334 /* Process command line, if there is one. If not, ask user for info. */
335 if (argc == 1) {
336 g_text_mode = FALSE;
337 setup_newt_stuff();
338 res = interactively_obtain_media_parameters_from_user(bkpinfo, TRUE); /* yes, archiving */
339 if (res) {
340 fatal_error
341 ("Syntax error. Please review the parameters you have supplied and try again.");
342 }
343 } else {
344 res = handle_incoming_parameters(argc, argv, bkpinfo);
345 if (res) {
346 printf
347 ("Errors were detected in the command line you supplied.\n");
348 printf("Please review the log file - " MONDO_LOGFILE "\n");
349 mr_msg(1, "Mondoarchive will now exit.");
350 finish(1);
351 }
352 setup_newt_stuff();
353 }
354
355/* Finish configuring global structures */
356 if (post_param_configuration(bkpinfo)) {
357 fatal_error
358 ("Post-param initialization phase failed. Perhaps bad parameters were supplied to mondoarchive? Please review the documentation, error messages and logs. Exiting...");
359 }
360
361 log_to_screen
362 ("BusyBox's sources are available from http://www.busybox.net");
363 sprintf(g_erase_tmpdir_and_scratchdir, "rm -Rf %s %s", bkpinfo->tmpdir,
364 bkpinfo->scratchdir);
365
366 /* If we're meant to backup then backup */
367 if (bkpinfo->backup_data) {
368 res = backup_data(bkpinfo);
369 retval += res;
370 if (res) {
371 strcat(say_at_end,
372 "Data archived. Please check the logs, just as a precaution. ");
373 } else {
374 strcat(say_at_end, "Data archived OK. ");
375 }
376 }
377
378/* If we're meant to verify then verify */
379 if (bkpinfo->verify_data) {
380 res = verify_data(bkpinfo);
381 if (res < 0) {
382 sprintf(tmp, "%d difference%c found.", -res,
383 (-res != 1) ? 's' : ' ');
384 strcat(say_at_end, tmp);
385 log_to_screen(tmp);
386 res = 0;
387 }
388 retval += res;
389 }
390
391/* Offer to write floppy disk images to physical disks */
392 if (bkpinfo->backup_data && !g_skip_floppies) {
393 res = offer_to_write_boot_floppies_to_physical_disks(bkpinfo);
394 retval += res;
395// res = offer_to_write_boot_ISO_to_physical_CD(bkpinfo);
396// retval += res;
397 }
398
399/* Report result of entire operation (success? errors?) */
400 if (!retval) {
401 mvaddstr_and_log_it(g_currentY++, 0,
402 "Backup and/or verify ran to completion. Everything appears to be fine.");
403 } else {
404 mvaddstr_and_log_it(g_currentY++, 0,
405 "Backup and/or verify ran to completion. However, errors did occur.");
406 }
407
408 if (does_file_exist("/var/cache/mindi/mondorescue.iso")) {
409 log_to_screen
410 ("/var/cache/mindi/mondorescue.iso, a boot/utility CD, is available if you want it.");
411 }
412
413
414 if (length_of_file("/tmp/changed.files") > 2) {
415 if (g_text_mode) {
416 log_to_screen
417 ("Type 'less /tmp/changed.files' to see which files don't match the archives");
418 } else {
419 mr_msg(1,
420 "Type 'less /tmp/changed.files' to see which files don't match the archives");
421 mr_msg(2, "Calling popup_changelist_from_file()");
422 popup_changelist_from_file("/tmp/changed.files");
423 mr_msg(2, "Returned from popup_changelist_from_file()");
424 }
425 } else {
426 unlink("/tmp/changed.files");
427 }
428 log_to_screen(say_at_end);
429 sprintf(tmp, "umount %s/tmpfs", bkpinfo->tmpdir);
430 run_program_and_log_output(tmp, TRUE);
431 run_program_and_log_output(g_erase_tmpdir_and_scratchdir, TRUE);
432
433 run_program_and_log_output("mount", 2);
434
435 system("rm -f /var/cache/mondo-archive/last-backup.aborted");
436 system("rm -Rf /tmp.mondo.* /mondo.scratch.*");
437 if (!retval) {
438 printf("Mondoarchive ran OK.\n");
439 } else {
440 printf("Errors occurred during backup. Please check logfile.\n");
441 }
442 distro_specific_kludges_at_end_of_mondoarchive();
443 register_pid(0, "mondo");
444 set_signals(FALSE);
445 chdir("/tmp"); // just in case there's something wrong with g_erase_tmpdir_and_scratchdir
446 system(g_erase_tmpdir_and_scratchdir);
447 free_libmondo_global_strings();
448 mr_free(say_at_end);
449 mr_free(tmp);
450 mr_free(bkpinfo);
451
452 unlink("/tmp/filelist.full");
453 unlink("/tmp/filelist.full.gz");
454
455 if (!g_cdrom_drive_is_here) {
456 mr_msg(10, "FYI, g_cdrom_drive_is_here was never used");
457 }
458 if (!g_dvd_drive_is_here) {
459 mr_msg(10, "FYI, g_dvd_drive_is_here was never used");
460 }
461
462 /* finalize log file with time stamp */
463 mr_msg(0, "Time finished: %s", mr_date());
464 mr_msg_close();
465
466 if (!g_text_mode) {
467 popup_and_OK
468 ("Mondo Archive has finished its run. Please press ENTER to return to the shell prompt.");
469 log_to_screen("See %s for details of backup run.", MONDO_LOGFILE);
470 finish(retval);
471 } else {
472 printf("See %s for details of backup run.\n", MONDO_LOGFILE);
473 exit(retval);
474 }
475
476 return EXIT_SUCCESS;
477}
Note: See TracBrowser for help on using the repository browser.