From 620d5a95b7a3e52073177f3839bb991fbd988a7b Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Wed, 9 Aug 2017 03:09:05 +0100 Subject: [PATCH] Added support for the Cray UNICOS file system (untested). --- .../DiscImageChef.Filesystems.csproj | 1 + DiscImageChef.Filesystems/UNICOS.cs | 289 ++++++++++++++++++ README.md | 1 + 3 files changed, 291 insertions(+) create mode 100644 DiscImageChef.Filesystems/UNICOS.cs diff --git a/DiscImageChef.Filesystems/DiscImageChef.Filesystems.csproj b/DiscImageChef.Filesystems/DiscImageChef.Filesystems.csproj index ceece292c..a2106e795 100644 --- a/DiscImageChef.Filesystems/DiscImageChef.Filesystems.csproj +++ b/DiscImageChef.Filesystems/DiscImageChef.Filesystems.csproj @@ -129,6 +129,7 @@ + diff --git a/DiscImageChef.Filesystems/UNICOS.cs b/DiscImageChef.Filesystems/UNICOS.cs new file mode 100644 index 000000000..31fea99c5 --- /dev/null +++ b/DiscImageChef.Filesystems/UNICOS.cs @@ -0,0 +1,289 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : UNICOS.cs +// Author(s) : Natalia Portillo +// +// Component : Component +// +// --[ Description ] ---------------------------------------------------------- +// +// Identifies the UNICOS filesystem and shows information. +// +// --[ License ] -------------------------------------------------------------- +// +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 2.1 of the +// License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, see . +// +// ---------------------------------------------------------------------------- +// Copyright © 2011-2017 Natalia Portillo +// ****************************************************************************/ + +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Text; +using DiscImageChef.CommonTypes; +using DiscImageChef.Console; +// UNICOS is ILP64 so let's think everything is 64-bit +using dev_t = System.Int64; +using daddr_t = System.Int64; +using time_t = System.Int64; +using blkno_t = System.Int64; +using ino_t = System.Int64; +using extent_t = System.Int64; + +namespace DiscImageChef.Filesystems +{ + public class UNICOS : Filesystem + { + const int NC1MAXPART = 64; + const int NC1MAXIREG = 4; + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct nc1ireg_sb + { + public ushort i_unused; /* reserved */ + public ushort i_nblk; /* number of blocks */ + public uint i_sblk; /* start block number */ + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct nc1fdev_sb + { + public long fd_name; /* Physical device name */ + public uint fd_sblk; /* Start block number */ + public uint fd_nblk; /* Number of blocks */ + [MarshalAs(UnmanagedType.ByValArray, SizeConst = NC1MAXIREG)] + public nc1ireg_sb[] fd_ireg; /* Inode regions */ + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct UNICOS_Superblock + { + public ulong s_magic; /* magic number to indicate file system type */ + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] + public byte[] s_fname; /* file system name */ + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] + public byte[] s_fpack; /* file system pack name */ + public dev_t s_dev; /* major/minor device, for verification */ + + public daddr_t s_fsize; /* size in blocks of entire volume */ + public long s_isize; /* Number of total inodes */ + public long s_bigfile; /* number of bytes at which a file is big */ + public long s_bigunit; /* minimum number of blocks allocated for big files */ + public ulong s_secure; /* security: secure FS label */ + public long s_maxlvl; /* security: maximum security level */ + public long s_minlvl; /* security: minimum security level */ + public long s_valcmp; /* security: valid security compartments */ + public time_t s_time; /* last super block update */ + public blkno_t s_dboff; /* Dynamic block number */ + public ino_t s_root; /* root inode */ + public long s_error; /* Type of file system error detected */ + public blkno_t s_mapoff; /* Start map block number */ + public long s_mapblks; /* Last map block number */ + public long s_nscpys; /* Number of copies of s.b per partition */ + public long s_npart; /* Number of partitions */ + public long s_ifract; /* Ratio of inodes to blocks */ + public extent_t s_sfs; /* SFS only blocks */ + public long s_flag; /* Flag word */ + [MarshalAs(UnmanagedType.ByValArray, SizeConst = NC1MAXPART)] + public nc1fdev_sb s_part; /* Partition descriptors */ + public long s_iounit; /* Physical block size */ + public long s_numiresblks; /* number of inode reservation blocks */ + /* per region (currently 1) */ + /* 0 = 1*(AU) words, n = (n+1)*(AU) words */ + public long s_priparts; /* bitmap of primary partitions */ + public long s_priblock; /* block size of primary partition(s) */ + /* 0 = 1*512 words, n = (n+1)*512 words */ + public long s_prinblks; /* number of 512 wds blocks in primary */ + public long s_secparts; /* bitmap of secondary partitions */ + public long s_secblock; /* block size of secondary partition(s) */ + /* 0 = 1*512 words, n = (n+1)*512 words */ + public long s_secnblks; /* number of 512 wds blocks in secondary */ + public long s_sbdbparts; /* bitmap of partitions with file system data */ + /* including super blocks, dynamic block */ + /* and free block bitmaps (only primary */ + /* partitions may contain these) */ + public long s_rootdparts; /* bitmap of partitions with root directory */ + /* (only primary partitions) */ + public long s_nudparts; /* bitmap of no-user-data partitions */ + /* (only primary partitions) */ + public long s_nsema; /* SFS: # fs semaphores to allocate */ + public long s_priactive; /* bitmap of primary partitions which contain */ + /* active (up to date) dynamic blocks and */ + /* free block bitmaps. All bits set indicate */ + /* that all primary partitions are active, */ + /* and no kernel manipulation of active flag */ + /* is allowed. */ + public long s_sfs_arbiterid;/* SFS Arbiter ID */ + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 91)] + public long[] s_fill; /* reserved */ + } + + const ulong UNICOS_Magic = 0x6e6331667331636e; + const ulong UNICOS_Secure = 0xcd076d1771d670cd; + + public UNICOS() + { + Name = "UNICOS Filesystem Plugin"; + PluginUUID = new Guid("61712F04-066C-44D5-A2A0-1E44C66B33F0"); + CurrentEncoding = Encoding.GetEncoding("iso-8859-15"); + } + + public UNICOS(ImagePlugins.ImagePlugin imagePlugin, Partition partition, Encoding encoding) + { + Name = "UNICOS Filesystem Plugin"; + PluginUUID = new Guid("61712F04-066C-44D5-A2A0-1E44C66B33F0"); + if(encoding == null) + CurrentEncoding = Encoding.GetEncoding("iso-8859-15"); + else + CurrentEncoding = encoding; + } + + public override bool Identify(ImagePlugins.ImagePlugin imagePlugin, Partition partition) + { + if(imagePlugin.GetSectorSize() < 512) + return false; + + UNICOS_Superblock unicosSb = new UNICOS_Superblock(); + + uint sbSize = (uint)((Marshal.SizeOf(unicosSb)) / imagePlugin.GetSectorSize()); + if((Marshal.SizeOf(unicosSb)) % imagePlugin.GetSectorSize() != 0) + sbSize++; + + byte[] sector = imagePlugin.ReadSector(partition.Start, sbSize); + if(sector.Length < Marshal.SizeOf(unicosSb)) + return false; + + unicosSb = BigEndianMarshal.ByteArrayToStructureBigEndian(sector); + + DicConsole.DebugWriteLine("UNICOS plugin", "magic = 0x{0:X16} (expected 0x{1:X16})", unicosSb.s_magic, UNICOS_Magic); + + return unicosSb.s_magic == UNICOS_Magic; + } + + public override void GetInformation(ImagePlugins.ImagePlugin imagePlugin, Partition partition, out string information) + { + information = ""; + if(imagePlugin.GetSectorSize() < 512) + return; + + UNICOS_Superblock unicosSb = new UNICOS_Superblock(); + + uint sbSize = (uint)((Marshal.SizeOf(unicosSb)) / imagePlugin.GetSectorSize()); + if((Marshal.SizeOf(unicosSb)) % imagePlugin.GetSectorSize() != 0) + sbSize++; + + byte[] sector = imagePlugin.ReadSector(partition.Start, sbSize); + if(sector.Length < Marshal.SizeOf(unicosSb)) + return; + + unicosSb = BigEndianMarshal.ByteArrayToStructureBigEndian(sector); + + + if(unicosSb.s_magic != UNICOS_Magic) + return; + + StringBuilder sb = new StringBuilder(); + + sb.AppendLine("UNICOS filesystem"); + if(unicosSb.s_secure == UNICOS_Secure) + sb.AppendLine("Volume is secure"); + sb.AppendFormat("Volume contains {0} partitions", unicosSb.s_npart).AppendLine(); + sb.AppendFormat("{0} bytes per sector", unicosSb.s_iounit).AppendLine(); + sb.AppendLine("4096 bytes per block"); + sb.AppendFormat("{0} data blocks in volume", unicosSb.s_fsize).AppendLine(); + sb.AppendFormat("Root resides on inode {0}", unicosSb.s_root).AppendLine(); + sb.AppendFormat("{0} inodes in volume", unicosSb.s_isize).AppendLine(); + sb.AppendFormat("Volume last updated on {0}", DateHandlers.UNIXToDateTime(unicosSb.s_time)).AppendLine(); + if(unicosSb.s_error > 0) + sb.AppendFormat("Volume is dirty, error code = 0x{0:X16}", unicosSb.s_error).AppendLine(); + sb.AppendFormat("Volume name: {0}", StringHandlers.CToString(unicosSb.s_fname, CurrentEncoding)).AppendLine(); + + information = sb.ToString(); + + xmlFSType = new Schemas.FileSystemType + { + Type = "UNICOS filesystem", + ClusterSize = 4096, + Clusters = unicosSb.s_fsize, + VolumeName = StringHandlers.CToString(unicosSb.s_fname, CurrentEncoding), + ModificationDate = DateHandlers.UNIXToDateTime(unicosSb.s_time), + ModificationDateSpecified = true + }; + xmlFSType.Dirty |= unicosSb.s_error > 0; + } + + public override Errno Mount() + { + return Errno.NotImplemented; + } + + public override Errno Mount(bool debug) + { + return Errno.NotImplemented; + } + + public override Errno Unmount() + { + return Errno.NotImplemented; + } + + public override Errno MapBlock(string path, long fileBlock, ref long deviceBlock) + { + return Errno.NotImplemented; + } + + public override Errno GetAttributes(string path, ref FileAttributes attributes) + { + return Errno.NotImplemented; + } + + public override Errno ListXAttr(string path, ref List xattrs) + { + return Errno.NotImplemented; + } + + public override Errno GetXattr(string path, string xattr, ref byte[] buf) + { + return Errno.NotImplemented; + } + + public override Errno Read(string path, long offset, long size, ref byte[] buf) + { + return Errno.NotImplemented; + } + + public override Errno ReadDir(string path, ref List contents) + { + return Errno.NotImplemented; + } + + public override Errno StatFs(ref FileSystemInfo stat) + { + return Errno.NotImplemented; + } + + public override Errno Stat(string path, ref FileEntryInfo stat) + { + return Errno.NotImplemented; + } + + public override Errno ReadLink(string path, ref string dest) + { + return Errno.NotImplemented; + } + } +} \ No newline at end of file diff --git a/README.md b/README.md index 87dcf2c30..db6750580 100644 --- a/README.md +++ b/README.md @@ -151,6 +151,7 @@ Supported file systems for identification and information only * SmartFileSystem * SolarOS file system * Squash file system +* UNICOS file system * UNIX System V file system * UNIX Version 7 file system * Universal Disk Format (UDF)