📄 rock.c
字号:
/* @(#)rock.c 1.25 00/05/07 joerg */#ifndef lintstatic char sccsid[] = "@(#)rock.c 1.25 00/05/07 joerg";#endif/* * 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. */#include "config.h"#include <stdlib.h>#include <unixstd.h>#include <device.h>#include "mkisofs.h"#include "iso9660.h"#include <strdefs.h>#include <statdefs.h>#ifdef USE_LIBSCHILY#include <standard.h>#include <schily.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 APPLE_HYB#define AA_SIZE 14 /* size of Apple extension */#endif /* APPLE_HYB */#ifdef __QNX__#define TF_SIZE (5 + 4 * 7)#else#define TF_SIZE (5 + 3 * 7)#endif#ifdef APPLE_HYBstatic void rstrncpy __PR((char *t, char *f, int c));#endifstatic void add_CE_entry __PR((void)); int generate_rock_ridge_attributes __PR((char *whole_name, char *name, struct directory_entry * s_entry, struct stat * statbuf, struct stat * lstatbuf, int deep_opt)); char * generate_rr_extension_record __PR((char *id, char *descriptor, char *source, int *size));/* * 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;#ifdef APPLE_HYB/* if we are using the HFS name, we don't want the '/' character */static voidrstrncpy(t, f, c) char *t; char *f; int c;{ while (c-- && *f) { switch (*f) { case '/': *t = '_'; break; default: *t = *f; break; } t++; f++; }}#endif /* APPLE HYB */static voidadd_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__intgenerate_rock_ridge_attributes(char *whole_name, char *name, struct directory_entry * s_entry, struct stat * statbuf, struct stat * lstatbuf, int deep_opt)#elseintgenerate_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);#ifdef APPLE_HYB /* if we have regular file, then add Apple extensions */ if (S_ISREG(lstatbuf->st_mode) && apple_ext && s_entry->hfs_ent) { Rock[ipnt++] = 'A'; /* AppleSignature */ Rock[ipnt++] = 'A'; Rock[ipnt++] = AA_SIZE; /* includes AppleSignature bytes */ Rock[ipnt++] = 0x02; /* SystemUseID */ Rock[ipnt++] = s_entry->hfs_ent->u.file.type[0]; Rock[ipnt++] = s_entry->hfs_ent->u.file.type[1]; Rock[ipnt++] = s_entry->hfs_ent->u.file.type[2]; Rock[ipnt++] = s_entry->hfs_ent->u.file.type[3]; Rock[ipnt++] = s_entry->hfs_ent->u.file.creator[0]; Rock[ipnt++] = s_entry->hfs_ent->u.file.creator[1]; Rock[ipnt++] = s_entry->hfs_ent->u.file.creator[2]; Rock[ipnt++] = s_entry->hfs_ent->u.file.creator[3]; Rock[ipnt++] = (s_entry->hfs_ent->fdflags >> 8) & 0xff; Rock[ipnt++] = s_entry->hfs_ent->fdflags & 0xff; }#endif /* APPLE_HYB */ /* 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;#ifdef APPLE_HYB /* use the HFS name if it exists */ if (USE_MAC_NAME(s_entry)) { remain = strlen(s_entry->hfs_ent->name); npnt = s_entry->hfs_ent->name; } else {#endif /* APPLE_HYB */ remain = strlen(name); npnt = name;#ifdef APPLE_HYB }#endif /* APPLE_HYB */ 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);#ifdef APPLE_HYB /* filter out any '/' character in HFS filename */ if (USE_MAC_NAME(s_entry)) rstrncpy((char *) &Rock[ipnt], npnt, use); else#endif /* APPLE_HYB */ 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) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -