📄 rock.c
字号:
/* * File rock.c - generate RRIP records for iso9660 filesystems. Written by Eric Youngdale (1993). Copyright 1993 Yggdrasil Computing, Incorporated This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */static char rcsid[] ="$Id: rock.c,v 1.8 1999/03/02 03:41:26 eric Exp $";#include "config.h"#include <stdlib.h>#include <unixstd.h>#include <device.h>#include "mkisofs.h"#include "iso9660.h"#include <string.h>#ifdef DOESNT_WORK#ifdef NON_UNIXFS/* * This is the dead code */#define S_ISLNK(m) (0)#else#ifndef S_ISLNK#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)#endif#endif#else/* * This is the new code */#include <statdefs.h>#endif#ifdef USE_LIBSCHILY#include <standard.h>#endif#define SU_VERSION 1#define SL_ROOT 8#define SL_PARENT 4#define SL_CURRENT 2#define SL_CONTINUE 1#define CE_SIZE 28#define CL_SIZE 12#define ER_SIZE 8#define NM_SIZE 5#define PL_SIZE 12#define PN_SIZE 20#define PX_SIZE 36#define RE_SIZE 4#define SL_SIZE 20#define ZZ_SIZE 15#ifdef __QNX__#define TF_SIZE (5 + 4 * 7)#else#define TF_SIZE (5 + 3 * 7)#endif/* If we need to store this number of bytes, make sure we do not box ourselves in so that we do not have room for a CE entry for the continuation record */#define MAYBE_ADD_CE_ENTRY(BYTES) \ (BYTES + CE_SIZE + currlen + (ipnt - recstart) > reclimit ? 1 : 0) /* * Buffer to build RR attributes */static unsigned char Rock[16384];static unsigned char symlink_buff[256];static int ipnt = 0;static int recstart = 0;static int currlen = 0;static int mainrec = 0;static int reclimit;static void add_CE_entry __PR((void));static void add_CE_entry(){ if(recstart) set_733((char*)Rock + recstart - 8, ipnt + 28 - recstart); Rock[ipnt++] ='C'; Rock[ipnt++] ='E'; Rock[ipnt++] = CE_SIZE; Rock[ipnt++] = SU_VERSION; set_733((char*)Rock + ipnt, 0); ipnt += 8; set_733((char*)Rock + ipnt, 0); ipnt += 8; set_733((char*)Rock + ipnt, 0); ipnt += 8; recstart = ipnt; currlen = 0; if(!mainrec) mainrec = ipnt; reclimit = SECTOR_SIZE - 8; /* Limit to one sector */}#ifdef __STDC__int generate_rock_ridge_attributes (char * whole_name, char * name, struct directory_entry * s_entry, struct stat * statbuf, struct stat * lstatbuf, int deep_opt)#elseint generate_rock_ridge_attributes (whole_name, name, s_entry, statbuf, lstatbuf, deep_opt)char * whole_name; char * name; struct directory_entry * s_entry;struct stat * statbuf, *lstatbuf;int deep_opt;#endif{ int flagpos, flagval; int need_ce; statbuf = statbuf; /* this shuts up unreferenced compiler warnings */ mainrec = recstart = ipnt = 0; reclimit = 0xf8; /* no need to fill in the RR stuff if we won't see the file */ if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) return 0; /* Obtain the amount of space that is currently used for the directory record. Assume max for name, since name conflicts may cause us to rename the file later on */ currlen = sizeof(s_entry->isorec); /* Identify that we are using the SUSP protocol */ if(deep_opt & NEED_SP){ Rock[ipnt++] ='S'; Rock[ipnt++] ='P'; Rock[ipnt++] = 7; Rock[ipnt++] = SU_VERSION; Rock[ipnt++] = 0xbe; Rock[ipnt++] = 0xef; Rock[ipnt++] = 0; }; /* First build the posix name field */ Rock[ipnt++] ='R'; Rock[ipnt++] ='R'; Rock[ipnt++] = 5; Rock[ipnt++] = SU_VERSION; flagpos = ipnt; flagval = 0; Rock[ipnt++] = 0; /* We go back and fix this later */ if(strcmp(name,".") && strcmp(name,"..")){ char * npnt; int remain, use; remain = strlen(name); npnt = name; while(remain){ use = remain; need_ce = 0; /* Can we fit this SUSP and a CE entry? */ if(use + currlen + CE_SIZE + (ipnt - recstart) > reclimit) { use = reclimit - currlen - CE_SIZE - (ipnt - recstart); need_ce++; } /* Only room for 256 per SUSP field */ if(use > 0xf8) use = 0xf8; /* First build the posix name field */ Rock[ipnt++] ='N'; Rock[ipnt++] ='M'; Rock[ipnt++] = NM_SIZE + use; Rock[ipnt++] = SU_VERSION; Rock[ipnt++] = (remain != use ? 1 : 0); flagval |= (1<<3); strncpy((char *)&Rock[ipnt], npnt, use); npnt += use; ipnt += use; remain -= use; if(remain && need_ce) add_CE_entry(); }; }; /* * Add the posix modes */ if(MAYBE_ADD_CE_ENTRY(PX_SIZE)) add_CE_entry(); Rock[ipnt++] ='P'; Rock[ipnt++] ='X'; Rock[ipnt++] = PX_SIZE; Rock[ipnt++] = SU_VERSION; flagval |= (1<<0); set_733((char*)Rock + ipnt, lstatbuf->st_mode); ipnt += 8; set_733((char*)Rock + ipnt, lstatbuf->st_nlink); ipnt += 8; set_733((char*)Rock + ipnt, lstatbuf->st_uid); ipnt += 8; set_733((char*)Rock + ipnt, lstatbuf->st_gid); ipnt += 8; /* * Check for special devices */#if defined(S_IFCHR) || defined(S_IFBLK)#ifndef NON_UNIXFS if (S_ISCHR(lstatbuf->st_mode) || S_ISBLK(lstatbuf->st_mode)) { if(MAYBE_ADD_CE_ENTRY(PN_SIZE)) add_CE_entry(); Rock[ipnt++] ='P'; Rock[ipnt++] ='N'; Rock[ipnt++] = PN_SIZE; Rock[ipnt++] = SU_VERSION; flagval |= (1<<1);#if 1 /* * This is the new and only code which uses <device.h> */ set_733((char*)Rock + ipnt, major(lstatbuf->st_rdev )); ipnt += 8; set_733((char*)Rock + ipnt, minor(lstatbuf->st_rdev)); ipnt += 8;#else /* * If we don't have sysmacros.h, then we have to guess as to how * best to pick apart the device number for major/minor. * Note: this may very well be wrong for many systems, so * it is always best to use the major/minor macros if the * system supports it. */ if(sizeof(dev_t) <= 2) { set_733((char*)Rock + ipnt, (lstatbuf->st_rdev >> 8)); ipnt += 8; set_733((char*)Rock + ipnt, lstatbuf->st_rdev & 0xff); ipnt += 8; } else if(sizeof(dev_t) <= 4) { set_733((char*)Rock + ipnt, (lstatbuf->st_rdev >> 8) >> 8); ipnt += 8; set_733((char*)Rock + ipnt, lstatbuf->st_rdev & 0xffff); ipnt += 8; } else { set_733((char*)Rock + ipnt, (lstatbuf->st_rdev >> 16) >> 16); ipnt += 8; set_733((char*)Rock + ipnt, lstatbuf->st_rdev); ipnt += 8; }#endif };#endif#endif /* defined(S_IFCHR) || defined(S_IFBLK) */ /* * Check for and symbolic links. VMS does not have these. */#ifdef S_IFLNK if (S_ISLNK(lstatbuf->st_mode)){ int lenpos, lenval, j0, j1; int nchar; unsigned char * cpnt, *cpnt1;#ifdef HAVE_READLINK nchar = readlink(whole_name, (char *)symlink_buff, sizeof(symlink_buff));#else nchar = -1;#endif /* HAVE_READLINK */ symlink_buff[nchar < 0 ? 0 : nchar] = 0; nchar = strlen((char *) symlink_buff); set_733(s_entry->isorec.size, 0); cpnt = &symlink_buff[0]; flagval |= (1<<2); if (! split_SL_field) { int sl_bytes = 0; for (cpnt1 = cpnt; *cpnt1 != '\0'; cpnt1++) { if (*cpnt1 == '/') { sl_bytes += 4; } else { sl_bytes += 1; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -