# # CDDL HEADER START # # The contents of this file are subject to the terms of the # Common Development and Distribution License (the "License"). # You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. # See the License for the specific language governing permissions # and limitations under the License. # # When distributing Covered Code, include this CDDL HEADER in each # file and include the License file at usr/src/OPENSOLARIS.LICENSE. # If applicable, add the following below this CDDL HEADER, with the # fields enclosed by brackets "[]" replaced with your own identifying # information: Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END # # # Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # /usr/src/cmd/lib/fs/hsfs is the directory of all ufs specific commands # whose executable reside in $(INSDIR1) and $(INSDIR2). # SUBDIR1= fstyp labelit SUBDIR2= mount SUBDIRS= $(SUBDIR1) $(SUBDIR2) all: TARGET= all install: TARGET= install clean: TARGET= clean clobber: TARGET= clobber catalog: TARGET= catalog # for messaging catalog # POFILE= hsfs.po # Hammerhead: GNU Make % substitution only replaces first %; use foreach. POFILES= $(foreach d,$(SUBDIR2),$(d)/$(d).po) .KEEP_STATE: .PARALLEL: $(SUBDIRS) all: $(SUBDIRS) catalog: $(SUBDIR2) $(RM) $(POFILE) cat $(POFILES) > $(POFILE) install clean clobber: $(SUBDIRS) $(SUBDIRS): FRC @cd $@; pwd; $(MAKE) $(TARGET) FRC: # # CDDL HEADER START # # The contents of this file are subject to the terms of the # Common Development and Distribution License (the "License"). # You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. # See the License for the specific language governing permissions # and limitations under the License. # # When distributing Covered Code, include this CDDL HEADER in each # file and include the License file at usr/src/OPENSOLARIS.LICENSE. # If applicable, add the following below this CDDL HEADER, with the # fields enclosed by brackets "[]" replaced with your own identifying # information: Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END # # # Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # FSTYP_VERS=1 FSTYPE= hsfs LIBPROG= fstyp.so.${FSTYP_VERS} include ../../../../lib/Makefile.lib include ../../Makefile.fstype # There should be a mapfile here MAPFILES = CFLAGS += $(C_PICFLAGS) DYNLIB= $(LIBPROG) LDLIBS += -lnvpair -lc # # Override PMAP dependency # PMAP= # # Rules for making shared objects out of .c files. Works well if # we have a one-to-one mapping. Applies in all cases so far. # .SUFFIXES: .so.${FSTYP_VERS} ${SUFFIXES} .c.so.${FSTYP_VERS}: $(CC) $(CPPFLAGS) $(CFLAGS) $(DYNFLAGS) $(GSHARED) -o $@ $< $(LDLIBS) $(POST_PROCESS_SO) SRCS= ${LIBPROG:%.so.$(FSTYP_VERS)=%.c} CPPFLAGS += -DFSTYP_VERS=${FSTYP_VERS} \ -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 CERRWARN += -Wno-switch .KEEP_STATE: all: $(LIBPROG) install: all $(RM) $(ROOTLIBFSTYPE)/fstyp $(LN) $(ROOTUSRSBIN)/fstyp $(ROOTLIBFSTYPE)/fstyp cstyle: $(CSTYLE) $(SRCS) clean: $(RM) $(LIBPROG) clobber: clean /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* * libfstyp module for hsfs */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include typedef struct fstyp_hsfs { int fd; nvlist_t *attr; char hs_buf[ISO_SECTOR_SIZE]; int hs_pvd_sec_no; char iso_buf[ISO_SECTOR_SIZE]; int iso_pvd_sec_no; char unix_buf[ISO_SECTOR_SIZE]; int unix_pvd_sec_no; int cdroff; int cd_type; } fstyp_hsfs_t; #define GETCDSECTOR(h, buf, secno, nosec) (getdisk(h, buf, \ ((secno)+(h)->cdroff)*ISO_SECTOR_SIZE, \ (nosec)*ISO_SECTOR_SIZE)) #define NELEM(a) sizeof (a) / sizeof (*(a)) static int ckvoldesc(fstyp_hsfs_t *h, int *cd_type); static int findhsvol(fstyp_hsfs_t *h, char *volp); static int findisovol(fstyp_hsfs_t *h, char *volp); static int findunixvol(fstyp_hsfs_t *h, char *volp); static char *get_old_name(char *new); static int rdev_is_a_cd(int rdevfd); static int getdisk(fstyp_hsfs_t *h, char *buf, int daddr, int size); static void copy_string(char *d, char *s, int maxlen); static int is_hsfs(fstyp_hsfs_t *h); static int get_attr(fstyp_hsfs_t *h); int fstyp_mod_init(int fd, off_t offset, fstyp_mod_handle_t *handle); void fstyp_mod_fini(fstyp_mod_handle_t handle); int fstyp_mod_ident(fstyp_mod_handle_t handle); int fstyp_mod_get_attr(fstyp_mod_handle_t handle, nvlist_t **attrp); int fstyp_mod_dump(fstyp_mod_handle_t handle, FILE *fout, FILE *ferr); int fstyp_mod_init(int fd, off_t offset, fstyp_mod_handle_t *handle) { fstyp_hsfs_t *h = (fstyp_hsfs_t *)handle; if (offset != 0) { return (FSTYP_ERR_OFFSET); } if ((h = calloc(1, sizeof (fstyp_hsfs_t))) == NULL) { return (FSTYP_ERR_NOMEM); } h->fd = fd; *handle = (fstyp_mod_handle_t)h; return (0); } void fstyp_mod_fini(fstyp_mod_handle_t handle) { fstyp_hsfs_t *h = (fstyp_hsfs_t *)handle; if (h->attr == NULL) { nvlist_free(h->attr); h->attr = NULL; } free(h); } int fstyp_mod_ident(fstyp_mod_handle_t handle) { fstyp_hsfs_t *h = (fstyp_hsfs_t *)handle; return (is_hsfs(h)); } int fstyp_mod_get_attr(fstyp_mod_handle_t handle, nvlist_t **attrp) { fstyp_hsfs_t *h = (fstyp_hsfs_t *)handle; int error; if (h->attr == NULL) { if (nvlist_alloc(&h->attr, NV_UNIQUE_NAME_TYPE, 0)) { return (FSTYP_ERR_NOMEM); } if ((error = get_attr(h)) != 0) { nvlist_free(h->attr); h->attr = NULL; return (error); } } *attrp = h->attr; return (0); } /* ARGSUSED */ int fstyp_mod_dump(fstyp_mod_handle_t handle, FILE *fout, FILE *ferr) { int error; nvlist_t *attr; nvpair_t *elem = NULL; char *str_value; uint64_t uint64_value; char *name; if ((error = fstyp_mod_get_attr(handle, &attr)) != 0) { return (error); } while ((elem = nvlist_next_nvpair(attr, elem)) != NULL) { /* format is special */ if (strcmp(nvpair_name(elem), "format") == 0) { (void) nvpair_value_string(elem, &str_value); if (strcmp(str_value, "ISO 9660 with UNIX extension") == 0) { (void) fprintf(fout, "CD-ROM is in ISO 9660 format with" " UNIX extension\n"); } else { (void) fprintf(fout, "CD-ROM is in %s" " format\n", str_value); } continue; } if ((name = get_old_name(nvpair_name(elem))) == NULL) { continue; } if (nvpair_type(elem) == DATA_TYPE_STRING) { (void) nvpair_value_string(elem, &str_value); (void) fprintf(fout, "%s: %s\n", name, str_value); } else if (nvpair_type(elem) == DATA_TYPE_UINT64) { (void) nvpair_value_uint64(elem, &uint64_value); (void) fprintf(fout, "%s %llu\n", name, (u_longlong_t)uint64_value); } } return (0); } static char * get_old_name(char *new) { static char *map[] = { "system_id", "System id", "volume_id", "Volume id", "volume_set_id", "Volume set id", "publisher_id", "Publisher id", "data_preparer_id", "Data preparer id", "application_id", "Application id", "copyright_file_id", "Copyright File id", "abstract_file_id", "Abstract File id", "bibliographic_file_id", "Bibliographic File id", "volume_set_size", "Volume set size is", "volume_set_sequence_number", "Volume set sequence number is", "logical_block_size", "Logical block size is", "volume_size", "Volume size is" }; int i; char *old = NULL; for (i = 0; i < NELEM(map) / 2; i++) { if (strcmp(new, map[i * 2]) == 0) { old = map[i * 2 + 1]; break; } } return (old); } /* * findhsvol: check if the disk is in high sierra format * return(1) if found, (0) otherwise * if found, volp will point to the descriptor * */ static int findhsvol(fstyp_hsfs_t *h, char *volp) { int secno; int i; int err; secno = HS_VOLDESC_SEC; if ((err = GETCDSECTOR(h, volp, secno++, 1)) != 0) { return (err); } while (HSV_DESC_TYPE(volp) != VD_EOV) { for (i = 0; i < HSV_ID_STRLEN; i++) if (HSV_STD_ID(volp)[i] != HSV_ID_STRING[i]) goto cantfind; if (HSV_STD_VER(volp) != HSV_ID_VER) goto cantfind; switch (HSV_DESC_TYPE(volp)) { case VD_SFS: h->hs_pvd_sec_no = secno-1; return (0); case VD_EOV: goto cantfind; } if ((err = GETCDSECTOR(h, volp, secno++, 1)) != 0) { return (err); } } cantfind: return (FSTYP_ERR_NO_MATCH); } /* * findisovol: check if the disk is in ISO 9660 format * return(1) if found, (0) otherwise * if found, volp will point to the descriptor * */ static int findisovol(fstyp_hsfs_t *h, char *volp) { int secno; int i; int err; secno = ISO_VOLDESC_SEC; if ((err = GETCDSECTOR(h, volp, secno++, 1)) != 0) { return (err); } while (ISO_DESC_TYPE(volp) != ISO_VD_EOV) { for (i = 0; i < ISO_ID_STRLEN; i++) if (ISO_STD_ID(volp)[i] != ISO_ID_STRING[i]) goto cantfind; if (ISO_STD_VER(volp) != ISO_ID_VER) goto cantfind; switch (ISO_DESC_TYPE(volp)) { case ISO_VD_PVD: h->iso_pvd_sec_no = secno-1; return (0); case ISO_VD_EOV: goto cantfind; } if ((err = GETCDSECTOR(h, volp, secno++, 1)) != 0) { return (err); } } cantfind: return (FSTYP_ERR_NO_MATCH); } /* * findunixvol: check if the disk is in UNIX extension format * return(1) if found, (0) otherwise * if found, volp will point to the descriptor * */ static int findunixvol(fstyp_hsfs_t *h, char *volp) { int secno; int i; int err; secno = ISO_VOLDESC_SEC; if ((err = GETCDSECTOR(h, volp, secno++, 1)) != 0) { return (err); } while (ISO_DESC_TYPE(volp) != ISO_VD_EOV) { for (i = 0; i < ISO_ID_STRLEN; i++) if (ISO_STD_ID(volp)[i] != ISO_ID_STRING[i]) goto cantfind; if (ISO_STD_VER(volp) != ISO_ID_VER) goto cantfind; switch (ISO_DESC_TYPE(volp)) { case ISO_VD_UNIX: h->unix_pvd_sec_no = secno-1; return (0); case ISO_VD_EOV: goto cantfind; } if ((err = GETCDSECTOR(h, volp, secno++, 1)) != 0) { return (err); } } cantfind: return (FSTYP_ERR_NO_MATCH); } static int ckvoldesc(fstyp_hsfs_t *h, int *cd_type) { int err; if ((err = findhsvol(h, h->hs_buf)) == 0) { *cd_type = 0; } else if ((err = findisovol(h, h->iso_buf)) == 0) { if (findunixvol(h, h->unix_buf) == 0) { *cd_type = 2; } else { *cd_type = 1; } } else { *cd_type = -1; } return (err); } static int is_hsfs(fstyp_hsfs_t *h) { #ifdef CDROMREADOFFSET int err; if (rdev_is_a_cd(h->fd)) { err = ioctl(h->fd, CDROMREADOFFSET, &h->cdroff); if (err == -1) /* * This device doesn't support this ioctl. * That's OK. */ h->cdroff = 0; } #endif /* check volume descriptor */ return (ckvoldesc(h, &h->cd_type)); } #define ADD_STRING(h, name, value) \ if (nvlist_add_string(h->attr, name, value) != 0) { \ return (FSTYP_ERR_NOMEM); \ } #define ADD_UINT64(h, name, value) \ if (nvlist_add_uint64(h->attr, name, value) != 0) { \ return (FSTYP_ERR_NOMEM); \ } #define ADD_BOOL(h, name, value) \ if (nvlist_add_boolean_value(h->attr, name, value) != 0) { \ return (FSTYP_ERR_NOMEM); \ } static int get_attr(fstyp_hsfs_t *h) { char *sysid; char *volid; char *volsetid; char *pubid; char *prepid; char *applid; char *copyfile; char *absfile; char *bibfile; int volsetsize; int volsetseq; int blksize; int volsize; char s[256]; switch (h->cd_type) { case 0: ADD_STRING(h, "format", "High Sierra"); ADD_STRING(h, "gen_version", "High Sierra"); sysid = (char *)HSV_sys_id(h->hs_buf); volid = (char *)HSV_vol_id(h->hs_buf); volsetid = (char *)HSV_vol_set_id(h->hs_buf); pubid = (char *)HSV_pub_id(h->hs_buf); prepid = (char *)HSV_prep_id(h->hs_buf); applid = (char *)HSV_appl_id(h->hs_buf); copyfile = (char *)HSV_copyr_id(h->hs_buf); absfile = (char *)HSV_abstr_id(h->hs_buf); bibfile = NULL; volsetsize = HSV_SET_SIZE(h->hs_buf); volsetseq = HSV_SET_SEQ(h->hs_buf); blksize = HSV_BLK_SIZE(h->hs_buf); volsize = HSV_VOL_SIZE(h->hs_buf); break; case 1: ADD_STRING(h, "format", "ISO 9660"); ADD_STRING(h, "gen_version", "ISO 9660"); sysid = (char *)ISO_sys_id(h->iso_buf); volid = (char *)ISO_vol_id(h->iso_buf); volsetid = (char *)ISO_vol_set_id(h->iso_buf); pubid = (char *)ISO_pub_id(h->iso_buf); prepid = (char *)ISO_prep_id(h->iso_buf); applid = (char *)ISO_appl_id(h->iso_buf); copyfile = (char *)ISO_copyr_id(h->iso_buf); absfile = (char *)ISO_abstr_id(h->iso_buf); bibfile = (char *)ISO_bibli_id(h->iso_buf); volsetsize = ISO_SET_SIZE(h->iso_buf); volsetseq = ISO_SET_SEQ(h->iso_buf); blksize = ISO_BLK_SIZE(h->iso_buf); volsize = ISO_VOL_SIZE(h->iso_buf); break; case 2: ADD_STRING(h, "format", "ISO 9660 with UNIX extension"); ADD_STRING(h, "gen_version", "ISO 9660 with UNIX extension"); sysid = (char *)ISO_sys_id(h->unix_buf); volid = (char *)ISO_vol_id(h->unix_buf); volsetid = (char *)ISO_vol_set_id(h->unix_buf); pubid = (char *)ISO_pub_id(h->unix_buf); prepid = (char *)ISO_prep_id(h->unix_buf); applid = (char *)ISO_appl_id(h->unix_buf); copyfile = (char *)ISO_copyr_id(h->unix_buf); absfile = (char *)ISO_abstr_id(h->unix_buf); bibfile = (char *)ISO_bibli_id(h->unix_buf); volsetsize = ISO_SET_SIZE(h->unix_buf); volsetseq = ISO_SET_SEQ(h->unix_buf); blksize = ISO_BLK_SIZE(h->unix_buf); volsize = ISO_VOL_SIZE(h->unix_buf); break; default: return (FSTYP_ERR_NO_MATCH); } copy_string(s, sysid, 32); ADD_STRING(h, "system_id", s); copy_string(s, volid, 32); ADD_STRING(h, "volume_id", s); ADD_STRING(h, "gen_volume_label", s); copy_string(s, volsetid, 128); ADD_STRING(h, "volume_set_id", s); copy_string(s, pubid, 128); ADD_STRING(h, "publisher_id", s); copy_string(s, prepid, 128); ADD_STRING(h, "data_preparer_id", s); copy_string(s, applid, 128); ADD_STRING(h, "application_id", s); copy_string(s, copyfile, 37); ADD_STRING(h, "copyright_file_id", s); copy_string(s, absfile, 37); ADD_STRING(h, "abstract_file_id", s); copy_string(s, bibfile, 37); ADD_STRING(h, "bibliographic_file_id", s); ADD_UINT64(h, "volume_set_size", volsetsize); ADD_UINT64(h, "volume_set_sequence_number", volsetseq); ADD_UINT64(h, "logical_block_size", blksize); ADD_UINT64(h, "volume_size", volsize); ADD_BOOL(h, "gen_clean", B_TRUE); return (0); } static void copy_string(char *d, char *s, int maxlen) { int i; /* strip off trailing zeros */ for (i = maxlen-1; i >= 0; i--) { if (s[i] != ' ') { break; } } maxlen = i+1; for (i = 0; i < maxlen; i++) { *d++ = s[i]; } *d++ = '\0'; } /* readdisk - read from cdrom image file */ static int getdisk(fstyp_hsfs_t *h, char *buf, int daddr, int size) { if (lseek(h->fd, daddr, L_SET) == -1) { return (FSTYP_ERR_IO); } if (read(h->fd, buf, size) != size) { return (FSTYP_ERR_IO); } return (0); } /* * rdev_is_a_cd - return TRUE if the raw device identified by * a file descriptor is a CDROM device. * * return FALSE if the device can't be accessed * or is not a CDROM. */ static int rdev_is_a_cd(int rdevfd) { struct dk_cinfo dkc; if (ioctl(rdevfd, DKIOCINFO, &dkc) < 0) return (0); if (dkc.dki_ctype == DKC_CDROM) return (1); else return (0); } # # CDDL HEADER START # # The contents of this file are subject to the terms of the # Common Development and Distribution License, Version 1.0 only # (the "License"). You may not use this file except in compliance # with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. # See the License for the specific language governing permissions # and limitations under the License. # # When distributing Covered Code, include this CDDL HEADER in each # file and include the License file at usr/src/OPENSOLARIS.LICENSE. # If applicable, add the following below this CDDL HEADER, with the # fields enclosed by brackets "[]" replaced with your own identifying # information: Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END # # # Copyright (c) 1989 by Sun Microsystems, Inc. # # Copyright (c) 2018, Joyent, Inc. FSTYPE= hsfs LIBPROG= labelit ATTMK= $(LIBPROG) include ../../Makefile.fstype CERRWARN += -Wno-switch CERRWARN += -Wno-implicit-function-declaration CERRWARN += -Wno-unused-variable # not linted SMATCH=off /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* * labelit [option=value ...] cdimage * where options are: * sysid system identifier (a characters, 32 max) * volid: volume identifier (d-characters, 32 max) * volsetid: volume set identifier (d-characters, 128 max) * pubid: publisher identifier (d-characters, 128 max) * prepid: data preparer identifier (d-charcter, 128 max) * applid: application identifier (d-charcter, 128 max) * copyfile: copyright file identifier (d-characters, 128 max) * absfile: abstract file identifier (d-characters, 37 max) * bibfile: bibliographic file identifier (d-charcters, 37 max) */ #include #include #include #include #include #include #include #include #include #include #define PUTSECTOR(buf, secno, nosec) (putdisk(buf, (secno)*ISO_SECTOR_SIZE, \ (nosec)*ISO_SECTOR_SIZE)) #define GETSECTOR(buf, secno, nosec) (getdisk(buf, (secno)*ISO_SECTOR_SIZE, \ (nosec)*ISO_SECTOR_SIZE)) char *string; #define MAXERRSTRNG 80 char errstrng[MAXERRSTRNG]; char callname[160]; int cdfd; int cd_type; char hs_buf[ISO_SECTOR_SIZE]; int hs_pvd_sec_no; char iso_buf[ISO_SECTOR_SIZE]; int iso_pvd_sec_no; char unix_buf[ISO_SECTOR_SIZE]; int unix_pvd_sec_no; char *vdp; char *sysid; char *volid; char *volsetid; char *pubid; char *prepid; char *applid; char *copyfile; char *absfile; char *bibfile; int volsetsize; int volsetseq; int blksize; int volsize; static int match(char *s); static void usage(void); static void putdisk(char *buf, int daddr, int size); static void getdisk(char *buf, int daddr, int size); static void prntstring(char *heading, char *s, int maxlen); static void copystring(char *from, char *to, int size); static void prntlabel(void); static void updatelabel(void); static void ckvoldesc(void); int main(int argc, char **argv) { int c; int openopt; strcpy(callname, argv[0]); for (c = 1; c < argc; c++) { string = argv[c]; if (match("sysid=")) { sysid = string; continue; } if (match("volid=")) { volid = string; continue; } if (match("volsetid=")) { volsetid = string; continue; } if (match("pubid=")) { pubid = string; continue; } if (match("prepid=")) { prepid = string; continue; } if (match("applid=")) { applid = string; continue; } if (match("copyfile=")) { copyfile = string; continue; } if (match("absfile=")) { absfile = string; continue; } if (match("bibfile=")) { bibfile = string; continue; } break; } /* the last argument must be the cdrom iamge file */ if (argc != c+1) { if (argc > 1) fprintf(stderr, "%s: Illegal option %s in input\n", callname, string); usage(); } /* open image file in read write only if necessary */ if (argc == 2) openopt = O_RDONLY; else openopt = O_RDWR; if ((cdfd = open(argv[c], openopt)) < 0) { if (strchr(argv[c], '=') || strchr(argv[c], '-')) { usage(); } sprintf(errstrng, "%s: main: open(): ", callname); perror(errstrng); exit(32); } /* check volume descriptor */ (void) ckvoldesc(); if (cd_type < 0) { fprintf(stderr, "%s: unknown cdrom format label\n", callname); exit(32); } /* update label, if needed */ if (argc != 2) updatelabel(); /* print the (updated) image label */ prntlabel(); close(cdfd); return (0); } static void usage(void) { fprintf(stderr, "usage: %s [-F ufs] [option=value ...] cdimage\n", callname); exit(32); } /* * findhsvol: check if the disk is in high sierra format * return(1) if found, (0) otherwise * if found, volp will point to the descriptor * */ int findhsvol(volp) char *volp; { int secno; int i; secno = HS_VOLDESC_SEC; GETSECTOR(volp, secno++, 1); while (HSV_DESC_TYPE(volp) != VD_EOV) { for (i = 0; i < HSV_ID_STRLEN; i++) if (HSV_STD_ID(volp)[i] != HSV_ID_STRING[i]) goto cantfind; if (HSV_STD_VER(volp) != HSV_ID_VER) goto cantfind; switch (HSV_DESC_TYPE(volp)) { case VD_SFS: hs_pvd_sec_no = secno-1; return (1); case VD_EOV: goto cantfind; } GETSECTOR(volp, secno++, 1); } cantfind: return (0); } /* * findisovol: check if the disk is in ISO 9660 format * return(1) if found, (0) otherwise * if found, volp will point to the descriptor * */ int findisovol(volp) char *volp; { int secno; int i; secno = ISO_VOLDESC_SEC; GETSECTOR(volp, secno++, 1); while (ISO_DESC_TYPE(volp) != ISO_VD_EOV) { for (i = 0; i < ISO_ID_STRLEN; i++) if (ISO_STD_ID(volp)[i] != ISO_ID_STRING[i]) goto cantfind; if (ISO_STD_VER(volp) != ISO_ID_VER) goto cantfind; switch (ISO_DESC_TYPE(volp)) { case ISO_VD_PVD: iso_pvd_sec_no = secno-1; return (1); case ISO_VD_EOV: goto cantfind; } GETSECTOR(volp, secno++, 1); } cantfind: return (0); } /* * findunixvol: check if the disk is in UNIX extension format * return(1) if found, (0) otherwise * if found, volp will point to the descriptor * */ int findunixvol(volp) char *volp; { int secno; int i; secno = ISO_VOLDESC_SEC; GETSECTOR(volp, secno++, 1); while (ISO_DESC_TYPE(volp) != ISO_VD_EOV) { for (i = 0; i < ISO_ID_STRLEN; i++) if (ISO_STD_ID(volp)[i] != ISO_ID_STRING[i]) goto cantfind; if (ISO_STD_VER(volp) != ISO_ID_VER) goto cantfind; switch (ISO_DESC_TYPE(volp)) { case ISO_VD_UNIX: unix_pvd_sec_no = secno-1; return (1); case ISO_VD_EOV: goto cantfind; } GETSECTOR(volp, secno++, 1); } cantfind: return (0); } static void ckvoldesc(void) { if (findhsvol(hs_buf)) cd_type = 0; else if (findisovol(iso_buf)) { if (findunixvol(unix_buf)) cd_type = 2; else cd_type = 1; } else { cd_type = -1; } } static void updatelabel(void) { switch (cd_type) { case 0: copystring(sysid, (char *)HSV_sys_id(hs_buf), 32); copystring(volid, (char *)HSV_vol_id(hs_buf), 32); copystring(volsetid, (char *)HSV_vol_set_id(hs_buf), 128); copystring(pubid, (char *)HSV_pub_id(hs_buf), 128); copystring(prepid, (char *)HSV_prep_id(hs_buf), 128); copystring(applid, (char *)HSV_appl_id(hs_buf), 128); copystring(copyfile, (char *)HSV_copyr_id(hs_buf), 37); copystring(absfile, (char *)HSV_abstr_id(hs_buf), 37); PUTSECTOR(hs_buf, hs_pvd_sec_no, 1); break; case 2: copystring(sysid, (char *)ISO_sys_id(unix_buf), 32); copystring(volid, (char *)ISO_vol_id(unix_buf), 32); copystring(volsetid, (char *)ISO_vol_set_id(unix_buf), 128); copystring(pubid, (char *)ISO_pub_id(unix_buf), 128); copystring(prepid, (char *)ISO_prep_id(unix_buf), 128); copystring(applid, (char *)ISO_appl_id(unix_buf), 128); copystring(copyfile, (char *)ISO_copyr_id(unix_buf), 37); copystring(absfile, (char *)ISO_abstr_id(unix_buf), 37); copystring(bibfile, (char *)ISO_bibli_id(unix_buf), 37); PUTSECTOR(unix_buf, unix_pvd_sec_no, 1); /* * after update unix volume descriptor, * fall thru to update the iso primary vol descriptor */ /* FALLTHROUGH */ case 1: copystring(sysid, (char *)ISO_sys_id(iso_buf), 32); copystring(volid, (char *)ISO_vol_id(iso_buf), 32); copystring(volsetid, (char *)ISO_vol_set_id(iso_buf), 128); copystring(pubid, (char *)ISO_pub_id(iso_buf), 128); copystring(prepid, (char *)ISO_prep_id(iso_buf), 128); copystring(applid, (char *)ISO_appl_id(iso_buf), 128); copystring(copyfile, (char *)ISO_copyr_id(iso_buf), 37); copystring(absfile, (char *)ISO_abstr_id(iso_buf), 37); copystring(bibfile, (char *)ISO_bibli_id(iso_buf), 37); PUTSECTOR(iso_buf, iso_pvd_sec_no, 1); break; } } static void prntlabel(void) { int i; switch (cd_type) { case 0: printf("CD-ROM is in High Sierra format\n"); sysid = (char *)HSV_sys_id(hs_buf); volid = (char *)HSV_vol_id(hs_buf); volsetid = (char *)HSV_vol_set_id(hs_buf); pubid = (char *)HSV_pub_id(hs_buf); prepid = (char *)HSV_prep_id(hs_buf); applid = (char *)HSV_appl_id(hs_buf); copyfile = (char *)HSV_copyr_id(hs_buf); absfile = (char *)HSV_abstr_id(hs_buf); bibfile = NULL; volsetsize = HSV_SET_SIZE(hs_buf); volsetseq = HSV_SET_SEQ(hs_buf); blksize = HSV_BLK_SIZE(hs_buf); volsize = HSV_VOL_SIZE(hs_buf); break; case 1: printf("CD-ROM is in ISO 9660 format\n"); sysid = (char *)ISO_sys_id(iso_buf); volid = (char *)ISO_vol_id(iso_buf); volsetid = (char *)ISO_vol_set_id(iso_buf); pubid = (char *)ISO_pub_id(iso_buf); prepid = (char *)ISO_prep_id(iso_buf); applid = (char *)ISO_appl_id(iso_buf); copyfile = (char *)ISO_copyr_id(iso_buf); absfile = (char *)ISO_abstr_id(iso_buf); bibfile = (char *)ISO_bibli_id(iso_buf); volsetsize = ISO_SET_SIZE(iso_buf); volsetseq = ISO_SET_SEQ(iso_buf); blksize = ISO_BLK_SIZE(iso_buf); volsize = ISO_VOL_SIZE(iso_buf); break; case 2: printf("CD-ROM is in ISO 9660 format with UNIX extension\n"); sysid = (char *)ISO_sys_id(unix_buf); volid = (char *)ISO_vol_id(unix_buf); volsetid = (char *)ISO_vol_set_id(unix_buf); pubid = (char *)ISO_pub_id(unix_buf); prepid = (char *)ISO_prep_id(unix_buf); applid = (char *)ISO_appl_id(unix_buf); copyfile = (char *)ISO_copyr_id(unix_buf); absfile = (char *)ISO_abstr_id(unix_buf); bibfile = (char *)ISO_bibli_id(unix_buf); volsetsize = ISO_SET_SIZE(unix_buf); volsetseq = ISO_SET_SEQ(unix_buf); blksize = ISO_BLK_SIZE(unix_buf); volsize = ISO_VOL_SIZE(unix_buf); break; default: return; } /* system id */ prntstring("System id", sysid, 32); /* read volume id */ prntstring("Volume id", volid, 32); /* read volume set id */ prntstring("Volume set id", volsetid, 128); /* publisher id */ prntstring("Publisher id", pubid, 128); /* data preparer id */ prntstring("Data preparer id", prepid, 128); /* application id */ prntstring("Application id", applid, 128); /* copyright file identifier */ prntstring("Copyright File id", copyfile, 37); /* Abstract file identifier */ prntstring("Abstract File id", absfile, 37); /* Bibliographic file identifier */ prntstring("Bibliographic File id", bibfile, 37); /* print volume set size */ printf("Volume set size is %d\n", volsetsize); /* print volume set sequnce number */ printf("Volume set sequence number is %d\n", volsetseq); /* print logical block size */ printf("Logical block size is %d\n", blksize); /* print volume size */ printf("Volume size is %d\n", volsize); } static void copystring(char *from, char *to, int size) { int i; if (from == NULL) return; for (i = 0; i < size; i++) { if (*from == '\0') break; else *to++ = *from++; } for (; i < size; i++) *to++ = ' '; } static void prntstring(char *heading, char *s, int maxlen) { int i; if (maxlen < 1) return; if (heading == NULL || s == NULL) return; /* print heading */ printf("%s: ", heading); /* strip off trailing zeros */ for (i = maxlen-1; i >= 0; i--) if (s[i] != ' ') break; maxlen = i+1; for (i = 0; i < maxlen; i++) printf("%c", s[i]); printf("\n"); } static int match(char *s) { char *cs; cs = string; while (*cs++ == *s) if (*s++ == '\0') goto true; if (*s != '\0') return (0); true: cs--; string = cs; return (1); } /* readdisk - read from cdrom image file */ static void getdisk(char *buf, int daddr, int size) { if (lseek(cdfd, daddr, L_SET) == -1) { sprintf(errstrng, "%s: getdisk: lseek()", callname); perror(errstrng); exit(32); } if (read(cdfd, buf, size) != size) { sprintf(errstrng, "%s: getdisk: read()", callname); perror(errstrng); exit(32); } } /* putdisk - write to cdrom image file */ static void putdisk(char *buf, int daddr, int size) { if (lseek(cdfd, daddr, L_SET) == -1) { sprintf(errstrng, "%s: putdisk: lseek()", callname); perror(errstrng); exit(32); } if (write(cdfd, buf, size) != size) { sprintf(errstrng, "%s: putdisk: write()", callname); perror(errstrng); exit(32); } } # # CDDL HEADER START # # The contents of this file are subject to the terms of the # Common Development and Distribution License, Version 1.0 only # (the "License"). You may not use this file except in compliance # with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. # See the License for the specific language governing permissions # and limitations under the License. # # When distributing Covered Code, include this CDDL HEADER in each # file and include the License file at usr/src/OPENSOLARIS.LICENSE. # If applicable, add the following below this CDDL HEADER, with the # fields enclosed by brackets "[]" replaced with your own identifying # information: Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END # # # Copyright 2003 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # Copyright (c) 2018, Joyent, Inc. FSTYPE= hsfs LIBPROG= mount PROG= $(LIBPROG) ROOTFS_PROG= $(PROG) # duplicate ROOTLIBFSTYPE value needed for installation rule # we must define this before including Makefile.fstype ROOTLIBFSTYPE = $(ROOT)/usr/lib/fs/$(FSTYPE) $(ROOTLIBFSTYPE)/%: $(ROOTLIBFSTYPE) % $(RM) $@; $(SYMLINK) ../../../../etc/fs/$(FSTYPE)/$(PROG) $@ include ../../Makefile.fstype include ../../Makefile.mount include ../../Makefile.mount.targ CERRWARN += -Wno-unused-variable # not linted SMATCH=off /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2003 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include #include #include #include /* defines F_LOCK for lockf */ #include /* for getopt(3) */ #include #include #include #include #include #include #include #include #include #include #include extern int optind; extern char *optarg; #define NAME_MAX 64 #define GLOBAL 0 #define NOGLOBAL 1 #ifndef MNTOPT_NOGLOBAL #define MNTOPT_NOGLOBAL "noglobal" #endif /* MNTOPT_NOGLOBAL */ static int gflg = 0; /* mount into global name space: flag form */ static int global = 0; /* mount into global name space: option form */ static int havegblopt = 0; /* global value supercedes gflg value */ static int qflg = 0; /* quiet option - don't flag bad options */ static char fstype[] = MNTTYPE_HSFS; static char typename[NAME_MAX], *myname; /* * Mount options that require special handling */ static char *myopts[] = { MNTOPT_GLOBAL, MNTOPT_NOGLOBAL, NULL }; static void rpterr(char *, char *); static void usage(void); int main(int argc, char **argv) { char *options, *value; char *special, *mountp; char *gopt; struct mnttab mm; int c; char obuff[MAX_MNTOPT_STR]; char saved_input_options[MAX_MNTOPT_STR]; int hsfs_flags; int flags; int Oflg = 0; /* Overlay mounts */ (void) setlocale(LC_ALL, ""); #if !defined(TEXT_DOMAIN) #define TEXT_DOMAIN "SYS_TEST" #endif (void) textdomain(TEXT_DOMAIN); myname = strrchr(argv[0], '/'); if (myname) myname++; else myname = argv[0]; snprintf(typename, sizeof (typename), "%s %s", fstype, myname); argv[0] = typename; /* * Check for arguments requiring special handling. Ignore * unrecognized options. */ strcpy(obuff, "ro"); /* default */ while ((c = getopt(argc, argv, "o:rmOgq")) != EOF) { switch (c) { case 'o': if (strlen(optarg) > MAX_MNTOPT_STR) { (void) fprintf(stderr, gettext( "%s: option set too long\n"), myname); exit(1); } if (strlen(optarg) == 0) { (void) fprintf(stderr, gettext( "%s: missing suboptions\n"), myname); exit(1); } strcpy(obuff, optarg); options = optarg; while (*options != '\0') { switch (getsubopt(&options, myopts, &value)) { case GLOBAL: havegblopt = 1; global = 1; break; case NOGLOBAL: havegblopt = 1; global = 0; break; } } break; case 'O': Oflg++; break; case 'r': /* accept for backwards compatibility */ break; case 'm': break; case 'g': gflg++; break; case 'q': qflg++; break; } } if ((argc - optind) != 2) usage(); special = argv[optind++]; mountp = argv[optind++]; /* * Force readonly. obuff is guaranteed to have something in * it. We might end up with "ro,ro", but that's acceptable. */ flags = MS_RDONLY; if ((strlen(obuff) + strlen(MNTOPT_RO) + 2) > MAX_MNTOPT_STR) { (void) fprintf(stderr, gettext("%s: option set too long\n"), myname); exit(1); } strcat(obuff, ","); strcat(obuff, MNTOPT_RO); flags |= Oflg ? MS_OVERLAY : 0; /* * xxx it's not clear if should just put MS_GLOBAL in flags, * or provide it as a string. Be safe, do both. The subopt * version has precedence over the switch version. */ gopt = NULL; if ((havegblopt && global) || gflg) { gopt = MNTOPT_GLOBAL; flags |= MS_GLOBAL; } else if (havegblopt) { gopt = MNTOPT_NOGLOBAL; } if (gopt != NULL) { if ((strlen(obuff) + strlen(gopt) + 2) > MAX_MNTOPT_STR) { (void) fprintf(stderr, gettext("%s: option set too long\n"), myname); exit(1); } strcat(obuff, ","); strcat(obuff, gopt); } signal(SIGHUP, SIG_IGN); signal(SIGQUIT, SIG_IGN); signal(SIGINT, SIG_IGN); /* * Save a copy of the options to compare with the options that * were actually recognized and supported by the kernel. */ (void) strcpy(saved_input_options, obuff); /* * Perform the mount. */ if (mount(special, mountp, flags | MS_OPTIONSTR, fstype, NULL, 0, obuff, sizeof (obuff)) == -1) { rpterr(special, mountp); exit(31+2); } if (!qflg) { cmp_requested_to_actual_options(saved_input_options, obuff, special, mountp); } exit(0); /* NOTREACHED */ } static void rpterr(char *bs, char *mp) { switch (errno) { case EPERM: (void) fprintf(stderr, gettext("%s: insufficient privileges\n"), myname); break; case ENXIO: (void) fprintf(stderr, gettext("%s: %s no such device\n"), myname, bs); break; case ENOTDIR: (void) fprintf(stderr, gettext("%s: %s not a directory\n\tor a " "component of %s is not a directory\n"), myname, mp, bs); break; case ENOENT: (void) fprintf(stderr, gettext("%s: %s or %s, no such file or directory\n"), myname, bs, mp); break; case EINVAL: (void) fprintf(stderr, gettext("%s: %s is not an hsfs file " "system.\n"), typename, bs); break; case EBUSY: (void) fprintf(stderr, gettext("%s: %s is already mounted or %s is busy\n"), myname, bs, mp); break; case ENOTBLK: (void) fprintf(stderr, gettext("%s: %s not a block device\n"), myname, bs); break; case EROFS: (void) fprintf(stderr, gettext("%s: %s write-protected\n"), myname, bs); break; case ENOSPC: (void) fprintf(stderr, gettext("%s: %s is corrupted. needs checking\n"), myname, bs); break; default: perror(myname); (void) fprintf(stderr, gettext("%s: cannot mount %s\n"), myname, bs); } } static void usage() { char *opts; opts = "{-r | -o ro | -o nrr | -o nosuid | -o notraildot | -o nomaplcase}"; (void) fprintf(stdout, gettext("hsfs usage: mount [-F hsfs] %s {special | mount_point}\n"), opts); (void) fprintf(stdout, gettext("hsfs usage: mount [-F hsfs] %s special mount_point\n"), opts); exit(32); }