source: MondoRescue/branches/3.3/mondo/src/mondoarchive/mondoarchive.c@ 3801

Last change on this file since 3801 was 3790, checked in by Bruno Cornec, 23 months ago

Backport link fixes made for 3.2.2 to allow build on recent gcc versions

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