📄 iso9660.c
字号:
cdio_assert (offset == dsize); offset = ofs_last_rec; } /* be sure we don't cross sectors boundaries */ offset = _cdio_ofs_add (offset, length, ISO_BLOCKSIZE); offset -= length; cdio_assert (offset + length <= dsize); idr = (iso9660_dir_t *) &dir8[offset]; cdio_assert (offset+length < dsize); memset(idr, 0, length); idr->length = to_711(length); idr->extent = to_733(extent); idr->size = to_733(size); iso9660_set_dtime (gmtime(entry_time), &(idr->recording_time)); idr->file_flags = to_711(file_flags); idr->volume_sequence_number = to_723(1); idr->filename_len = to_711(strlen(filename) ? strlen(filename) : 1); /* working hack! */ memcpy(idr->filename, filename, from_711(idr->filename_len)); memcpy(&dir8[offset] + su_offset, su_data, su_size);}voidiso9660_dir_init_new (void *dir, uint32_t self, uint32_t ssize, uint32_t parent, uint32_t psize, const time_t *dir_time){ iso9660_dir_init_new_su (dir, self, ssize, NULL, 0, parent, psize, NULL, 0, dir_time);}void iso9660_dir_init_new_su (void *dir, uint32_t self, uint32_t ssize, const void *ssu_data, unsigned int ssu_size, uint32_t parent, uint32_t psize, const void *psu_data, unsigned int psu_size, const time_t *dir_time){ cdio_assert (ssize > 0 && !(ssize % ISO_BLOCKSIZE)); cdio_assert (psize > 0 && !(psize % ISO_BLOCKSIZE)); cdio_assert (dir != NULL); memset (dir, 0, ssize); /* "\0" -- working hack due to padding */ iso9660_dir_add_entry_su (dir, "\0", self, ssize, ISO_DIRECTORY, ssu_data, ssu_size, dir_time); iso9660_dir_add_entry_su (dir, "\1", parent, psize, ISO_DIRECTORY, psu_data, psu_size, dir_time);}/* Zero's out pathable. Do this first. */void iso9660_pathtable_init (void *pt){ cdio_assert (sizeof (struct iso_path_table) == 8); cdio_assert (pt != NULL); memset (pt, 0, ISO_BLOCKSIZE); /* fixme */}static const struct iso_path_table*pathtable_get_entry (const void *pt, unsigned int entrynum){ const uint8_t *tmp = pt; unsigned int offset = 0; unsigned int count = 0; cdio_assert (pt != NULL); while (from_711 (*tmp)) { if (count == entrynum) break; cdio_assert (count < entrynum); offset += sizeof (struct iso_path_table); offset += from_711 (*tmp); if (offset % 2) offset++; tmp = (uint8_t *)pt + offset; count++; } if (!from_711 (*tmp)) return NULL; return (const void *) tmp;}voidpathtable_get_size_and_entries (const void *pt, unsigned int *size, unsigned int *entries){ const uint8_t *tmp = pt; unsigned int offset = 0; unsigned int count = 0; cdio_assert (pt != NULL); while (from_711 (*tmp)) { offset += sizeof (struct iso_path_table); offset += from_711 (*tmp); if (offset % 2) offset++; tmp = (uint8_t *)pt + offset; count++; } if (size) *size = offset; if (entries) *entries = count;}unsigned intiso9660_pathtable_get_size (const void *pt){ unsigned int size = 0; pathtable_get_size_and_entries (pt, &size, NULL); return size;}uint16_t iso9660_pathtable_l_add_entry (void *pt, const char name[], uint32_t extent, uint16_t parent){ struct iso_path_table *ipt = (struct iso_path_table*)((char *)pt + iso9660_pathtable_get_size (pt)); size_t name_len = strlen (name) ? strlen (name) : 1; unsigned int entrynum = 0; cdio_assert (iso9660_pathtable_get_size (pt) < ISO_BLOCKSIZE); /*fixme */ memset (ipt, 0, sizeof (struct iso_path_table) + name_len); /* paranoia */ ipt->name_len = to_711 (name_len); ipt->extent = to_731 (extent); ipt->parent = to_721 (parent); memcpy (ipt->name, name, name_len); pathtable_get_size_and_entries (pt, NULL, &entrynum); if (entrynum > 1) { const struct iso_path_table *ipt2 = pathtable_get_entry (pt, entrynum - 2); cdio_assert (ipt2 != NULL); cdio_assert (from_721 (ipt2->parent) <= parent); } return entrynum;}uint16_t iso9660_pathtable_m_add_entry (void *pt, const char name[], uint32_t extent, uint16_t parent){ struct iso_path_table *ipt = (struct iso_path_table*)((char *)pt + iso9660_pathtable_get_size (pt)); size_t name_len = strlen (name) ? strlen (name) : 1; unsigned int entrynum = 0; cdio_assert (iso9660_pathtable_get_size(pt) < ISO_BLOCKSIZE); /* fixme */ memset(ipt, 0, sizeof (struct iso_path_table) + name_len); /* paranoia */ ipt->name_len = to_711 (name_len); ipt->extent = to_732 (extent); ipt->parent = to_722 (parent); memcpy (ipt->name, name, name_len); pathtable_get_size_and_entries (pt, NULL, &entrynum); if (entrynum > 1) { const struct iso_path_table *ipt2 = pathtable_get_entry (pt, entrynum - 2); cdio_assert (ipt2 != NULL); cdio_assert (from_722 (ipt2->parent) <= parent); } return entrynum;}/*! Check that pathname is a valid ISO-9660 directory name. A valid directory name should not start out with a slash (/), dot (.) or null byte, should be less than 37 characters long, have no more than 8 characters in a directory component which is separated by a /, and consist of only DCHARs. */booliso9660_dirname_valid_p (const char pathname[]){ const char *p = pathname; int len; cdio_assert (pathname != NULL); if (*p == '/' || *p == '.' || *p == '\0') return false; if (strlen (pathname) > MAX_ISOPATHNAME) return false; len = 0; for (; *p; p++) if (iso9660_isdchar (*p)) { len++; if (len > 8) return false; } else if (*p == '/') { if (!len) return false; len = 0; } else return false; /* unexpected char */ if (!len) return false; /* last char may not be '/' */ return true;}/*! Check that pathname is a valid ISO-9660 pathname. A valid pathname contains a valid directory name, if one appears and the filename portion should be no more than 8 characters for the file prefix and 3 characters in the extension (or portion after a dot). There should be exactly one dot somewhere in the filename portion and the filename should be composed of only DCHARs. True is returned if pathname is valid. */booliso9660_pathname_valid_p (const char pathname[]){ const char *p = NULL; cdio_assert (pathname != NULL); if ((p = strrchr (pathname, '/'))) { bool rc; char *_tmp = strdup (pathname); *strrchr (_tmp, '/') = '\0'; rc = iso9660_dirname_valid_p (_tmp); free (_tmp); if (!rc) return false; p++; } else p = pathname; if (strlen (pathname) > (MAX_ISOPATHNAME - 6)) return false; { int len = 0; int dots = 0; for (; *p; p++) if (iso9660_isdchar (*p)) { len++; if (dots == 0 ? len > 8 : len > 3) return false; } else if (*p == '.') { dots++; if (dots > 1) return false; if (!len) return false; len = 0; } else return false; if (dots != 1) return false; } return true;}/*! Take pathname and a version number and turn that into a ISO-9660 pathname. (That's just the pathname followd by ";" and the version number. For example, mydir/file.ext -> mydir/file.ext;1 for version 1. The resulting ISO-9660 pathname is returned.*/char *iso9660_pathname_isofy (const char pathname[], uint16_t version){ char tmpbuf[1024] = { 0, }; cdio_assert (strlen (pathname) < (sizeof (tmpbuf) - sizeof (";65535"))); snprintf (tmpbuf, sizeof(tmpbuf), "%s;%d", pathname, version); return strdup (tmpbuf);}/*! Return the PVD's application ID. NULL is returned if there is some problem in getting this. */char * iso9660_get_application_id(iso9660_pvd_t *p_pvd){ if (NULL==p_pvd) return NULL; return strdup(strip_trail(p_pvd->application_id, ISO_MAX_APPLICATION_ID));}#if FIXMElsn_tiso9660_get_dir_extent(const iso9660_dir_t *idr) { if (NULL == idr) return 0; return from_733(idr->extent);}#endifuint8_tiso9660_get_dir_len(const iso9660_dir_t *idr) { if (NULL == idr) return 0; return idr->length;}#if FIXMEuint8_tiso9660_get_dir_size(const iso9660_dir_t *idr) { if (NULL == idr) return 0; return from_733(idr->size);}#endifuint8_tiso9660_get_pvd_type(const iso9660_pvd_t *pvd) { if (NULL == pvd) return 255; return(pvd->type);}const char *iso9660_get_pvd_id(const iso9660_pvd_t *pvd) { if (NULL == pvd) return "ERR"; return(pvd->id);}intiso9660_get_pvd_space_size(const iso9660_pvd_t *pvd) { if (NULL == pvd) return 0; return from_733(pvd->volume_space_size);}intiso9660_get_pvd_block_size(const iso9660_pvd_t *pvd) { if (NULL == pvd) return 0; return from_723(pvd->logical_block_size);}/*! Return the primary volume id version number (of pvd). If there is an error 0 is returned. */intiso9660_get_pvd_version(const iso9660_pvd_t *pvd) { if (NULL == pvd) return 0; return pvd->version;}/*! Return the LSN of the root directory for pvd. If there is an error CDIO_INVALID_LSN is returned. */lsn_tiso9660_get_root_lsn(const iso9660_pvd_t *pvd) { if (NULL == pvd) return CDIO_INVALID_LSN; else { const iso9660_dir_t *idr = &(pvd->root_directory_record); if (NULL == idr) return CDIO_INVALID_LSN; return(from_733 (idr->extent)); }}/*! Return a string containing the preparer id with trailing blanks removed.*/char *iso9660_get_preparer_id(const iso9660_pvd_t *pvd){ if (NULL==pvd) return NULL; return strdup(strip_trail(pvd->preparer_id, ISO_MAX_PREPARER_ID));}/*! Return a string containing the publisher id with trailing blanks removed.*/char *iso9660_get_publisher_id(const iso9660_pvd_t *pvd){ if (NULL==pvd) return NULL; return strdup(strip_trail(pvd->publisher_id, ISO_MAX_PUBLISHER_ID));}/*! Return a string containing the PVD's system id with trailing blanks removed.*/char *iso9660_get_system_id(const iso9660_pvd_t *pvd){ if (NULL==pvd) return NULL; return strdup(strip_trail(pvd->system_id, ISO_MAX_SYSTEM_ID));}/*! Return the PVD's volume ID.*/char *iso9660_get_volume_id(const iso9660_pvd_t *pvd) { if (NULL == pvd) return NULL; return strdup(strip_trail(pvd->volume_id, ISO_MAX_VOLUME_ID));}/*! Return the PVD's volumeset ID. NULL is returned if there is some problem in getting this. */char *iso9660_get_volumeset_id(const iso9660_pvd_t *pvd){ if ( NULL == pvd ) return NULL; return strdup(strip_trail(pvd->volume_set_id, ISO_MAX_VOLUMESET_ID));}/* * Local variables: * c-file-style: "gnu" * tab-width: 8 * indent-tabs-mode: nil * End: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -