📄 main.c
字号:
#include <stdio.h>#include <string.h>#include <stdlib.h>#include <sys/fcntl.h>#include <errno.h>#include <unistd.h>#include "y.tab.h"#include "nodes.h"#include "x_malloc.h"#define MAP 0#define LIST 1extern char *version;extern char *date;char *boot_dev = DEFBOOT;static char *root_dir = NULL;static char *config_file = CONFIGFILE;int verbose = 0;extern int yyparse (void);extern FILE *yyin;int xwrite (int fild, void *p, int size){ int written = 0, i; do { i = write (fild, (char *)p + written, size - written); if (i == -1) { if (errno == EINTR) continue; return i; } written += i; } while (written < size); return written;}/* * Structure of kernel block written to buffer: * 0 0 type (0 = riscos, 1 = linux) * 1 4 name offset in file [null terminated] * 2 8 args offset in file [null terminated] * 3 12 bmap offset in file [null entry terminated] * 4 16 password offset in file [null terminated] * 5 20 kernels idea of root fs * 6 24 ramdisk size * 7 28 flags * 8 32 initrd offset in file [null terminated] * 9 36 rd start */ /* * Calculate the positions of the various parts of the file * and write the actual file, keeping a backup of the old */void create_config_file (void){ int blocksize = 40; int current_offset = (num_cnodes + 1) * blocksize; struct compressed_node *node; int fild; unsigned long buffer[16]; for (node = cnode; node; node = node->next) { if (node->name) { node->file_name_offset = current_offset; current_offset += strlen (node->name) + 1; } else node->file_name_offset = 0; if (node->passwd) { node->file_passwd_offset = current_offset; current_offset += strlen (node->passwd) + 1; } else node->file_passwd_offset = 0; if (node->args) { node->file_args_offset = current_offset; current_offset += strlen (node->args) + 1; } else node->file_args_offset = 0; if (node->bmap) { current_offset = (current_offset + 3) & ~3; node->file_bmap_offset = current_offset; current_offset += node->bmap_size; } else node->file_bmap_offset = 0; if (node->initrd) { current_offset = (current_offset + 3) & ~3; node->file_initrd_offset = current_offset; current_offset += node->initrd_size; } else node->file_initrd_offset = 0; } memset (buffer, 0, sizeof (buffer)); buffer[0] = 0xC35AE183; /* magic */ buffer[1] = 0x17089700 + blocksize; /* date + entry size */ buffer[2] = num_cnodes; /* number of entries */ rename ("/boot/boot.map", "/boot/boot.map.old"); fild = open ("/boot/boot.map", O_CREAT|O_RDWR, 0400); if (fild < 0) { perror ("cfg: open: /boot/boot.map"); exit (1); } if (xwrite (fild, buffer, blocksize) < 0) { perror ("write: prefix"); close (fild); remove("/boot/boot.map"); rename("/boot/boot.map.old", "/boot/boot.map"); exit (1); } for (node = cnode; node; node = node->next) { buffer[0] = node->type == KERNEL? 1 : 0; buffer[1] = node->file_name_offset; buffer[2] = node->file_args_offset; buffer[3] = node->file_bmap_offset; buffer[4] = node->file_passwd_offset; buffer[5] = node->root; buffer[6] = node->ramdisk_size; buffer[7] = node->flags; buffer[8] = node->file_initrd_offset; buffer[9] = node->rdstart; if (xwrite (fild, buffer, blocksize) < 0) { perror ("write: kernel image"); close (fild); remove("/boot/boot.map"); rename("/boot/boot.map.old", "/boot/boot.map"); exit (1); } } for (node = cnode; node; node = node->next) { int i = 0; if (node->file_name_offset) i = xwrite (fild, node->name, strlen (node->name) + 1); if (node->file_passwd_offset && i >= 0) i = xwrite (fild, node->passwd, strlen (node->passwd) + 1); if (node->file_args_offset && i >= 0) i = xwrite (fild, node->args, strlen (node->args) + 1); if (node->file_bmap_offset && i >= 0) { lseek (fild, node->file_bmap_offset, SEEK_SET); i = xwrite (fild, node->bmap, node->bmap_size); } if (node->file_initrd_offset && i >= 0) { lseek (fild, node->file_initrd_offset, SEEK_SET); i = xwrite (fild, node->initrd, node->initrd_size); } if (i < 0) { perror ("write: kernel image info"); close (fild); remove("/boot/boot.map"); rename("/boot/boot.map.old", "/boot/boot.map"); exit (1); } } close (fild);}void write_map_header (void){ unsigned long *addr, *addr2; char sector[512]; /* only one sector */ char old_sector[512]; char bkname[32]; int filp, bkfilp, len; addr2 = (unsigned long *)§or[0]; memset(sector, 0, sizeof (sector)); len = map_file ("/boot/boot.map", &addr); if (len < 0) exit (1); addr2[0] = 0xc53a4b2d; addr2[1] = addr[1]; for (filp = 2; filp < len / sizeof (unsigned long); filp++) addr2[filp] = addr[filp]; filp = open (boot_dev, O_RDWR); if (filp < 0) { perror ("open boot device"); exit (1); } sprintf (bkname, "/boot/bsect.%04X", get_boot_dev ()); if (access (bkname, F_OK) == -1 && errno == ENOENT) { if (verbose) printf ("Backing up boot sector information to %s\n", bkname); bkfilp = open (bkname, O_RDWR|O_CREAT, 0600); if (bkfilp < 0) { perror ("open backup file"); close (filp); exit (1); } if (lseek (filp, 0, SEEK_SET) < 0) { perror ("lseek root device"); close (filp); close (bkfilp); remove (bkname); exit (1); } if (read (filp, old_sector, 512) != 512) { perror ("read root device"); close (filp); close (bkfilp); remove (bkname); exit (1); } if (write (bkfilp, old_sector, 512) != 512) { perror ("write backup file"); close (filp); close (bkfilp); remove (bkname); exit (1); } close (bkfilp); } if (verbose) printf ("Writing boot sector\n"); if (lseek (filp, 0, SEEK_SET) < 0) { perror ("lseek root device"); close (filp); exit (1); } if (write (filp, sector, 512) != 512) { perror ("write root device"); close (filp); exit (1); } close (filp);} void usage (FILE *out, int exitstatus){ fprintf (out, "Usage: loadmap [OPTIONS]\n\n"); fprintf (out, " -r, --root ROOT\tSpecify the root of directories to use\n"); fprintf (out, " -R, --rdev ROOTDEV\tSpecify the root device to write to\n"); fprintf (out, " -C, --config CONFIG\tSpecify the configuration file\n"); fprintf (out, " -l, --list\t\tList the currently bootable images\n"); fprintf (out, " -v, --verbose\t\tBe verbose\n"); fprintf (out, " -V, --version\t\tPrint version and exit\n"); fprintf (out, " -h, --help\t\tPrint this help and exit\n"); exit (exitstatus);}int main (int argc, char *argv[]){ int i; int todo = MAP; for (i = 1; i < argc; i++) { if (strcmp (argv[i], "--root") == 0 || strcmp (argv[i], "-r") == 0) { if (i + 1 > argc) goto needs_arg; root_dir = argv[++i]; continue; } if (strcmp (argv[i], "--rdev") == 0 || strcmp (argv[i], "-R") == 0) { if (i + 1 > argc) goto needs_arg; boot_dev = argv[++i]; continue; } if (strcmp (argv[i], "--config") == 0 || strcmp (argv[i], "-C") == 0) { if (i + 1 > argc) goto needs_arg; config_file = argv[++i]; continue; } if (strcmp (argv[i], "--list") == 0 || strcmp (argv[i], "-l") == 0) { todo = LIST; continue; } if (strcmp (argv[i], "--verbose") == 0 || strcmp (argv[i], "-v") == 0) { verbose = 1; continue; } if (strcmp (argv[i], "--help") == 0 || strcmp (argv[i], "-h") == 0) usage (stdout, 0); if (strcmp (argv[i], "--version") == 0 || strcmp (argv[i], "-V") == 0) { fprintf (stderr, "loadmap version %s (%s)\n", version, date); exit (0); } fprintf (stderr, "Invalid option '%s'\n", argv[i]); usage (stderr, 1);needs_arg: fprintf (stderr, "Option '%s' requires an argument\n", argv[i]); usage (stderr, 1); } if (root_dir) chroot (root_dir); if (todo == MAP) { yyin = fopen (config_file, "rt"); if (!yyin) { fprintf (stderr, "Can't open '%s'\n", config_file); exit (1); } } if (todo == MAP) { yyparse (); if (compress_nodes ()) exit (1); if (verbose) dump_cnode (cnode); create_config_file (); write_map_header (); } else { } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -