home *** CD-ROM | disk | FTP | other *** search
- /*
- * Name: main.c
- * Description: main() function and parameter parsing.
- * Author: Christian Starkjohann <cs@hal.kph.tuwien.ac.at>
- * Date: 1996-11-14
- * Copyright: GNU-GPL
- * Tabsize: 4
- */
-
- #include <libc.h>
- #include <stdarg.h>
- #include <ctype.h>
- #include <syslog.h>
- #include <pwd.h>
- #include <grp.h>
- #include "my_defines.h"
-
- extern void nfs_program_2();
-
- typedef struct partition {
- unsigned char boot_ind; /* 0x80 - active */
- unsigned char head; /* starting head */
- unsigned char sector; /* starting sector */
- unsigned char cyl; /* starting cylinder */
- unsigned char sys_ind; /* What partition type */
- unsigned char end_head; /* end head */
- unsigned char end_sector; /* end sector */
- unsigned char end_cyl; /* end cylinder */
- unsigned char start_sect[4]; /* starting sector counting from 0 */
- unsigned char nr_sects[4]; /* nr of sectors in partition */
- }partition_t;
-
- typedef struct pinfo{
- unsigned int start_sect;
- unsigned int nr_sects;
- unsigned char sys_ind;
- }pinfo_t;
-
- #define SECTOR_SIZE 512 /* sector size on DOS partitioned disks */
- #define EXTENDED 5 /* id of extended partitions */
-
-
- /* ------------------------------------------------------------------------- */
-
- char *device_name;
- int my_fd;
- int wr_enable = 0;
- int had_fatal = 0;
- int probing_mode = 0;
- int use_syslog = 0;
- unsigned long part_offset = 0;
- unsigned long part_size = 0xffffffffUL;
- int debug_mode = 0;
- char *my_name;
-
- /* ------------------------------------------------------------------------- */
-
- static void vlogprintf(int level, const char *format, va_list vlist)
- {
- char buffer[32768]; /* should we alloc a larger chunk of virtual mem? */
-
- if(!probing_mode){
- if(use_syslog){
- vsprintf(buffer, format, vlist);
- syslog(level, "%s", buffer);
- }else{
- vfprintf(stderr, format, vlist);
- }
- }
- }
-
- /* ------------------------------------------------------------------------- */
-
- void dprintf(const char *format, ...)
- {
- va_list vlist;
-
- va_start(vlist, format);
- vlogprintf(LOG_INFO, format, vlist);
- va_end(vlist);
- }
-
- /* ------------------------------------------------------------------------- */
-
- void eprintf(const char *format, ...)
- {
- va_list vlist;
-
- va_start(vlist, format);
- vlogprintf(LOG_ERR, format, vlist);
- va_end(vlist);
- }
-
- /* ------------------------------------------------------------------------- */
-
- void fatal_error(const char *format, ...)
- {
- va_list vlist;
-
- if(!had_fatal){
- if(wr_enable){
- close(my_fd); /* reopen read only */
- my_fd = open(device_name, O_RDONLY);
- wr_enable = 0;
- }
- va_start(vlist, format);
- vlogprintf(LOG_ERR, format, vlist);
- va_end(vlist);
- had_fatal = 1;
- }
- }
-
- /* ------------------------------------------------------------------------- */
-
- static inline unsigned to_int(unsigned char *buf)
- {
- int res;
-
- res = buf[0];
- res |= (unsigned)buf[1] << 8;
- res |= (unsigned)buf[2] << 16;
- res |= (unsigned)buf[3] << 24;
- return res;
- }
-
- /* ------------------------------------------------------------------------- */
-
- static void print_part(partition_t *p, int i, unsigned offset)
- {
- fprintf(stderr, "%c %s %d 0x%02x start/sec=0x%08x size/sec=0x%08x\n",
- p->boot_ind ? '*' : ' ',
- i < 4 ? "primary" : "logical",
- i + 1,
- p->sys_ind,
- to_int(p->start_sect) + offset,
- to_int(p->nr_sects));
- }
-
- /* ------------------------------------------------------------------------- */
-
- static pinfo_t *get_part(int fd, unsigned *boot, unsigned offset, int *part_i, int info)
- {
- static pinfo_t pinfo;
- char buffer[SECTOR_SIZE];
- unsigned my_boot = *boot;
- int i;
- partition_t *p;
-
- if(my_boot >= 0x00800000/SECTOR_SIZE * 512){
- fprintf(stderr, "partition table at sector 0x%x outside 4GB limit\n",
- my_boot);
- fprintf(stderr, "aborting partition search.\n");
- return NULL;
- }
- if (lseek(fd, my_boot * SECTOR_SIZE, 0) == -1){
- perror("get_part() lseek()");
- exit(1);
- }
- if (read(fd, buffer, SECTOR_SIZE) != SECTOR_SIZE){
- perror("get_part() read()");
- exit(1);
- }
- for(*boot=i=0;i<4;i++){
- p = (struct partition *)(&buffer[0x1be] + i * sizeof(partition_t));
- if(p->sys_ind == 0){
- if(*part_i < 4)
- (*part_i)++;
- continue;
- }
- if(p->sys_ind == EXTENDED){
- if(*boot != 0){
- fprintf(stderr,
- "warning: one more extended partition in at index %d\n",
- *part_i);
- }
- *boot = to_int(p->start_sect) + offset;
- if(*part_i < 4)
- (*part_i)++;
- }else{
- if(*part_i == info){
- pinfo.start_sect = to_int(p->start_sect) + my_boot;
- pinfo.nr_sects = to_int(p->nr_sects);
- pinfo.sys_ind = p->sys_ind;
- return &pinfo;
- }
- if(info < 0)
- print_part(p, *part_i, my_boot);
- (*part_i)++;
- }
- }
- return NULL;
- }
-
- /* ------------------------------------------------------------------------- */
-
- static pinfo_t *partitions(int fd, int info)
- {
- unsigned boot = 0, extbase;
- int part_i;
- pinfo_t *res;
-
- part_i = 0;
- if((res = get_part(fd, &boot, 0, &part_i, info)) != NULL)
- return res;
- extbase = boot;
- while(boot != 0){
- if((res = get_part(fd, &boot, extbase, &part_i, info)) != NULL)
- return res;
- }
- return NULL;
- }
-
- /* ------------------------------------------------------------------------- */
-
- static void print_valid_filesystems(int part, char *fs)
- {
- char *p;
-
- while((p = strtok(fs, " ")) != NULL){
- fs = NULL;
- printf("%d/%s: -%c%d -t%s\n", part, p, part == 0 ? 'f' : 'p', part, p);
- }
- }
-
- /* ------------------------------------------------------------------------- */
-
- static void dump_info(int offset, int size, int part, int small_buffers)
- {
- pinfo_t *p;
- int i;
- char *fsys;
-
- missing_init();
- buffer_initialize(small_buffers);
- fops_init();
- probing_mode = 1;
- if(offset == -1){
- if(part == -1){
- for(i=0;i<100;i++){
- p = partitions(my_fd, i);
- if(p == NULL){
- if(i < 4)
- continue;
- else
- break;
- }
- buffer_invalidate();
- part_offset = p->start_sect * SECTOR_SIZE;
- part_size = p->nr_sects * SECTOR_SIZE;
- dummies_init(device_name, SECTOR_SIZE, SECTOR_SIZE, part_size);
- fsys = valid_filesystems();
- if(fsys[0] != 0)
- print_valid_filesystems(i+1, fsys);
- }
- }else{
- if((p = partitions(my_fd, part-1)) != NULL){
- buffer_invalidate();
- part_offset = p->start_sect * SECTOR_SIZE;
- part_size = p->nr_sects * SECTOR_SIZE;
- dummies_init(device_name, SECTOR_SIZE, SECTOR_SIZE, part_size);
- fsys = valid_filesystems();
- if(fsys[0] != 0)
- print_valid_filesystems(part, fsys);
- }
- }
- }else{
- buffer_invalidate();
- part_offset = offset;
- part_size = size;
- dummies_init(device_name, SECTOR_SIZE, SECTOR_SIZE, part_size);
- fsys = valid_filesystems();
- if(fsys[0] != 0)
- print_valid_filesystems(0, fsys);
- }
- probing_mode = 0;
- exit(0); /* must not continue after this kind of initialisation */
- }
-
- /* ------------------------------------------------------------------------- */
-
- static void print_help(char *name)
- {
- fprintf(stderr, "Usage: %s [-i] -m<mount-point> -t<fs-type> [-f<offset> | -p<partition>]\n", name);
- fprintf(stderr, "\t\t[-s<partition-size>] [-w] [-o<options>] [-d<debug-mode>] [-v]\n");
- fprintf(stderr, "\t\t[-U<fixed-userid>] [-G<fixed-groupid>] [-S]\n");
- fprintf(stderr, "\t\t[-u <uid-translation-file>] [-g <gid-translation-file>] device\n");
- fprintf(stderr, "-w .... mount filesystem read/write (default: read only)\n");
- fprintf(stderr, "-i .... print partitioning and filesystem info\n");
- fprintf(stderr, "-S .... use small cache buffers\n");
- fprintf(stderr, "-v .... print version info and exit\n");
- }
-
- /* ------------------------------------------------------------------------- */
-
- static void print_version(char *name)
- {
- fprintf(stderr, "%s: Version 0.6a (1997-06-06)\n", name);
- exit(0);
- }
-
- /* ------------------------------------------------------------------------- */
-
- int main(int argc, char **argv)
- {
- char print_info = 0, read_only = 1, err = 0, *fs_name = NULL;
- char *name = NULL, *mountpoint = NULL, *mount_options = NULL;
- int c, part = -1, go_background = 1, use_small_buffer = 0;
- long offset = -1, size = -1;
- char mountpoint_abs[MAXPATHLEN + 1], *mtab_options = "";
- struct passwd *pwd;
- struct group *grp;
- extern char *optarg;
- extern int optind;
- static char root_fh[32] = {0};
-
- my_name = argv[0];
- openlog(my_name, LOG_PID, LOG_DAEMON);
- while ((c = getopt(argc, argv, "Svo:O:t:d:t:him:f:p:s:wu:g:U:G:")) != EOF){
- switch(c){
- case 'i':
- print_info = 1;
- break;
- case 'm':
- mountpoint = optarg;
- break;
- case 'f':
- offset = strtol(optarg, NULL, 0);
- break;
- case 'p':
- part = atoi(optarg);
- break;
- case 's':
- size = strtol(optarg, NULL, 0);
- break;
- case 'w':
- read_only = 0;
- break;
- case 'h':
- err = 1;
- break;
- case 'o':
- mount_options = optarg;
- break;
- case 'O':
- mtab_options = optarg;
- break;
- case 'd':
- debug_mode = strtol(optarg, NULL, 0);
- go_background = 0;
- break;
- case 't':
- fs_name = optarg;
- break;
- case 'u':
- load_translationfile(IDBUF_USR, optarg);
- break;
- case 'g':
- load_translationfile(IDBUF_GRP, optarg);
- break;
- case 'U':
- if(isdigit(optarg[0])){
- set_fixed_id(IDBUF_USR, atoi(optarg));
- }else{
- pwd = getpwnam(optarg);
- if(pwd == NULL){
- eprintf("Unknown user: %s\n", optarg);
- exit(1);
- }
- set_fixed_id(IDBUF_USR, pwd->pw_uid);
- set_fixed_id(IDBUF_GRP, pwd->pw_gid);
- }
- break;
- case 'G':
- if(isdigit(optarg[0])){
- set_fixed_id(IDBUF_GRP, atoi(optarg));
- }else{
- grp = getgrnam(optarg);
- if(grp == NULL){
- eprintf("Unknown group: %s\n", optarg);
- exit(1);
- }
- set_fixed_id(IDBUF_GRP, grp->gr_gid);
- }
- break;
- case 'v':
- print_version(argv[0]);
- break;
- case 'S':
- use_small_buffer = 1;
- break;
- default:
- err = 1;
- fprintf(stderr, "unknown option -%c\n", c);
- break;
- }
- }
- if(err){
- print_help(argv[0]);
- exit(1);
- }
- while(optind < argc){
- if(name == NULL)
- name = argv[optind];
- else{
- fprintf(stderr, "trailing superflous parameter ->%s<- ignored\n",
- argv[optind]);
- }
- optind++;
- }
- if(name == NULL){
- fprintf(stderr, "No device specified\n");
- exit(1);
- }
- device_name = name;
- dprintf("mounting read%s\n",(wr_enable = !read_only)!=0 ?"/write":" only");
- my_fd = open(name, wr_enable ? O_RDWR : O_RDONLY);
- if(my_fd < 0){
- perror("error opening device");
- exit(1);
- }
- if(print_info){ /* print partition tables */
- if(offset == -1)
- partitions(my_fd, -1);
- dump_info(offset, size, part, use_small_buffer);
- close(my_fd);
- exit(0);
- }
- if(fs_name == NULL){
- fprintf(stderr, "Option -t is mandatory\n");
- exit(1);
- }
- if(mountpoint == NULL){
- fprintf(stderr, "Option -m is mandatory!\n");
- exit(1);
- }
- if(offset != -1 && part != -1){
- fprintf(stderr, "Options -f and -p are exclusive!\n");
- exit(1);
- }
- if(part != -1){
- pinfo_t *p;
- if(part < 1){
- fprintf(stderr, "Partition number is %d (< 1).\n", part);
- fprintf(stderr,"Partitions are counted from 1 in this version.\n");
- exit(1);
- }
- if((p = partitions(my_fd, part - 1)) == NULL){
- fprintf(stderr, "Partition %d does not exist on %s.\n", part,name);
- fprintf(stderr, "Use -i option to display partition table.\n");
- exit(1);
- }
- if(p->start_sect >= 0x00800000/SECTOR_SIZE*512
- || (p->start_sect + p->nr_sects) >= 0x00800000/SECTOR_SIZE*512){
- fprintf(stderr, "Partition %d reaches out of 4GB limit\n", part);
- exit(1);
- }
- part_offset = p->start_sect * SECTOR_SIZE;
- part_size = p->nr_sects * SECTOR_SIZE;
- }else{
- if(offset != -1)
- part_offset = offset;
- if(size != -1)
- part_size = size;
- }
- missing_init();
- buffer_initialize(use_small_buffer);
- dummies_init(name, 512, 512, part_size);
- fops_init();
- if(my_mount(fs_name, wr_enable ? 0 : MNT_RONLY,
- mount_options, (int *)root_fh) != 0){
- close(my_fd);
- exit(1);
- }
- if(*mountpoint == '/'){ /* absolute path given? */
- strcpy(mountpoint_abs, mountpoint);
- }else{
- if(getwd(mountpoint_abs) == NULL){
- mountpoint_abs[0] = 0;
- }else{
- strcat(mountpoint_abs, "/");
- }
- strcat(mountpoint_abs, mountpoint);
- }
- mount_and_dispatch(mountpoint_abs, nfs_program_2, root_fh, go_background,
- mtab_options);
- close(my_fd);
- return 0;
- }
-
- /* ------------------------------------------------------------------------- */
-