📄 _cdio_sunos.c
字号:
env->gen.fd = -1; if (env->gen.fd > -1) { if ((ret = ioctl(env->gen.fd, CDROMEJECT)) != 0) { cdio_generic_free((void *) env); cdio_warn ("CDROMEJECT failed: %s\n", strerror(errno)); return 1; } else { return 0; } } return 2;}static void *_cdio_malloc_and_zero(size_t size) { void *ptr; if( !size ) size++; if((ptr = malloc(size)) == NULL) { cdio_warn("malloc() failed: %s", strerror(errno)); return NULL; } memset(ptr, 0, size); return ptr;}/*! Return the value associated with the key "arg".*/static const char *get_arg_solaris (void *p_user_data, const char key[]){ _img_private_t *env = p_user_data; if (!strcmp (key, "source")) { return env->gen.source_name; } else if (!strcmp (key, "access-mode")) { switch (env->access_mode) { case _AM_SUN_CTRL_ATAPI: return "ATAPI"; case _AM_SUN_CTRL_SCSI: return "SCSI"; case _AM_NONE: return "no access method"; } } return NULL;}/*! Return a string containing the default CD device if none is specified. */char *cdio_get_default_device_solaris(void){ char *volume_device; char *volume_name; char *volume_action; char *device; struct stat stb; if ((volume_device = getenv("VOLUME_DEVICE")) != NULL && (volume_name = getenv("VOLUME_NAME")) != NULL && (volume_action = getenv("VOLUME_ACTION")) != NULL && strcmp(volume_action, "insert") == 0) { device = _cdio_malloc_and_zero(strlen(volume_device) + strlen(volume_name) + 2); if (device == NULL) return strdup(DEFAULT_CDIO_DEVICE); sprintf(device, "%s/%s", volume_device, volume_name); if (stat(device, &stb) != 0 || !S_ISCHR(stb.st_mode)) { free(device); return strdup(DEFAULT_CDIO_DEVICE); } return device; } /* Check if it could be a Solaris media*/ if((stat(DEFAULT_CDIO_DEVICE, &stb) == 0) && S_ISDIR(stb.st_mode)) { device = _cdio_malloc_and_zero(strlen(DEFAULT_CDIO_DEVICE) + 4); sprintf(device, "%s/s0", DEFAULT_CDIO_DEVICE); return device; } return strdup(DEFAULT_CDIO_DEVICE);}/*! Get disc type associated with cd object.*/static discmode_tget_discmode_solaris (void *p_user_data){ _img_private_t *p_env = p_user_data; track_t i_track; discmode_t discmode=CDIO_DISC_MODE_NO_INFO; struct dk_minfo media; int ret; /* Get the media info */ if((ret = ioctl(p_env->gen.fd, DKIOCGMEDIAINFO, &media)) != 0) { cdio_warn ("DKIOCGMEDIAINFO failed: %s\n", strerror(errno)); return CDIO_DISC_MODE_NO_INFO; } switch(media.dki_media_type) { case DK_CDROM: case DK_CDR: case DK_CDRW: /* Do cdrom detection */ break; case DK_DVDROM: return CDIO_DISC_MODE_DVD_ROM; case DK_DVDR: discmode = CDIO_DISC_MODE_DVD_R; break; case DK_DVDRAM: discmode = CDIO_DISC_MODE_DVD_RAM; break; case DK_DVDRW: case DK_DVDRW+1: discmode = CDIO_DISC_MODE_DVD_RW; break; default: /* no valid match */ return CDIO_DISC_MODE_NO_INFO; } if((discmode == CDIO_DISC_MODE_DVD_RAM || discmode == CDIO_DISC_MODE_DVD_RW || discmode == CDIO_DISC_MODE_DVD_R)) { /* Fallback to uscsi if we can */ if(geteuid() == 0) return get_discmode_solaris(p_user_data); return discmode; } if (!p_env->gen.toc_init) read_toc_solaris (p_env); if (!p_env->gen.toc_init) return CDIO_DISC_MODE_NO_INFO; for (i_track = p_env->gen.i_first_track; i_track < p_env->gen.i_first_track + p_env->tochdr.cdth_trk1 ; i_track ++) { track_format_t track_fmt=get_track_format_solaris(p_env, i_track); switch(track_fmt) { case TRACK_FORMAT_AUDIO: switch(discmode) { case CDIO_DISC_MODE_NO_INFO: discmode = CDIO_DISC_MODE_CD_DA; break; case CDIO_DISC_MODE_CD_DA: case CDIO_DISC_MODE_CD_MIXED: case CDIO_DISC_MODE_ERROR: /* No change*/ break; default: discmode = CDIO_DISC_MODE_CD_MIXED; } break; case TRACK_FORMAT_XA: switch(discmode) { case CDIO_DISC_MODE_NO_INFO: discmode = CDIO_DISC_MODE_CD_XA; break; case CDIO_DISC_MODE_CD_XA: case CDIO_DISC_MODE_CD_MIXED: case CDIO_DISC_MODE_ERROR: /* No change*/ break; default: discmode = CDIO_DISC_MODE_CD_MIXED; } break; case TRACK_FORMAT_DATA: switch(discmode) { case CDIO_DISC_MODE_NO_INFO: discmode = CDIO_DISC_MODE_CD_DATA; break; case CDIO_DISC_MODE_CD_DATA: case CDIO_DISC_MODE_CD_MIXED: case CDIO_DISC_MODE_ERROR: /* No change*/ break; default: discmode = CDIO_DISC_MODE_CD_MIXED; } break; case TRACK_FORMAT_ERROR: default: discmode = CDIO_DISC_MODE_ERROR; } } return discmode;}/*! Get format of track. */static track_format_tget_track_format_solaris(void *p_user_data, track_t i_track) { _img_private_t *p_env = p_user_data; if ( !p_env ) return TRACK_FORMAT_ERROR; if (!p_env->gen.init) init_solaris(p_env); if (!p_env->gen.toc_init) read_toc_solaris (p_user_data) ; if ( (i_track > p_env->gen.i_tracks+p_env->gen.i_first_track) || i_track < p_env->gen.i_first_track) return TRACK_FORMAT_ERROR; i_track -= p_env->gen.i_first_track; /* This is pretty much copied from the "badly broken" cdrom_count_tracks in linux/cdrom.c. */ if (p_env->tocent[i_track].cdte_ctrl & CDROM_DATA_TRACK) { if (p_env->tocent[i_track].cdte_format == CDIO_CDROM_CDI_TRACK) return TRACK_FORMAT_CDI; else if (p_env->tocent[i_track].cdte_format == CDIO_CDROM_XA_TRACK) return TRACK_FORMAT_XA; else return TRACK_FORMAT_DATA; } else return TRACK_FORMAT_AUDIO; }/*! Return true if we have XA data (green, mode2 form1) or XA data (green, mode2 form2). That is track begins: sync - header - subheader 12 4 - 8 FIXME: there's gotta be a better design for this and get_track_format?*/static bool_cdio_get_track_green(void *p_user_data, track_t i_track) { _img_private_t *p_env = p_user_data; if ( !p_env ) return false; if (!p_env->gen.init) init_solaris(p_env); if (!p_env->gen.toc_init) read_toc_solaris (p_env) ; if (i_track >= p_env->gen.i_tracks+p_env->gen.i_first_track || i_track < p_env->gen.i_first_track) return false; i_track -= p_env->gen.i_first_track; /* FIXME: Dunno if this is the right way, but it's what I was using in cd-info for a while. */ return ((p_env->tocent[i_track].cdte_ctrl & 2) != 0);}/*! Return the starting MSF (minutes/secs/frames) for track number track_num in obj. Track numbers usually start at something greater than 0, usually 1. The "leadout" track is specified either by using track_num LEADOUT_TRACK or the total tracks+1. False is returned if there is no entry.*/static bool_cdio_get_track_msf(void *p_user_data, track_t i_track, msf_t *msf){ _img_private_t *p_env = p_user_data; if (NULL == msf) return false; if (!p_env->gen.init) init_solaris(p_env); if (!p_env->gen.toc_init) read_toc_solaris (p_env) ; if (i_track == CDIO_CDROM_LEADOUT_TRACK) i_track = p_env->gen.i_tracks + p_env->gen.i_first_track; if (i_track > (p_env->gen.i_tracks+p_env->gen.i_first_track) || i_track < p_env->gen.i_first_track) { return false; } else { struct cdrom_tocentry *msf0 = &p_env->tocent[i_track-1]; msf->m = cdio_to_bcd8(msf0->cdte_addr.msf.minute); msf->s = cdio_to_bcd8(msf0->cdte_addr.msf.second); msf->f = cdio_to_bcd8(msf0->cdte_addr.msf.frame); return true; }}#else /*! Return a string containing the default VCD device if none is specified. */char *cdio_get_default_device_solaris(void){ return strdup(DEFAULT_CDIO_DEVICE);}#endif /* HAVE_SOLARIS_CDROM *//*! Return an array of strings giving possible CD devices. */char **cdio_get_devices_solaris (void){#ifndef HAVE_SOLARIS_CDROM return NULL;#else char volpath[256]; struct stat st; char **drives = NULL; unsigned int i_files=0;#ifdef HAVE_GLOB_H unsigned int i; glob_t globbuf; globbuf.gl_offs = 0; glob("/vol/dev/aliases/cdrom*", GLOB_DOOFFS, NULL, &globbuf); for (i=0; i<globbuf.gl_pathc; i++) { if(stat(globbuf.gl_pathv[i], &st) < 0) continue; /* Check if this is a directory, if so it's probably Solaris media */ if(S_ISDIR(st.st_mode)) { sprintf(volpath, "%s/s0", globbuf.gl_pathv[i]); if(stat(volpath, &st) == 0) cdio_add_device_list(&drives, volpath, &i_files); }else cdio_add_device_list(&drives, globbuf.gl_pathv[i], &i_files); } globfree(&globbuf);#else if(stat(DEFAULT_CDIO_DEVICE, &st) == 0) { /* Check if this is a directory, if so it's probably Solaris media */ if(S_ISDIR(st.st_mode)) { sprintf(volpath, "%s/s0", DEFAULT_CDIO_DEVICE); if(stat(volpath, &st) == 0) cdio_add_device_list(&drives, volpath, &i_files); }else cdio_add_device_list(&drives, DEFAULT_CDIO_DEVICE, &i_files); }#endif /*HAVE_GLOB_H*/ cdio_add_device_list(&drives, NULL, &i_files); return drives;#endif /*HAVE_SOLARIS_CDROM*/}/*! Initialization routine. This is the only thing that doesn't get called via a function pointer. In fact *we* are the ones to set that up. */CdIo *cdio_open_solaris (const char *psz_source_name){ return cdio_open_am_solaris(psz_source_name, NULL);}/*! Initialization routine. This is the only thing that doesn't get called via a function pointer. In fact *we* are the ones to set that up. */CdIo *cdio_open_am_solaris (const char *psz_orig_source, const char *access_mode){#ifdef HAVE_SOLARIS_CDROM CdIo *ret; _img_private_t *_data; char *psz_source; cdio_funcs _funcs; _funcs.eject_media = eject_media_solaris; _funcs.free = cdio_generic_free; _funcs.get_arg = get_arg_solaris; _funcs.get_cdtext = get_cdtext_generic; _funcs.get_default_device = cdio_get_default_device_solaris; _funcs.get_devices = cdio_get_devices_solaris; _funcs.get_discmode = get_discmode_solaris; _funcs.get_drive_cap = scsi_mmc_get_drive_cap_generic; _funcs.get_first_track_num= get_first_track_num_generic; _funcs.get_hwinfo = NULL; _funcs.get_mcn = scsi_mmc_get_mcn_generic, _funcs.get_num_tracks = get_num_tracks_generic; _funcs.get_track_format = get_track_format_solaris; _funcs.get_track_green = _cdio_get_track_green; _funcs.get_track_lba = NULL; /* This could be implemented if need be. */ _funcs.get_track_msf = _cdio_get_track_msf; _funcs.lseek = cdio_generic_lseek; _funcs.read = cdio_generic_read; _funcs.read_audio_sectors = _read_audio_sectors_solaris; _funcs.read_mode1_sector = _read_mode1_sector_solaris; _funcs.read_mode1_sectors = _read_mode1_sectors_solaris; _funcs.read_mode2_sector = _read_mode2_sector_solaris; _funcs.read_mode2_sectors = _read_mode2_sectors_solaris; _funcs.read_toc = read_toc_solaris; _funcs.run_scsi_mmc_cmd = run_scsi_cmd_solaris; _funcs.stat_size = _cdio_stat_size; _funcs.set_arg = _set_arg_solaris; _data = _cdio_malloc (sizeof (_img_private_t)); _data->access_mode = _AM_SUN_CTRL_SCSI; _data->gen.init = false; _data->gen.fd = -1; _data->gen.toc_init = false; _data->gen.b_cdtext_init = false; _data->gen.b_cdtext_error = false; if (NULL == psz_orig_source) { psz_source = cdio_get_default_device_solaris(); if (NULL == psz_source) return NULL; _set_arg_solaris(_data, "source", psz_source); free(psz_source); } else { if (cdio_is_device_generic(psz_orig_source)) _set_arg_solaris(_data, "source", psz_orig_source); else { /* The below would be okay if all device drivers worked this way. */#if 0 cdio_info ("source %s is not a device", psz_orig_source);#endif return NULL; } } ret = cdio_new ( (void *) _data, &_funcs ); if (ret == NULL) return NULL; if (init_solaris(_data)) return ret; else { cdio_generic_free (_data); return NULL; }#else return NULL;#endif /* HAVE_SOLARIS_CDROM */}boolcdio_have_solaris (void){#ifdef HAVE_SOLARIS_CDROM return true;#else return false;#endif /* HAVE_SOLARIS_CDROM */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -