source: MondoRescue/trunk/mondo/src/mondoarchive/main.c@ 900

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

Huge patch to introduce low level functions that will bw used everywhere (mr_free, mr_asprintf, ...)
Nearly linking now due to that.

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