⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 imfs_load_tar.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
字号:
/* * $Id: imfs_load_tar.c,v 1.6 2002/01/08 12:05:36 joel Exp $ */#if HAVE_CONFIG_H#include "config.h"#endif/************************************************************************** * This file implements the "mount" procedure for tar-based IMFS * extensions.  The TAR is not actually mounted under the IMFS. * Directories from the TAR file are created as usual in the IMFS. * File entries are created as IMFS_LINEAR_FILE nodes with their nods * pointing to addresses in the TAR image. *************************************************************************/#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <string.h>#include <rtems.h>#include <rtems/libio_.h>#include <chain.h>#include <imfs.h>/************************************************************************** * TAR file format: * *   Offset   Length   Contents *     0    100 bytes  File name ('\0' terminated, 99 maxmum length) *   100      8 bytes  File mode (in octal ascii) *   108      8 bytes  User ID (in octal ascii) *   116      8 bytes  Group ID (in octal ascii) *   124     12 bytes  File size (s) (in octal ascii) *   136     12 bytes  Modify time (in octal ascii) *   148      8 bytes  Header checksum (in octal ascii) *   156      1 bytes  Link flag *   157    100 bytes  Linkname ('\0' terminated, 99 maxmum length) *   257      8 bytes  Magic ("ustar  \0") *   265     32 bytes  User name ('\0' terminated, 31 maxmum length) *   297     32 bytes  Group name ('\0' terminated, 31 maxmum length) *   329      8 bytes  Major device ID (in octal ascii) *   337      8 bytes  Minor device ID (in octal ascii) *   345    167 bytes  Padding *   512   (s+p)bytes  File contents (s+p) := (((s) + 511) & ~511), *                     round up to 512 bytes *  *   Checksum: *   int i, sum; *   char* header = tar_header_pointer; *   sum = 0; *   for(i = 0; i < 512; i++) *       sum += 0xFF & header[i]; *************************************************************************/#define LF_OLDNORMAL  '\0'     /* Normal disk file, Unix compatible */#define LF_NORMAL     '0'      /* Normal disk file                  */#define LF_LINK       '1'      /* Link to previously dumped file    */#define LF_SYMLINK    '2'      /* Symbolic link                     */#define LF_CHR        '3'      /* Character special file            */#define LF_BLK        '4'      /* Block special file                */#define LF_DIR        '5'      /* Directory                         */#define LF_FIFO       '6'      /* FIFO special file                 */#define LF_CONFIG     '7'      /* Contiguous file                   */#define MAX_NAME_FIELD_SIZE      99#define MIN(a,b)   ((a)>(b)?(b):(a))static unsigned long octal2ulong(char *octascii, int len);static int compute_tar_header_checksum(char *bufr);/************************************************************************** * rtems_tarfs_load * * Here we create the mountpoint directory and load the tarfs at * that node.  Once the IMFS has been mounted, we work through the * tar image and perform as follows: *  - For directories, simply call mkdir().  The IMFS creates nodes as *    needed. *  - For files, we make our own calls to IMFS eval_for_make and  *    create_node. *************************************************************************/intrtems_tarfs_load(char *mountpoint,                 unsigned char *tar_image,                 unsigned long tar_size){   rtems_filesystem_location_info_t root_loc;   rtems_filesystem_location_info_t loc;   char            *hdr_ptr;   char            filename[100];   char            full_filename[256];   int             hdr_chksum;   unsigned char   linkflag;   unsigned long   file_size;   unsigned long   file_mode;   int             offset;   unsigned long   nblocks;   IMFS_jnode_t    *node;   int             status;   status = rtems_filesystem_evaluate_path(mountpoint, 0, &root_loc, 0);   if (status != 0)      return(-1);   if (root_loc.ops != &IMFS_ops)      return(-1);   /***********************************************************************    * Create an IMFS node structure pointing to tar image memory.    **********************************************************************/   offset = 0;   while (1)   {      if (offset + 512 > tar_size)         break;      /******************************************************************       * Read a header.       ******************************************************************/      hdr_ptr = &tar_image[offset];      offset += 512;      if (strncmp(&hdr_ptr[257], "ustar  ", 7))         break;      strncpy(filename, hdr_ptr, MAX_NAME_FIELD_SIZE);      filename[MAX_NAME_FIELD_SIZE] = '\0';      linkflag   = hdr_ptr[156];      file_mode  = octal2ulong(&hdr_ptr[100], 8);      file_size  = octal2ulong(&hdr_ptr[124], 12);      hdr_chksum = (int)octal2ulong(&hdr_ptr[148], 8);      if (compute_tar_header_checksum(hdr_ptr) != hdr_chksum)         break;      /******************************************************************       * Generate an IMFS node depending on the file type.       * - For directories, just create directories as usual.  IMFS        *   will take care of the rest.       * - For files, create a file node with special tarfs properties.       *****************************************************************/      if (linkflag == LF_DIR)      {         strcpy(full_filename, mountpoint);         if (full_filename[strlen(full_filename)-1] != '/')            strcat(full_filename, "/");         strcat(full_filename, filename);         mkdir(full_filename, S_IRWXU | S_IRWXG | S_IRWXO);      }      /******************************************************************       * Create a LINEAR_FILE node if no user write permission.       *****************************************************************/      else if ((linkflag == LF_NORMAL) &&               ((file_mode & 0200) == 0000))      {         const char  *name;         loc = root_loc;         if (IMFS_evaluate_for_make(filename, &loc, &name) == 0)         {            node = IMFS_create_node(&loc,                                    IMFS_LINEAR_FILE, (char *)name,                                    (S_IRUSR | S_IRGRP | S_IROTH) | S_IFREG,                                    NULL);            node->info.linearfile.size   = file_size;            node->info.linearfile.direct = &tar_image[offset];         }         nblocks = (((file_size) + 511) & ~511) / 512;         offset += 512 * nblocks;      }      /******************************************************************       * Create a regular MEMORY_FILE if write permission exists.       *****************************************************************/      else if ((linkflag == LF_NORMAL) &&               ((file_mode & 0200) == 0200))      {         int fd;         int n, left, ptr;         strcpy(full_filename, mountpoint);         if (full_filename[strlen(full_filename)-1] != '/')            strcat(full_filename, "/");         strcat(full_filename, filename);         fd = creat(full_filename, S_IRUSR|S_IWUSR | S_IRGRP|S_IWGRP);         if (fd != -1)         {            left = file_size;            ptr  = offset;            while ((n = write(fd, &tar_image[ptr], left)) > 0)            {               left -= n;               ptr += n;            }            close(fd);         }         nblocks = (((file_size) + 511) & ~511) / 512;         offset += 512 * nblocks;      }   }   return(status);}/************************************************************************** * This converts octal ASCII number representations into an * unsigned long.  Only support 32-bit numbers for now. *************************************************************************/static unsigned longoctal2ulong(char *octascii, int len){   int           i;   unsigned long num;   unsigned long mult;   num = 0;   mult = 1;   for (i=len-1; i>=0; i--)   {      if (octascii[i] < '0')          continue;      if (octascii[i] > '9')         continue;      num  += mult*((unsigned long)(octascii[i] - '0'));      mult *= 8;   }   return(num);}/************************************************************************ * Compute the TAR checksum and check with the value in  * the archive.  The checksum is computed over the entire * header, but the checksum field is substituted with blanks. ************************************************************************/static intcompute_tar_header_checksum(char *bufr){   int  i, sum;   sum = 0;   for (i=0; i<512; i++)   {      if ((i >= 148) && (i < 156))         sum += 0xff & ' ';      else         sum += 0xff & bufr[i];   }   return(sum);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -