Logo Search packages:      
Sourcecode: e2fsprogs version File versions

e2initrd_helper.c

/*
 * e2initrd_helper.c - Get the filesystem table
 *
 * Copyright 2004 by Theodore Ts'o.
 *
 * %Begin-Header%
 * This file may be redistributed under the terms of the GNU Public
 * License.
 * %End-Header%
 */

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <time.h>
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <utime.h>
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#else 
extern int optind;
extern char *optarg;
#endif

#include "ext2fs/ext2_fs.h"
#include "ext2fs/ext2fs.h"
#include "e2p/e2p.h"
#include "blkid/blkid.h"

#include "../version.h"
#include "nls-enable.h"

const char * program_name = "get_fstab";
char * device_name;
static int open_flag;
static int root_type;
static blkid_cache cache = NULL;

struct mem_file {
      char  *buf;
      int   size;
      int   ptr;
};

struct fs_info {
      char  *device;
      char  *mountpt;
      char  *type;
      char  *opts;
      int   freq;
      int   passno;
      int   flags;
      struct fs_info *next;
};

static void usage(void)
{
      fprintf(stderr,
            _("Usage: %s -r device\n"), program_name);
      exit (1);
}

static errcode_t get_file(ext2_filsys fs, const char * filename, 
               struct mem_file *ret_file)
{
      errcode_t   retval;
      char        *buf;
      ext2_file_t e2_file;
      unsigned int      got;
      struct ext2_inode inode;
      ext2_ino_t  ino;

      ret_file->buf = 0;
      ret_file->size = 0;
      ret_file->ptr = 0;

      retval = ext2fs_namei(fs, EXT2_ROOT_INO, EXT2_ROOT_INO, 
                        filename, &ino);
      if (retval)
            return retval;

      retval = ext2fs_read_inode(fs, ino, &inode);
      if (retval)
            return retval;

      if (inode.i_size_high || (inode.i_size > 65536))
            return EFBIG;

      buf = malloc(inode.i_size + 1);
      if (!buf)
            return ENOMEM;
      memset(buf, 0, inode.i_size+1);

      retval = ext2fs_file_open(fs, ino, 0, &e2_file);
      if (retval)
            return retval;

      retval = ext2fs_file_read(e2_file, buf, inode.i_size, &got);
      if (retval) 
            goto errout;

      retval = ext2fs_file_close(e2_file);
      if (retval)
            return retval;

      ret_file->buf = buf;
      ret_file->size = (int) got;

errout:
      ext2fs_file_close(e2_file);
      return retval;
}

static char *get_line(struct mem_file *file)
{
      char  *cp, *ret;
      int   s = 0;

      cp = file->buf + file->ptr;
      while (*cp && *cp != '\n') {
            cp++;
            s++;
      }
      ret = malloc(s+1);
      if (!ret)
            return 0;
      ret[s]=0;
      memcpy(ret, file->buf + file->ptr, s);
      while (*cp && (*cp == '\n' || *cp == '\r')) {
            cp++;
            s++;
      }
      file->ptr += s;
      return ret;
}

static int mem_file_eof(struct mem_file *file)
{
      return (file->ptr >= file->size);
}

/*
 * fstab parsing code
 */
static char *string_copy(const char *s)
{
      char  *ret;

      if (!s)
            return 0;
      ret = malloc(strlen(s)+1);
      if (ret)
            strcpy(ret, s);
      return ret;
}

static char *skip_over_blank(char *cp)
{
      while (*cp && isspace(*cp))
            cp++;
      return cp;
}

static char *skip_over_word(char *cp)
{
      while (*cp && !isspace(*cp))
            cp++;
      return cp;
}

static char *parse_word(char **buf)
{
      char *word, *next;

      word = *buf;
      if (*word == 0)
            return 0;

      word = skip_over_blank(word);
      next = skip_over_word(word);
      if (*next)
            *next++ = 0;
      *buf = next;
      return word;
}

static void parse_escape(char *word)
{
      char  *p, *q;
      int   ac, i;

      if (!word)
            return;

      for (p = word, q = word; *p; p++, q++) {
            *q = *p;
            if (*p != '\\')
                  continue;
            if (*++p == 0)
                  break;
            if (*p == 't') {
                  *q = '\t';
                  continue;
            }
            if (*p == 'n') {
                  *q = '\n';
                  continue;
            }
            if (!isdigit(*p)) {
                  *q = *p;
                  continue;
            }
            ac = 0;
            for (i = 0; i < 3; i++, p++) {
                  if (!isdigit(*p))
                        break;
                  ac = (ac * 8) + (*p - '0');
            }
            *q = ac;
            p--;
      }
      *q = 0;
}

static int parse_fstab_line(char *line, struct fs_info *fs)
{
      char  *dev, *device, *mntpnt, *type, *opts, *freq, *passno, *cp;

      if ((cp = strchr(line, '#')))
            *cp = 0;    /* Ignore everything after the comment char */
      cp = line;

      device = parse_word(&cp);
      mntpnt = parse_word(&cp);
      type = parse_word(&cp);
      opts = parse_word(&cp);
      freq = parse_word(&cp);
      passno = parse_word(&cp);

      if (!device)
            return -1;  /* Allow blank lines */
      
      if (!mntpnt || !type)
            return -1;

      parse_escape(device);
      parse_escape(mntpnt);
      parse_escape(type);
      parse_escape(opts);
      parse_escape(freq);
      parse_escape(passno);

      dev = blkid_get_devname(cache, device, NULL);
      if (dev)
            device = dev;

      if (strchr(type, ','))
            type = 0;

      fs->device = string_copy(device);
      fs->mountpt = string_copy(mntpnt);
      fs->type = string_copy(type);
      fs->opts = string_copy(opts ? opts : "");
      fs->freq = freq ? atoi(freq) : -1;
      fs->passno = passno ? atoi(passno) : -1;
      fs->flags = 0;
      fs->next = NULL;

      if (dev)
            free(dev);
         
      return 0;
}

static void free_fstab_line(struct fs_info *fs)
{
      if (fs->device)
            fs->device = 0;
      if (fs->mountpt)
            fs->mountpt = 0;
      if (fs->type)
            fs->type = 0;
      if (fs->opts)
            fs->opts = 0;
      memset(fs, 0, sizeof(struct fs_info));
}


static void PRS(int argc, char **argv)
{
      int c;

#ifdef ENABLE_NLS
      setlocale(LC_MESSAGES, "");
      setlocale(LC_CTYPE, "");
      bindtextdomain(NLS_CAT_NAME, LOCALEDIR);
      textdomain(NLS_CAT_NAME);
#endif

      while ((c = getopt(argc, argv, "rv")) != EOF) {
            switch (c) {
            case 'r':
                  root_type++;
                  break;

            case 'v':
                  printf("%s %s (%s)\n", program_name, 
                         E2FSPROGS_VERSION, E2FSPROGS_DATE);
                  break;
            default:
                  usage();
            }
      }
      if (optind < argc - 1 || optind == argc)
            usage();
      device_name = blkid_get_devname(NULL, argv[optind], NULL);
      if (!device_name) {
            com_err("tune2fs", 0, _("Unable to resolve '%s'"), 
                  argv[optind]);
            exit(1);
      }
}

static void get_root_type(ext2_filsys fs)
{
      errcode_t retval;
      struct mem_file file;
      char        *buf;
      struct fs_info fs_info;
      int         ret;

      retval = get_file(fs, "/etc/fstab", &file);

      while (!mem_file_eof(&file)) {
            buf = get_line(&file);
            if (!buf)
                  continue;
            
            ret = parse_fstab_line(buf, &fs_info);
            if (ret < 0) 
                  goto next_line;

            if (!strcmp(fs_info.mountpt, "/"))
                  printf("%s\n", fs_info.type);

            free_fstab_line(&fs_info);

      next_line:
            free(buf);
      }
}


int main (int argc, char ** argv)
{
      errcode_t retval;
      ext2_filsys fs;
      io_manager io_ptr;

      initialize_ext2_error_table();

      blkid_get_cache(&cache, NULL);
      PRS(argc, argv);
      
#ifdef CONFIG_TESTIO_DEBUG
      io_ptr = test_io_manager;
      test_io_backing_manager = unix_io_manager;
#else
      io_ptr = unix_io_manager;
#endif
      retval = ext2fs_open (device_name, open_flag, 0, 0, io_ptr, &fs);
        if (retval)
            exit(1);

      if (root_type) 
            get_root_type(fs);

      return (ext2fs_close (fs) ? 1 : 0);
}

Generated by  Doxygen 1.6.0   Back to index