1/* 2 * volume_id - reads filesystem label and uuid 3 * 4 * Copyright (C) 2005 Kay Sievers <kay.sievers@vrfy.org> 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License as published by the 8 * Free Software Foundation version 2 of the License. 9 */ 10 11#ifndef _GNU_SOURCE 12#define _GNU_SOURCE 1 13#endif 14 15#ifdef HAVE_CONFIG_H 16# include <config.h> 17#endif 18 19#include <stdio.h> 20#include <stdlib.h> 21#include <unistd.h> 22#include <string.h> 23#include <errno.h> 24#include <ctype.h> 25 26#include "libvolume_id.h" 27#include "util.h" 28 29#define SYSV_NICINOD 100 30#define SYSV_NICFREE 50 31 32struct sysv_super 33{ 34 uint16_t s_isize; 35 uint16_t s_pad0; 36 uint32_t s_fsize; 37 uint16_t s_nfree; 38 uint16_t s_pad1; 39 uint32_t s_free[SYSV_NICFREE]; 40 uint16_t s_ninode; 41 uint16_t s_pad2; 42 uint16_t s_inode[SYSV_NICINOD]; 43 uint8_t s_flock; 44 uint8_t s_ilock; 45 uint8_t s_fmod; 46 uint8_t s_ronly; 47 uint32_t s_time; 48 uint16_t s_dinfo[4]; 49 uint32_t s_tfree; 50 uint16_t s_tinode; 51 uint16_t s_pad3; 52 uint8_t s_fname[6]; 53 uint8_t s_fpack[6]; 54 uint32_t s_fill[12]; 55 uint32_t s_state; 56 uint32_t s_magic; 57 uint32_t s_type; 58} PACKED; 59 60#define XENIX_NICINOD 100 61#define XENIX_NICFREE 100 62 63struct xenix_super { 64 uint16_t s_isize; 65 uint32_t s_fsize; 66 uint16_t s_nfree; 67 uint32_t s_free[XENIX_NICFREE]; 68 uint16_t s_ninode; 69 uint16_t s_inode[XENIX_NICINOD]; 70 uint8_t s_flock; 71 uint8_t s_ilock; 72 uint8_t s_fmod; 73 uint8_t s_ronly; 74 uint32_t s_time; 75 uint32_t s_tfree; 76 uint16_t s_tinode; 77 uint16_t s_dinfo[4]; 78 uint8_t s_fname[6]; 79 uint8_t s_fpack[6]; 80 uint8_t s_clean; 81 uint8_t s_fill[371]; 82 uint32_t s_magic; 83 uint32_t s_type; 84} PACKED; 85 86#define SYSV_SUPERBLOCK_BLOCK 0x01 87#define SYSV_MAGIC 0xfd187e20 88#define XENIX_SUPERBLOCK_BLOCK 0x18 89#define XENIX_MAGIC 0x2b5544 90#define SYSV_MAX_BLOCKSIZE 0x800 91 92int volume_id_probe_sysv(struct volume_id *id, uint64_t off, uint64_t size) 93{ 94 struct sysv_super *vs; 95 struct xenix_super *xs; 96 unsigned int boff; 97 98 info("probing at offset 0x%llx", (unsigned long long) off); 99 100 for (boff = 0x200; boff <= SYSV_MAX_BLOCKSIZE; boff <<= 1) { 101 vs = (struct sysv_super *) 102 volume_id_get_buffer(id, off + (boff * SYSV_SUPERBLOCK_BLOCK), 0x200); 103 if (vs == NULL) 104 return -1; 105 106 if (vs->s_magic == cpu_to_le32(SYSV_MAGIC) || vs->s_magic == cpu_to_be32(SYSV_MAGIC)) { 107 volume_id_set_label_raw(id, vs->s_fname, 6); 108 volume_id_set_label_string(id, vs->s_fname, 6); 109 id->type = "sysv"; 110 goto found; 111 } 112 } 113 114 for (boff = 0x200; boff <= SYSV_MAX_BLOCKSIZE; boff <<= 1) { 115 xs = (struct xenix_super *) 116 volume_id_get_buffer(id, off + (boff + XENIX_SUPERBLOCK_BLOCK), 0x200); 117 if (xs == NULL) 118 return -1; 119 120 if (xs->s_magic == cpu_to_le32(XENIX_MAGIC) || xs->s_magic == cpu_to_be32(XENIX_MAGIC)) { 121 volume_id_set_label_raw(id, xs->s_fname, 6); 122 volume_id_set_label_string(id, xs->s_fname, 6); 123 id->type = "xenix"; 124 goto found; 125 } 126 } 127 128 return -1; 129 130found: 131 volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); 132 return 0; 133} 134