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

Last change on this file since 3879 was 3879, checked in by Bruno Cornec, 3 months ago

Fix all remaining compiler errors

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