ddpt-0.92/0000755000175000017500000000000011527261465011404 5ustar douggdouggddpt-0.92/README.freebsd0000644000175000017500000000146711142643107013673 0ustar douggdouggDisk devices in FreeBSD have names like '/dev/da0' while the corresponding pass-through devices have names like '/dev/pass0'. See the 'camcontrol devlist' command for a list of available devices (registered with the CAM subsystem) and the mapping between "block" devices names and the corresponding pass-through device name. The usual sequence of "./configure ; make ; make install" can be used to build and install this package. If that fails try the "./autogen.sh" script prior to that sequence. Attempts to copy in chunks greater than 64kB (65536 bytes) failed on a FreeBSD 7.0 test system with an "argument list too long" error message. There is a corresponding kernel message (viewable with dmesg) that an attempt has been made to map bytes which is greater than DFLTPHYS(65536). Doug Gilbert 5th February 2009 ddpt-0.92/include/0000755000175000017500000000000011527261465013027 5ustar douggdouggddpt-0.92/include/sg_linux_inc.h0000644000175000017500000000367010671112741015656 0ustar douggdougg#ifndef SG_LINUX_INC_H #define SG_LINUX_INC_H #ifdef SG_KERNEL_INCLUDES #define __user typedef unsigned char u8; #include "/usr/src/linux/include/scsi/sg.h" #include "/usr/src/linux/include/scsi/scsi.h" #else #ifdef SG_TRICK_GNU_INCLUDES #include #include #else #include #include #endif #endif #ifdef BLKGETSIZE64 #ifndef u64 #include /* C99 header for exact integer types */ typedef uint64_t u64; /* problems with BLKGETSIZE64 ioctl in lk 2.4 */ #endif #endif /* Getting the correct include files for the sg interface can be an ordeal. In a perfect world, one would just write: #include #include This would include the files found in the /usr/include/scsi directory. Those files are maintained with the GNU library which may or may not agree with the kernel and version of sg driver that is running. Any many cases this will not matter. However in some it might, for example glibc 2.1's include files match the sg driver found in the lk 2.2 series. Hence if glibc 2.1 is used with lk 2.4 then the additional sg v3 interface will not be visible. If this is a problem then defining SG_KERNEL_INCLUDES will access the kernel supplied header files (assuming they are in the normal place). The GNU library maintainers and various kernel people don't like this approach (but it does work). The technique selected by defining SG_TRICK_GNU_INCLUDES worked (and was used) prior to glibc 2.2 . Prior to that version /usr/include/linux was a symbolic link to /usr/src/linux/include/linux . There are other approaches if this include "mixup" causes pain. These would involve include files being copied or symbolic links being introduced. Sorry about the inconvenience. Typically neither SG_KERNEL_INCLUDES nor SG_TRICK_GNU_INCLUDES is defined. dpg 20010415, 20030522 */ #endif ddpt-0.92/include/sg_cmds_mmc.h0000644000175000017500000000412211346470114015442 0ustar douggdougg#ifndef SG_CMDS_MMC_H #define SG_CMDS_MMC_H /* * Copyright (c) 2008-2010 Douglas Gilbert. * All rights reserved. * Use of this source code is governed by a BSD-style * license that can be found in the BSD_LICENSE file. */ #ifdef __cplusplus extern "C" { #endif /* Invokes a SCSI GET CONFIGURATION command (MMC-3...6). * Returns 0 when successful, SG_LIB_CAT_INVALID_OP if command not * supported, SG_LIB_CAT_ILLEGAL_REQ if field in cdb not supported, * SG_LIB_CAT_UNIT_ATTENTION, SG_LIB_CAT_ABORTED_COMMAND, else -1 */ extern int sg_ll_get_config(int sg_fd, int rt, int starting, void * resp, int mx_resp_len, int noisy, int verbose); /* Invokes a SCSI GET PERFORMANCE command (MMC-3...6). * Returns 0 when successful, SG_LIB_CAT_INVALID_OP if command not * supported, SG_LIB_CAT_ILLEGAL_REQ if field in cdb not supported, * SG_LIB_CAT_UNIT_ATTENTION, SG_LIB_CAT_ABORTED_COMMAND, else -1 */ extern int sg_ll_get_performance(int sg_fd, int data_type, unsigned int starting_lba, int max_num_desc, int type, void * resp, int mx_resp_len, int noisy, int verbose); /* Invokes a SCSI SET CD SPEED command (MMC). * Return of 0 -> success, SG_LIB_CAT_INVALID_OP -> command not supported, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_UNIT_ATTENTION, * SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND, * -1 -> other failure */ extern int sg_ll_set_cd_speed(int sg_fd, int rot_control, int drv_read_speed, int drv_write_speed, int noisy, int verbose); /* Invokes a SCSI SET STREAMING command (MMC). Return of 0 -> success, * SG_LIB_CAT_INVALID_OP -> Set Streaming not supported, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_ABORTED_COMMAND, * SG_LIB_CAT_UNIT_ATTENTION, SG_LIB_CAT_NOT_READY -> device not ready, * -1 -> other failure */ extern int sg_ll_set_streaming(int sg_fd, int type, void * paramp, int param_len, int noisy, int verbose); #ifdef __cplusplus } #endif #endif ddpt-0.92/include/sg_io_linux.h0000644000175000017500000001351411346470114015513 0ustar douggdougg#ifndef SG_IO_LINUX_H #define SG_IO_LINUX_H /* * Copyright (c) 2004-2010 Douglas Gilbert. * All rights reserved. * Use of this source code is governed by a BSD-style * license that can be found in the BSD_LICENSE file. */ /* * Version 1.02 [20090708] */ /* * This header file contains linux specific information related to the SCSI * command pass through in the SCSI generic (sg) driver and the linux * block layer. */ #include "sg_lib.h" #include "sg_linux_inc.h" #ifdef __cplusplus extern "C" { #endif /* The following are 'host_status' codes */ #ifndef DID_OK #define DID_OK 0x00 #endif #ifndef DID_NO_CONNECT #define DID_NO_CONNECT 0x01 /* Unable to connect before timeout */ #define DID_BUS_BUSY 0x02 /* Bus remain busy until timeout */ #define DID_TIME_OUT 0x03 /* Timed out for some other reason */ #define DID_BAD_TARGET 0x04 /* Bad target (id?) */ #define DID_ABORT 0x05 /* Told to abort for some other reason */ #define DID_PARITY 0x06 /* Parity error (on SCSI bus) */ #define DID_ERROR 0x07 /* Internal error */ #define DID_RESET 0x08 /* Reset by somebody */ #define DID_BAD_INTR 0x09 /* Received an unexpected interrupt */ #define DID_PASSTHROUGH 0x0a /* Force command past mid-level */ #define DID_SOFT_ERROR 0x0b /* The low-level driver wants a retry */ #endif #ifndef DID_IMM_RETRY #define DID_IMM_RETRY 0x0c /* Retry without decrementing retry count */ #endif #ifndef DID_REQUEUE #define DID_REQUEUE 0x0d /* Requeue command (no immediate retry) also * without decrementing the retry count */ #endif /* These defines are to isolate applications from kernel define changes */ #define SG_LIB_DID_OK DID_OK #define SG_LIB_DID_NO_CONNECT DID_NO_CONNECT #define SG_LIB_DID_BUS_BUSY DID_BUS_BUSY #define SG_LIB_DID_TIME_OUT DID_TIME_OUT #define SG_LIB_DID_BAD_TARGET DID_BAD_TARGET #define SG_LIB_DID_ABORT DID_ABORT #define SG_LIB_DID_PARITY DID_PARITY #define SG_LIB_DID_ERROR DID_ERROR #define SG_LIB_DID_RESET DID_RESET #define SG_LIB_DID_BAD_INTR DID_BAD_INTR #define SG_LIB_DID_PASSTHROUGH DID_PASSTHROUGH #define SG_LIB_DID_SOFT_ERROR DID_SOFT_ERROR #define SG_LIB_DID_IMM_RETRY DID_IMM_RETRY #define SG_LIB_DID_REQUEUE DID_REQUEUE /* The following are 'driver_status' codes */ #ifndef DRIVER_OK #define DRIVER_OK 0x00 #endif #ifndef DRIVER_BUSY #define DRIVER_BUSY 0x01 #define DRIVER_SOFT 0x02 #define DRIVER_MEDIA 0x03 #define DRIVER_ERROR 0x04 #define DRIVER_INVALID 0x05 #define DRIVER_TIMEOUT 0x06 #define DRIVER_HARD 0x07 #define DRIVER_SENSE 0x08 /* Sense_buffer has been set */ /* Following "suggests" are "or-ed" with one of previous 8 entries */ #define SUGGEST_RETRY 0x10 #define SUGGEST_ABORT 0x20 #define SUGGEST_REMAP 0x30 #define SUGGEST_DIE 0x40 #define SUGGEST_SENSE 0x80 #define SUGGEST_IS_OK 0xff #endif #ifndef DRIVER_MASK #define DRIVER_MASK 0x0f #endif #ifndef SUGGEST_MASK #define SUGGEST_MASK 0xf0 #endif /* These defines are to isolate applications from kernel define changes */ #define SG_LIB_DRIVER_OK DRIVER_OK #define SG_LIB_DRIVER_BUSY DRIVER_BUSY #define SG_LIB_DRIVER_SOFT DRIVER_SOFT #define SG_LIB_DRIVER_MEDIA DRIVER_MEDIA #define SG_LIB_DRIVER_ERROR DRIVER_ERROR #define SG_LIB_DRIVER_INVALID DRIVER_INVALID #define SG_LIB_DRIVER_TIMEOUT DRIVER_TIMEOUT #define SG_LIB_DRIVER_HARD DRIVER_HARD #define SG_LIB_DRIVER_SENSE DRIVER_SENSE #define SG_LIB_SUGGEST_RETRY SUGGEST_RETRY #define SG_LIB_SUGGEST_ABORT SUGGEST_ABORT #define SG_LIB_SUGGEST_REMAP SUGGEST_REMAP #define SG_LIB_SUGGEST_DIE SUGGEST_DIE #define SG_LIB_SUGGEST_SENSE SUGGEST_SENSE #define SG_LIB_SUGGEST_IS_OK SUGGEST_IS_OK #define SG_LIB_DRIVER_MASK DRIVER_MASK #define SG_LIB_SUGGEST_MASK SUGGEST_MASK extern void sg_print_masked_status(int masked_status); extern void sg_print_host_status(int host_status); extern void sg_print_driver_status(int driver_status); /* sg_chk_n_print() returns 1 quietly if there are no errors/warnings else it prints errors/warnings (prefixed by 'leadin') to 'sg_warnings_fd' and returns 0. raw_sinfo indicates whether the raw sense buffer (in ASCII hex) should be printed. */ extern int sg_chk_n_print(const char * leadin, int masked_status, int host_status, int driver_status, const unsigned char * sense_buffer, int sb_len, int raw_sinfo); /* The following function declaration is for the sg version 3 driver. */ struct sg_io_hdr; /* sg_chk_n_print3() returns 1 quietly if there are no errors/warnings; else it prints errors/warnings (prefixed by 'leadin') to 'sg_warnings_fd' and returns 0. */ extern int sg_chk_n_print3(const char * leadin, struct sg_io_hdr * hp, int raw_sinfo); /* Calls sg_scsi_normalize_sense() after obtaining the sense buffer and its length from the struct sg_io_hdr pointer. If these cannot be obtained, 0 is returned. */ extern int sg_normalize_sense(const struct sg_io_hdr * hp, struct sg_scsi_sense_hdr * sshp); extern int sg_err_category(int masked_status, int host_status, int driver_status, const unsigned char * sense_buffer, int sb_len); extern int sg_err_category_new(int scsi_status, int host_status, int driver_status, const unsigned char * sense_buffer, int sb_len); /* The following function declaration is for the sg version 3 driver. */ extern int sg_err_category3(struct sg_io_hdr * hp); /* Note about SCSI status codes found in older versions of Linux. Linux has traditionally used a 1 bit right shifted and masked version of SCSI standard status codes. Now CHECK_CONDITION and friends (in ) are deprecated. */ #ifdef __cplusplus } #endif #endif ddpt-0.92/include/sg_lib.h0000644000175000017500000004157211346470114014440 0ustar douggdougg#ifndef SG_LIB_H #define SG_LIB_H /* * Copyright (c) 2004-2010 Douglas Gilbert. * All rights reserved. * Use of this source code is governed by a BSD-style * license that can be found in the BSD_LICENSE file. */ /* * * On 5th October 2004 a FreeBSD license was added to this file. * The intention is to keep this file and the related sg_lib.c file * as open source and encourage their unencumbered use. * * Current version number is in the sg_lib.c file and can be accessed * with the sg_lib_version() function. */ /* * This header file contains defines and function declarations that may * be useful to applications that communicate with devices that use a * SCSI command set. These command sets have names like SPC-4, SBC-3, * SSC-3, SES-2 and draft standards defining them can be found at * http://www.t10.org . Virtually all devices in the Linux SCSI subsystem * utilize SCSI command sets. Many devices in other Linux device subsystems * utilize SCSI command sets either natively or via emulation (e.g. a * parallel ATA disk in a USB enclosure). */ #include #include #ifdef __cplusplus extern "C" { #endif /* SCSI Peripheral Device Types (PDT) [5 bit field] */ #define PDT_DISK 0x0 /* direct access block device (disk) */ #define PDT_TAPE 0x1 /* sequential access device (magnetic tape) */ #define PDT_PRINTER 0x2 /* printer device (see SSC-1) */ #define PDT_PROCESSOR 0x3 /* processor device (e.g. SAFTE device) */ #define PDT_WO 0x4 /* write once device (some optical disks) */ #define PDT_MMC 0x5 /* CD/DVD/BD (multi-media) */ #define PDT_SCANNER 0x6 /* obsolete */ #define PDT_OPTICAL 0x7 /* optical memory device (some optical disks) */ #define PDT_MCHANGER 0x8 /* media changer device (e.g. tape robot) */ #define PDT_COMMS 0x9 /* communications device (obsolete) */ #define PDT_SAC 0xc /* storage array controller device */ #define PDT_SES 0xd /* SCSI Enclosure Services (SES) device */ #define PDT_RBC 0xe /* Reduced Block Commands (simplified PDT_DISK) */ #define PDT_OCRW 0xf /* optical card read/write device */ #define PDT_BCC 0x10 /* bridge controller commands */ #define PDT_OSD 0x11 /* Object Storage Device (OSD) */ #define PDT_ADC 0x12 /* Automation/drive commands (ADC) */ #define PDT_SMD 0x13 /* Security Manager Device (SMD) */ #define PDT_WLUN 0x1e /* Well known logical unit (WLUN) */ #define PDT_UNKNOWN 0x1f /* Unknown or no device type */ #ifndef SAM_STAT_GOOD /* The SCSI status codes as found in SAM-4 at www.t10.org */ #define SAM_STAT_GOOD 0x0 #define SAM_STAT_CHECK_CONDITION 0x2 #define SAM_STAT_CONDITION_MET 0x4 #define SAM_STAT_BUSY 0x8 #define SAM_STAT_INTERMEDIATE 0x10 /* obsolete in SAM-4 */ #define SAM_STAT_INTERMEDIATE_CONDITION_MET 0x14 /* obsolete in SAM-4 */ #define SAM_STAT_RESERVATION_CONFLICT 0x18 #define SAM_STAT_COMMAND_TERMINATED 0x22 /* obsolete in SAM-3 */ #define SAM_STAT_TASK_SET_FULL 0x28 #define SAM_STAT_ACA_ACTIVE 0x30 #define SAM_STAT_TASK_ABORTED 0x40 #endif /* The SCSI sense key codes as found in SPC-4 at www.t10.org */ #define SPC_SK_NO_SENSE 0x0 #define SPC_SK_RECOVERED_ERROR 0x1 #define SPC_SK_NOT_READY 0x2 #define SPC_SK_MEDIUM_ERROR 0x3 #define SPC_SK_HARDWARE_ERROR 0x4 #define SPC_SK_ILLEGAL_REQUEST 0x5 #define SPC_SK_UNIT_ATTENTION 0x6 #define SPC_SK_DATA_PROTECT 0x7 #define SPC_SK_BLANK_CHECK 0x8 #define SPC_SK_COPY_ABORTED 0xa #define SPC_SK_ABORTED_COMMAND 0xb #define SPC_SK_VOLUME_OVERFLOW 0xd #define SPC_SK_MISCOMPARE 0xe /* Transport protocol identifiers */ #define TPROTO_FCP 0 #define TPROTO_SPI 1 #define TPROTO_SSA 2 #define TPROTO_1394 3 #define TPROTO_SRP 4 #define TPROTO_ISCSI 5 #define TPROTO_SAS 6 #define TPROTO_ADT 7 #define TPROTO_ATA 8 #define TPROTO_NONE 0xf /* The format of the version string is like this: "1.47 20090201" */ extern const char * sg_lib_version(); /* Returns length of SCSI command given the opcode (first byte). * Yields the wrong answer for variable length commands (opcode=0x7f) * and potentially some vendor specific commands. */ extern int sg_get_command_size(unsigned char cdb_byte0); /* Command name given pointer to the cdb. Certain command names * depend on peripheral type (give 0 if unknown). Places command * name into buff and will write no more than buff_len bytes. */ extern void sg_get_command_name(const unsigned char * cdbp, int peri_type, int buff_len, char * buff); /* Command name given only the first byte (byte 0) of a cdb and * peripheral type. */ extern void sg_get_opcode_name(unsigned char cdb_byte0, int peri_type, int buff_len, char * buff); /* Command name given opcode (byte 0), service action and peripheral type. * If no service action give 0, if unknown peripheral type give 0. */ extern void sg_get_opcode_sa_name(unsigned char cdb_byte0, int service_action, int peri_type, int buff_len, char * buff); /* Fetch scsi status string. */ extern void sg_get_scsi_status_str(int scsi_status, int buff_len, char * buff); /* This is a slightly stretched SCSI sense "descriptor" format header. * The addition is to allow the 0x70 and 0x71 response codes. The idea * is to place the salient data of both "fixed" and "descriptor" sense * format into one structure to ease application processing. * The original sense buffer should be kept around for those cases * in which more information is required (e.g. the LBA of a MEDIUM ERROR). */ struct sg_scsi_sense_hdr { unsigned char response_code; /* permit: 0x0, 0x70, 0x71, 0x72, 0x73 */ unsigned char sense_key; unsigned char asc; unsigned char ascq; unsigned char byte4; unsigned char byte5; unsigned char byte6; unsigned char additional_length; }; /* Maps the salient data from a sense buffer which is in either fixed or * descriptor format into a structure mimicking a descriptor format * header (i.e. the first 8 bytes of sense descriptor format). * If zero response code returns 0. Otherwise returns 1 and if 'sshp' is * non-NULL then zero all fields and then set the appropriate fields in * that structure. sshp::additional_length is always 0 for response * codes 0x70 and 0x71 (fixed format). */ extern int sg_scsi_normalize_sense(const unsigned char * sensep, int sense_len, struct sg_scsi_sense_hdr * sshp); /* Attempt to find the first SCSI sense data descriptor that matches the * given 'desc_type'. If found return pointer to start of sense data * descriptor; otherwise (including fixed format sense data) returns NULL. */ extern const unsigned char * sg_scsi_sense_desc_find( const unsigned char * sensep, int sense_len, int desc_type); /* Yield string associated with sense_key value. Returns 'buff'. */ extern char * sg_get_sense_key_str(int sense_key, int buff_len, char * buff); /* Yield string associated with ASC/ASCQ values. Returns 'buff'. */ extern char * sg_get_asc_ascq_str(int asc, int ascq, int buff_len, char * buff); /* Returns 1 if valid bit set, 0 if valid bit clear. Irrespective the * information field is written out via 'info_outp' (except when it is * NULL). Handles both fixed and descriptor sense formats. */ extern int sg_get_sense_info_fld(const unsigned char * sensep, int sb_len, uint64_t * info_outp); /* Returns 1 if any of the 3 bits (i.e. FILEMARK, EOM or ILI) are set. * In descriptor format if the stream commands descriptor not found * then returns 0. Writes 1 or 0 corresponding to these bits to the * last three arguments if they are non-NULL. */ extern int sg_get_sense_filemark_eom_ili(const unsigned char * sensep, int sb_len, int * filemark_p, int * eom_p, int * ili_p); /* Returns 1 if sense key is NO_SENSE or NOT_READY and SKSV is set. Places * progress field from sense data where progress_outp points. If progress * field is not available returns 0. Handles both fixed and descriptor * sense formats. N.B. App should multiply by 100 and divide by 65536 * to get percentage completion from given value. */ extern int sg_get_sense_progress_fld(const unsigned char * sensep, int sb_len, int * progress_outp); /* Closely related to sg_print_sense(). Puts decode sense data in 'buff'. * Usually multiline with multiple '\n' including one trailing. If * 'raw_sinfo' set appends sense buffer in hex. */ extern void sg_get_sense_str(const char * leadin, const unsigned char * sense_buffer, int sb_len, int raw_sinfo, int buff_len, char * buff); /* Yield string associated with peripheral device type (pdt). Returns * 'buff'. If 'pdt' out of range yields "bad pdt" string. */ extern char * sg_get_pdt_str(int pdt, int buff_len, char * buff); /* Yield string associated with transport protocol identifier (tpi). Returns * 'buff'. If 'tpi' out of range yields "bad tpi" string. */ extern char * sg_get_trans_proto_str(int tpi, int buff_len, char * buff); extern FILE * sg_warnings_strm; extern void sg_set_warnings_strm(FILE * warnings_strm); /* The following "print" functions send ACSII to 'sg_warnings_strm' file * descriptor (default value is stderr) */ extern void sg_print_command(const unsigned char * command); extern void sg_print_sense(const char * leadin, const unsigned char * sense_buffer, int sb_len, int raw_info); extern void sg_print_scsi_status(int scsi_status); /* Utilities can use these process status values for syntax errors and * file (device node) problems (e.g. not found or permissions). */ #define SG_LIB_SYNTAX_ERROR 1 #define SG_LIB_FILE_ERROR 15 /* The sg_err_category_sense() function returns one of the following. * These may be used as process status values (on exit). Notice that * some of the lower values correspond to SCSI sense key values. */ #define SG_LIB_CAT_CLEAN 0 /* No errors or other information */ /* Value 1 left unused for utilities to use SG_LIB_SYNTAX_ERROR */ #define SG_LIB_CAT_NOT_READY 2 /* interpreted from sense buffer */ /* [sk,asc,ascq: 0x2,*,*] */ #define SG_LIB_CAT_MEDIUM_HARD 3 /* medium or hardware error, blank check */ /* [sk,asc,ascq: 0x3/0x4/0x8,*,*] */ #define SG_LIB_CAT_ILLEGAL_REQ 5 /* Illegal request (other than invalid */ /* opcode): [sk,asc,ascq: 0x5,*,*] */ #define SG_LIB_CAT_UNIT_ATTENTION 6 /* interpreted from sense buffer */ /* [sk,asc,ascq: 0x6,*,*] */ /* was SG_LIB_CAT_MEDIA_CHANGED earlier [sk,asc,ascq: 0x6,0x28,*] */ #define SG_LIB_CAT_INVALID_OP 9 /* (Illegal request,) Invalid opcode: */ /* [sk,asc,ascq: 0x5,0x20,0x0] */ #define SG_LIB_CAT_ABORTED_COMMAND 11 /* interpreted from sense buffer */ /* [sk,asc,ascq: 0xb,*,*] */ #define SG_LIB_CAT_NO_SENSE 20 /* sense data with key of "no sense" */ /* [sk,asc,ascq: 0x0,*,*] */ #define SG_LIB_CAT_RECOVERED 21 /* Successful command after recovered err */ /* [sk,asc,ascq: 0x1,*,*] */ #define SG_LIB_CAT_MALFORMED 97 /* Response to SCSI command malformed */ #define SG_LIB_CAT_SENSE 98 /* Something else is in the sense buffer */ #define SG_LIB_CAT_OTHER 99 /* Some other error/warning has occurred */ /* (e.g. a transport or driver error) */ extern int sg_err_category_sense(const unsigned char * sense_buffer, int sb_len); /* Here are some additional sense data categories that are not returned * by sg_err_category_sense() but are returned by some related functions. */ #define SG_LIB_CAT_ILLEGAL_REQ_WITH_INFO 17 /* Illegal request (other than */ /* invalid opcode) plus 'info' field: */ /* [sk,asc,ascq: 0x5,*,*] */ #define SG_LIB_CAT_MEDIUM_HARD_WITH_INFO 18 /* medium or hardware error */ /* sense key plus 'info' field: */ /* [sk,asc,ascq: 0x3/0x4,*,*] */ #define SG_LIB_CAT_TIMEOUT 33 /* Iterates to next designation descriptor in the device identification * VPD page. The 'initial_desig_desc' should point to start of first * descriptor with 'page_len' being the number of valid bytes in that * and following descriptors. To start, 'off' should point to a negative * value, thereafter it should point to the value yielded by the previous * call. If 0 returned then 'initial_desig_desc + *off' should be a valid * descriptor; returns -1 if normal end condition and -2 for an abnormal * termination. Matches association, designator_type and/or code_set when * any of those values are greater than or equal to zero. */ extern int sg_vpd_dev_id_iter(const unsigned char * initial_desig_desc, int page_len, int * off, int m_assoc, int m_desig_type, int m_code_set); /* <<< General purpose (i.e. not SCSI specific) utility functions >>> */ /* Always returns valid string even if errnum is wild (or library problem). * If errnum is negative, flip its sign. */ extern char * safe_strerror(int errnum); /* Print (to stdout) 'str' of bytes in hex, 16 bytes per line optionally * followed at the right hand side of the line with an ASCII interpretation. * Each line is prefixed with an address, starting at 0 for str[0]..str[15]. * All output numbers are in hex. 'no_ascii' allows for 3 output types: * > 0 each line has address then up to 16 ASCII-hex bytes * = 0 in addition, the bytes are listed in ASCII to the right * < 0 only the ASCII-hex bytes are listed (i.e. without address) */ extern void dStrHex(const char* str, int len, int no_ascii); /* Returns 1 when executed on big endian machine; else returns 0. * Useful for displaying ATA identify words (which need swapping on a * big endian machine). */ extern int sg_is_big_endian(); /* Extract character sequence from ATA words as in the model string * in a IDENTIFY DEVICE response. Returns number of characters * written to 'ochars' before 0 character is found or 'num' words * are processed. */ extern int sg_ata_get_chars(const unsigned short * word_arr, int start_word, int num_words, int is_big_endian, char * ochars); /* Print (to stdout) 16 bit 'words' in hex, 8 words per line optionally * followed at the right hand side of the line with an ASCII interpretation * (pairs of ASCII characters in big endian order (upper first)). * Each line is prefixed with an address, starting at 0. * All output numbers are in hex. 'no_ascii' allows for 3 output types: * > 0 each line has address then up to 8 ASCII-hex words * = 0 in addition, the words are listed in ASCII pairs to the right * = -1 only the ASCII-hex words are listed (i.e. without address) * = -2 only the ASCII-hex words, formatted for "hdparm --Istdin" * < -2 same as -1 * If 'swapb' non-zero then bytes in each word swapped. Needs to be set * for ATA IDENTIFY DEVICE response on big-endian machines. */ extern void dWordHex(const unsigned short* words, int num, int no_ascii, int swapb); /* If the number in 'buf' can not be decoded or the multiplier is unknown * then -1 is returned. Accepts a hex prefix (0x or 0X) or a 'h' (or 'H') * suffix. Otherwise a decimal multiplier suffix may be given. Recognised * multipliers: c C *1; w W *2; b B *512; k K KiB *1,024; * KB *1,000; m M MiB *1,048,576; MB *1,000,000; g G GiB *1,073,741,824; * GB *1,000,000,000 and x which multiplies by . */ extern int sg_get_num(const char * buf); /* If the number in 'buf' can not be decoded then -1 is returned. Accepts a * hex prefix (0x or 0X) or a 'h' (or 'H') suffix; otherwise decimal is * assumed. Does not accept multipliers. Accept a comma (","), a whitespace * or newline as terminator. */ extern int sg_get_num_nomult(const char * buf); /* If the number in 'buf' can not be decoded or the multiplier is unknown * then -1LL is returned. Accepts a hex prefix (0x or 0X) or a 'h' (or 'H') * suffix. Otherwise a decimal multiplier suffix may be given. In addition * to supporting the multipliers of sg_get_num(), this function supports: * t T TiB *(2**40); TB *(10**12); p P PiB *(2**50); PB *(10**15) . */ extern int64_t sg_get_llnum(const char * buf); /* <<< Architectural support functions [is there a better place?] >>> */ /* Non Unix OSes distinguish between text and binary files. * Set text mode on fd. Does nothing in Unix. Returns negative number on * failure. */ extern int sg_set_text_mode(int fd); /* Set binary mode on fd. Does nothing in Unix. Returns negative number on * failure. */ extern int sg_set_binary_mode(int fd); #ifdef __cplusplus } #endif #endif ddpt-0.92/include/sg_lib_data.h0000644000175000017500000000454211346470114015425 0ustar douggdougg#ifndef SG_LIB_DATA_H #define SG_LIB_DATA_H /* * Copyright (c) 2007-2010 Douglas Gilbert. * All rights reserved. * Use of this source code is governed by a BSD-style * license that can be found in the BSD_LICENSE file. */ /* * This header file contains some structure declarations and array name * declarations which are defined in the sg_lib_data.c . * Typically this header does not need to be exposed to users of the * sg_lib interface declared in sg_libs.h . */ #include #ifdef __cplusplus extern "C" { #endif /* Commands with service actions that change the command name */ #define SG_MAINTENANCE_IN 0xa3 #define SG_MAINTENANCE_OUT 0xa4 #define SG_PERSISTENT_RESERVE_IN 0x5e #define SG_PERSISTENT_RESERVE_OUT 0x5f #define SG_SERVICE_ACTION_IN_12 0xab #define SG_SERVICE_ACTION_OUT_12 0xa9 #define SG_SERVICE_ACTION_IN_16 0x9e #define SG_SERVICE_ACTION_OUT_16 0x9f #define SG_VARIABLE_LENGTH_CMD 0x7f struct sg_lib_value_name_t { int value; int peri_dev_type; /* 0 -> SPC and/or PDT_DISK, >0 -> PDT */ const char * name; }; struct sg_lib_asc_ascq_t { unsigned char asc; /* additional sense code */ unsigned char ascq; /* additional sense code qualifier */ const char * text; }; struct sg_lib_asc_ascq_range_t { unsigned char asc; /* additional sense code (ASC) */ unsigned char ascq_min; /* ASCQ minimum in range */ unsigned char ascq_max; /* ASCQ maximum in range */ const char * text; }; extern const char * sg_lib_version_str; extern struct sg_lib_value_name_t sg_lib_normal_opcodes[]; extern struct sg_lib_value_name_t sg_lib_maint_in_arr[]; extern struct sg_lib_value_name_t sg_lib_maint_out_arr[]; extern struct sg_lib_value_name_t sg_lib_pr_in_arr[]; extern struct sg_lib_value_name_t sg_lib_pr_out_arr[]; extern struct sg_lib_value_name_t sg_lib_serv_in12_arr[]; extern struct sg_lib_value_name_t sg_lib_serv_out12_arr[]; extern struct sg_lib_value_name_t sg_lib_serv_in16_arr[]; extern struct sg_lib_value_name_t sg_lib_serv_out16_arr[]; extern struct sg_lib_value_name_t sg_lib_variable_length_arr[]; extern struct sg_lib_asc_ascq_range_t sg_lib_asc_ascq_range[]; extern struct sg_lib_asc_ascq_t sg_lib_asc_ascq[]; extern const char * sg_lib_sense_key_desc[]; extern const char * sg_lib_pdt_strs[]; extern const char * sg_lib_transport_proto_strs[]; #ifdef __cplusplus } #endif #endif ddpt-0.92/include/sg_cmds_basic.h0000644000175000017500000003021611504563063015754 0ustar douggdougg#ifndef SG_CMDS_BASIC_H #define SG_CMDS_BASIC_H /* * Copyright (c) 2004-2010 Douglas Gilbert. * All rights reserved. * Use of this source code is governed by a BSD-style * license that can be found in the BSD_LICENSE file. */ #ifdef __cplusplus extern "C" { #endif /* Invokes a SCSI INQUIRY command and yields the response * Returns 0 when successful, SG_LIB_CAT_INVALID_OP -> not supported, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, * SG_LIB_CAT_ABORTED_COMMAND, -1 -> other errors */ extern int sg_ll_inquiry(int sg_fd, int cmddt, int evpd, int pg_op, void * resp, int mx_resp_len, int noisy, int verbose); /* Invokes a SCSI LOG SELECT command. Return of 0 -> success, * SG_LIB_CAT_INVALID_OP -> Log Select not supported, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_UNIT_ATTENTION, * SG_LIB_CAT_ABORTED_COMMAND, * SG_LIB_CAT_NOT_READY -> device not ready, * -1 -> other failure */ extern int sg_ll_log_select(int sg_fd, int pcr, int sp, int pc, int pg_code, int subpg_code, unsigned char * paramp, int param_len, int noisy, int verbose); /* Invokes a SCSI LOG SENSE command. Return of 0 -> success, * SG_LIB_CAT_INVALID_OP -> Log Sense not supported, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_UNIT_ATTENTION, * SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND, * -1 -> other failure */ extern int sg_ll_log_sense(int sg_fd, int ppc, int sp, int pc, int pg_code, int subpg_code, int paramp, unsigned char * resp, int mx_resp_len, int noisy, int verbose); /* Invokes a SCSI MODE SELECT (6) command. Return of 0 -> success, * SG_LIB_CAT_INVALID_OP -> invalid opcode, SG_LIB_CAT_ILLEGAL_REQ -> * bad field in cdb, * SG_LIB_CAT_NOT_READY -> device not ready, * SG_LIB_CAT_UNIT_ATTENTION, SG_LIB_CAT_ABORTED_COMMAND, * -1 -> other failure */ extern int sg_ll_mode_select6(int sg_fd, int pf, int sp, void * paramp, int param_len, int noisy, int verbose); /* Invokes a SCSI MODE SELECT (10) command. Return of 0 -> success, * SG_LIB_CAT_INVALID_OP -> invalid opcode, SG_LIB_CAT_ILLEGAL_REQ -> * bad field in cdb, * SG_LIB_CAT_NOT_READY -> device not ready, * SG_LIB_CAT_UNIT_ATTENTION, SG_LIB_CAT_ABORTED_COMMAND, * -1 -> other failure */ extern int sg_ll_mode_select10(int sg_fd, int pf, int sp, void * paramp, int param_len, int noisy, int verbose); /* Invokes a SCSI MODE SENSE (6) command. Return of 0 -> success, * SG_LIB_CAT_INVALID_OP -> invalid opcode, SG_LIB_CAT_ILLEGAL_REQ -> * bad field in cdb, * SG_LIB_CAT_NOT_READY -> device not ready, * SG_LIB_CAT_UNIT_ATTENTION, SG_LIB_CAT_ABORTED_COMMAND, * -1 -> other failure */ extern int sg_ll_mode_sense6(int sg_fd, int dbd, int pc, int pg_code, int sub_pg_code, void * resp, int mx_resp_len, int noisy, int verbose); /* Invokes a SCSI MODE SENSE (10) command. Return of 0 -> success, * SG_LIB_CAT_INVALID_OP -> invalid opcode, SG_LIB_CAT_ILLEGAL_REQ -> * bad field in cdb, * SG_LIB_CAT_NOT_READY -> device not ready, * SG_LIB_CAT_UNIT_ATTENTION, SG_LIB_CAT_ABORTED_COMMAND, * -1 -> other failure */ extern int sg_ll_mode_sense10(int sg_fd, int llbaa, int dbd, int pc, int pg_code, int sub_pg_code, void * resp, int mx_resp_len, int noisy, int verbose); /* Invokes a SCSI PREVENT ALLOW MEDIUM REMOVAL command (SPC-3) * prevent==0 allows removal, prevent==1 prevents removal ... * Return of 0 -> success, * SG_LIB_CAT_INVALID_OP -> command not supported * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_UNIT_ATTENTION, * SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND, * -1 -> other failure */ extern int sg_ll_prevent_allow(int sg_fd, int prevent, int noisy, int verbose); /* Invokes a SCSI READ CAPACITY (10) command. Return of 0 -> success, * SG_LIB_CAT_INVALID_OP -> invalid opcode, SG_LIB_CAT_UNIT_ATTENTION * -> perhaps media changed, SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, * SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND, * -1 -> other failure */ extern int sg_ll_readcap_10(int sg_fd, int pmi, unsigned int lba, void * resp, int mx_resp_len, int noisy, int verbose); /* Invokes a SCSI READ CAPACITY (16) command. Returns 0 -> success, * SG_LIB_CAT_UNIT_ATTENTION -> media changed??, SG_LIB_CAT_INVALID_OP * -> cdb not supported, SG_LIB_CAT_IlLEGAL_REQ -> bad field in cdb * SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND, * -1 -> other failure */ extern int sg_ll_readcap_16(int sg_fd, int pmi, uint64_t llba, void * resp, int mx_resp_len, int noisy, int verbose); /* Invokes a SCSI REPORT LUNS command. Return of 0 -> success, * SG_LIB_CAT_INVALID_OP -> Report Luns not supported, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_ABORTED_COMMAND, * SG_LIB_NOT_READY (shouldn't happen), -1 -> other failure */ extern int sg_ll_report_luns(int sg_fd, int select_report, void * resp, int mx_resp_len, int noisy, int verbose); /* Invokes a SCSI REQUEST SENSE command. Return of 0 -> success, * SG_LIB_CAT_INVALID_OP -> Request Sense not supported??, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_ABORTED_COMMAND, * -1 -> other failure */ extern int sg_ll_request_sense(int sg_fd, int desc, void * resp, int mx_resp_len, int noisy, int verbose); /* Invokes a SCSI START STOP UNIT command (SBC + MMC). * Return of 0 -> success, * SG_LIB_CAT_INVALID_OP -> Start stop unit not supported, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_UNIT_ATTENTION, * SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND, * -1 -> other failure * SBC-3 and MMC partially overlap on the power_condition_modifier(sbc) and * format_layer_number(mmc) fields. They also overlap on the noflush(sbc) * and fl(mmc) one bit field. This is the cause of the awkardly named * pc_mod__fl_num and noflush__fl arguments to this function. */ extern int sg_ll_start_stop_unit(int sg_fd, int immed, int pc_mod__fl_num, int power_cond, int noflush__fl, int loej, int start, int noisy, int verbose); /* Invokes a SCSI SYNCHRONIZE CACHE (10) command. Return of 0 -> success, * SG_LIB_CAT_UNIT_ATTENTION, SG_LIB_CAT_ABORTED_COMMAND, * SG_LIB_CAT_INVALID_OP -> cdb not supported, * SG_LIB_CAT_IlLEGAL_REQ -> bad field in cdb * SG_LIB_CAT_NOT_READY -> device not ready, -1 -> other failure */ extern int sg_ll_sync_cache_10(int sg_fd, int sync_nv, int immed, int group, unsigned int lba, unsigned int count, int noisy, int verbose); /* Invokes a SCSI TEST UNIT READY command. * 'pack_id' is just for diagnostics, safe to set to 0. * Return of 0 -> success, SG_LIB_CAT_UNIT_ATTENTION, * SG_LIB_CAT_NOT_READY -> device not ready, * SG_LIB_CAT_ABORTED_COMMAND, -1 -> other failure */ extern int sg_ll_test_unit_ready(int sg_fd, int pack_id, int noisy, int verbose); /* Invokes a SCSI TEST UNIT READY command. * 'pack_id' is just for diagnostics, safe to set to 0. * Looks for progress indicator if 'progress' non-NULL; * if found writes value [0..65535] else write -1. * Return of 0 -> success, SG_LIB_CAT_UNIT_ATTENTION, * SG_LIB_CAT_ABORTED_COMMAND, SG_LIB_CAT_NOT_READY -> * device not ready, -1 -> other failure */ extern int sg_ll_test_unit_ready_progress(int sg_fd, int pack_id, int * progress, int noisy, int verbose); struct sg_simple_inquiry_resp { unsigned char peripheral_qualifier; unsigned char peripheral_type; unsigned char rmb; unsigned char version; /* as per recent drafts: whole of byte 2 */ unsigned char byte_3; unsigned char byte_5; unsigned char byte_6; unsigned char byte_7; char vendor[9]; char product[17]; char revision[5]; }; /* Yields most of first 36 bytes of a standard INQUIRY (evpd==0) response. * Returns 0 when successful, SG_LIB_CAT_INVALID_OP -> not supported, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_ABORTED_COMMAND, * -1 -> other errors */ extern int sg_simple_inquiry(int sg_fd, struct sg_simple_inquiry_resp * inq_data, int noisy, int verbose); /* MODE SENSE commands yield a response that has block descriptors followed * by mode pages. In most cases users are interested in the first mode page. * This function returns the (byte) offset of the start of the first mode * page. Set mode_sense_6 to 1 for MODE SENSE (6) and 0 for MODE SENSE (10). * Returns >= 0 is successful or -1 if failure. If there is a failure * a message is written to err_buff. */ extern int sg_mode_page_offset(const unsigned char * resp, int resp_len, int mode_sense_6, char * err_buff, int err_buff_len); /* Fetches current, changeable, default and/or saveable modes pages as * indicated by pcontrol_arr for given pg_code and sub_pg_code. If * mode6==0 then use MODE SENSE (10) else use MODE SENSE (6). If * flexible set and mode data length seems wrong then try and * fix (compensating hack for bad device or driver). pcontrol_arr * should have 4 elements for output of current, changeable, default * and saved values respectively. Each element should be NULL or * at least mx_mpage_len bytes long. * Return of 0 -> overall success, SG_LIB_CAT_INVALID_OP -> invalid opcode, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_UNIT_ATTENTION, * SG_LIB_CAT_NOT_READY -> device not ready, * SG_LIB_CAT_MALFORMED -> bad response, -1 -> other failure. * If success_mask pointer is not NULL then first zeros it. Then set bits * 0, 1, 2 and/or 3 if the current, changeable, default and saved values * respectively have been fetched. If error on current page * then stops and returns that error; otherwise continues if an error is * detected but returns the first error encountered. */ extern int sg_get_mode_page_controls(int sg_fd, int mode6, int pg_code, int sub_pg_code, int dbd, int flexible, int mx_mpage_len, int * success_mask, void * pcontrol_arr[], int * reported_len, int verbose); /* Returns file descriptor >= 0 if successful. If error in Unix returns negated errno. Implementation calls scsi_pt_open_device(). */ extern int sg_cmds_open_device(const char * device_name, int read_only, int verbose); /* Returns file descriptor >= 0 if successful. If error in Unix returns negated errno. Implementation calls scsi_pt_open_flags(). */ extern int sg_cmds_open_flags(const char * device_name, int flags, int verbose); /* Returns 0 if successful. If error in Unix returns negated errno. Implementation calls scsi_pt_close_device(). */ extern int sg_cmds_close_device(int device_fd); extern const char * sg_cmds_version(); struct sg_pt_base; /* This is a helper function used by all sg_cmds_* implementations. * If valid sense data is found it is decoded and output to sg_warnings_strm * (def: stderr); depending on the 'noisy' and 'verbose' settings. * Returns -2 for sense data (may not be fatal), -1 for failed or the * number of data in bytes received. For data out (to device) or no data, * set 'mx_di_len' to 0 or less. If -2 returned then sense category * output via 'o_sense_cat' pointer (if not NULL). Note that several sense * categories also have data in bytes received; -2 is still returned. */ extern int sg_cmds_process_resp(struct sg_pt_base * ptvp, const char * leadin, int res, int mx_di_len, const unsigned char * sense_b, int noisy, int verbose, int * o_sense_cat); #ifdef __cplusplus } #endif #endif ddpt-0.92/include/sg_pt_win32.h0000644000175000017500000001057111205600074015324 0ustar douggdougg#ifndef SG_PT_WIN32_H #define SG_PT_WIN32_H /* * The information in this file was obtained from scsi-wnt.h by * Richard Stemmer, rs@epost.de . He in turn gives credit to * Jay A. Key (for scsipt.c). * The plscsi program (by Pat LaVarre ) has * also been used as a reference. * Much of the information in this header can also be obtained * from msdn.microsoft.com . */ #include #define SCSI_MAX_SENSE_LEN 64 #define SCSI_MAX_CDB_LEN 16 #define SCSI_MAX_INDIRECT_DATA 16384 typedef struct { USHORT Length; UCHAR ScsiStatus; UCHAR PathId; UCHAR TargetId; UCHAR Lun; UCHAR CdbLength; UCHAR SenseInfoLength; UCHAR DataIn; ULONG DataTransferLength; ULONG TimeOutValue; ULONG DataBufferOffset; ULONG SenseInfoOffset; UCHAR Cdb[SCSI_MAX_CDB_LEN]; } SCSI_PASS_THROUGH, *PSCSI_PASS_THROUGH; typedef struct { USHORT Length; UCHAR ScsiStatus; UCHAR PathId; UCHAR TargetId; UCHAR Lun; UCHAR CdbLength; UCHAR SenseInfoLength; UCHAR DataIn; ULONG DataTransferLength; ULONG TimeOutValue; PVOID DataBuffer; ULONG SenseInfoOffset; UCHAR Cdb[SCSI_MAX_CDB_LEN]; } SCSI_PASS_THROUGH_DIRECT, *PSCSI_PASS_THROUGH_DIRECT; typedef struct { SCSI_PASS_THROUGH spt; /* plscsi shows a follow on 16 bytes allowing 32 byte cdb */ ULONG Filler; UCHAR ucSenseBuf[SCSI_MAX_SENSE_LEN]; UCHAR ucDataBuf[SCSI_MAX_INDIRECT_DATA]; } SCSI_PASS_THROUGH_WITH_BUFFERS, *PSCSI_PASS_THROUGH_WITH_BUFFERS; typedef struct { SCSI_PASS_THROUGH_DIRECT spt; ULONG Filler; UCHAR ucSenseBuf[SCSI_MAX_SENSE_LEN]; } SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, *PSCSI_PASS_THROUGH_DIRECT_WITH_BUFFER; typedef struct { UCHAR NumberOfLogicalUnits; UCHAR InitiatorBusId; ULONG InquiryDataOffset; } SCSI_BUS_DATA, *PSCSI_BUS_DATA; typedef struct { UCHAR NumberOfBusses; SCSI_BUS_DATA BusData[1]; } SCSI_ADAPTER_BUS_INFO, *PSCSI_ADAPTER_BUS_INFO; typedef struct { UCHAR PathId; UCHAR TargetId; UCHAR Lun; BOOLEAN DeviceClaimed; ULONG InquiryDataLength; ULONG NextInquiryDataOffset; UCHAR InquiryData[1]; } SCSI_INQUIRY_DATA, *PSCSI_INQUIRY_DATA; typedef struct { ULONG Length; UCHAR PortNumber; UCHAR PathId; UCHAR TargetId; UCHAR Lun; } SCSI_ADDRESS, *PSCSI_ADDRESS; /* * method codes */ #define METHOD_BUFFERED 0 #define METHOD_IN_DIRECT 1 #define METHOD_OUT_DIRECT 2 #define METHOD_NEITHER 3 /* * file access values */ #define FILE_ANY_ACCESS 0 #define FILE_READ_ACCESS 0x0001 #define FILE_WRITE_ACCESS 0x0002 #define IOCTL_SCSI_BASE 0x00000004 /* * constants for DataIn member of SCSI_PASS_THROUGH* structures */ #define SCSI_IOCTL_DATA_OUT 0 #define SCSI_IOCTL_DATA_IN 1 #define SCSI_IOCTL_DATA_UNSPECIFIED 2 /* * Standard IOCTL define */ #define CTL_CODE(DevType, Function, Method, Access) \ (((DevType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method)) #define IOCTL_SCSI_PASS_THROUGH CTL_CODE(IOCTL_SCSI_BASE, 0x0401, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) #define IOCTL_SCSI_MINIPORT CTL_CODE(IOCTL_SCSI_BASE, 0x0402, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) #define IOCTL_SCSI_GET_INQUIRY_DATA CTL_CODE(IOCTL_SCSI_BASE, 0x0403, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_SCSI_GET_CAPABILITIES CTL_CODE(IOCTL_SCSI_BASE, 0x0404, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_SCSI_PASS_THROUGH_DIRECT CTL_CODE(IOCTL_SCSI_BASE, 0x0405, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) #define IOCTL_SCSI_GET_ADDRESS CTL_CODE(IOCTL_SCSI_BASE, 0x0406, METHOD_BUFFERED, FILE_ANY_ACCESS) #endif ddpt-0.92/include/Makefile.in0000644000175000017500000003740511446023005015067 0ustar douggdougg# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, # Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = include DIST_COMMON = $(am__noinst_HEADERS_DIST) \ $(am__scsiinclude_HEADERS_DIST) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = SOURCES = DIST_SOURCES = am__noinst_HEADERS_DIST = sg_linux_inc.h sg_io_linux.h sg_pt_win32.h am__scsiinclude_HEADERS_DIST = sg_lib.h sg_lib_data.h sg_cmds.h \ sg_cmds_basic.h sg_cmds_extra.h sg_cmds_mmc.h sg_pt.h \ sg_linux_inc.h sg_io_linux.h sg_pt_win32.h am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__installdirs = "$(DESTDIR)$(scsiincludedir)" HEADERS = $(noinst_HEADERS) $(scsiinclude_HEADERS) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GETOPT_O_FILES = @GETOPT_O_FILES@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ os_libs = @os_libs@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ scsiincludedir = $(includedir)/scsi @OS_FREEBSD_TRUE@scsiinclude_HEADERS = \ @OS_FREEBSD_TRUE@ sg_lib.h \ @OS_FREEBSD_TRUE@ sg_lib_data.h \ @OS_FREEBSD_TRUE@ sg_cmds.h \ @OS_FREEBSD_TRUE@ sg_cmds_basic.h \ @OS_FREEBSD_TRUE@ sg_cmds_extra.h \ @OS_FREEBSD_TRUE@ sg_cmds_mmc.h \ @OS_FREEBSD_TRUE@ sg_pt.h @OS_LINUX_TRUE@scsiinclude_HEADERS = \ @OS_LINUX_TRUE@ sg_lib.h \ @OS_LINUX_TRUE@ sg_lib_data.h \ @OS_LINUX_TRUE@ sg_cmds.h \ @OS_LINUX_TRUE@ sg_cmds_basic.h \ @OS_LINUX_TRUE@ sg_cmds_extra.h \ @OS_LINUX_TRUE@ sg_cmds_mmc.h \ @OS_LINUX_TRUE@ sg_pt.h \ @OS_LINUX_TRUE@ sg_linux_inc.h \ @OS_LINUX_TRUE@ sg_io_linux.h @OS_OSF_TRUE@scsiinclude_HEADERS = \ @OS_OSF_TRUE@ sg_lib.h \ @OS_OSF_TRUE@ sg_lib_data.h \ @OS_OSF_TRUE@ sg_cmds.h \ @OS_OSF_TRUE@ sg_cmds_basic.h \ @OS_OSF_TRUE@ sg_cmds_extra.h \ @OS_OSF_TRUE@ sg_cmds_mmc.h \ @OS_OSF_TRUE@ sg_pt.h @OS_SOLARIS_TRUE@scsiinclude_HEADERS = \ @OS_SOLARIS_TRUE@ sg_lib.h \ @OS_SOLARIS_TRUE@ sg_lib_data.h \ @OS_SOLARIS_TRUE@ sg_cmds.h \ @OS_SOLARIS_TRUE@ sg_cmds_basic.h \ @OS_SOLARIS_TRUE@ sg_cmds_extra.h \ @OS_SOLARIS_TRUE@ sg_cmds_mmc.h \ @OS_SOLARIS_TRUE@ sg_pt.h @OS_WIN32_CYGWIN_TRUE@scsiinclude_HEADERS = \ @OS_WIN32_CYGWIN_TRUE@ sg_lib.h \ @OS_WIN32_CYGWIN_TRUE@ sg_lib_data.h \ @OS_WIN32_CYGWIN_TRUE@ sg_cmds.h \ @OS_WIN32_CYGWIN_TRUE@ sg_cmds_basic.h \ @OS_WIN32_CYGWIN_TRUE@ sg_cmds_extra.h \ @OS_WIN32_CYGWIN_TRUE@ sg_cmds_mmc.h \ @OS_WIN32_CYGWIN_TRUE@ sg_pt.h \ @OS_WIN32_CYGWIN_TRUE@ sg_pt_win32.h @OS_WIN32_MINGW_TRUE@scsiinclude_HEADERS = \ @OS_WIN32_MINGW_TRUE@ sg_lib.h \ @OS_WIN32_MINGW_TRUE@ sg_lib_data.h \ @OS_WIN32_MINGW_TRUE@ sg_cmds.h \ @OS_WIN32_MINGW_TRUE@ sg_cmds_basic.h \ @OS_WIN32_MINGW_TRUE@ sg_cmds_extra.h \ @OS_WIN32_MINGW_TRUE@ sg_cmds_mmc.h \ @OS_WIN32_MINGW_TRUE@ sg_pt.h \ @OS_WIN32_MINGW_TRUE@ sg_pt_win32.h @OS_FREEBSD_TRUE@noinst_HEADERS = \ @OS_FREEBSD_TRUE@ sg_linux_inc.h \ @OS_FREEBSD_TRUE@ sg_io_linux.h \ @OS_FREEBSD_TRUE@ sg_pt_win32.h @OS_LINUX_TRUE@noinst_HEADERS = \ @OS_LINUX_TRUE@ sg_pt_win32.h @OS_OSF_TRUE@noinst_HEADERS = \ @OS_OSF_TRUE@ sg_linux_inc.h \ @OS_OSF_TRUE@ sg_io_linux.h \ @OS_OSF_TRUE@ sg_pt_win32.h @OS_SOLARIS_TRUE@noinst_HEADERS = \ @OS_SOLARIS_TRUE@ sg_linux_inc.h \ @OS_SOLARIS_TRUE@ sg_io_linux.h \ @OS_SOLARIS_TRUE@ sg_pt_win32.h @OS_WIN32_CYGWIN_TRUE@noinst_HEADERS = \ @OS_WIN32_CYGWIN_TRUE@ sg_linux_inc.h \ @OS_WIN32_CYGWIN_TRUE@ sg_io_linux.h @OS_WIN32_MINGW_TRUE@noinst_HEADERS = \ @OS_WIN32_MINGW_TRUE@ sg_linux_inc.h \ @OS_WIN32_MINGW_TRUE@ sg_io_linux.h all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu include/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu include/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-scsiincludeHEADERS: $(scsiinclude_HEADERS) @$(NORMAL_INSTALL) test -z "$(scsiincludedir)" || $(MKDIR_P) "$(DESTDIR)$(scsiincludedir)" @list='$(scsiinclude_HEADERS)'; test -n "$(scsiincludedir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(scsiincludedir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(scsiincludedir)" || exit $$?; \ done uninstall-scsiincludeHEADERS: @$(NORMAL_UNINSTALL) @list='$(scsiinclude_HEADERS)'; test -n "$(scsiincludedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ test -n "$$files" || exit 0; \ echo " ( cd '$(DESTDIR)$(scsiincludedir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(scsiincludedir)" && rm -f $$files ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(HEADERS) installdirs: for dir in "$(DESTDIR)$(scsiincludedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-scsiincludeHEADERS install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-scsiincludeHEADERS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool ctags distclean distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-scsiincludeHEADERS \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am uninstall-scsiincludeHEADERS # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: ddpt-0.92/include/sg_cmds_extra.h0000644000175000017500000003526211524334352016023 0ustar douggdougg#ifndef SG_CMDS_EXTRA_H #define SG_CMDS_EXTRA_H /* * Copyright (c) 2004-2011 Douglas Gilbert. * All rights reserved. * Use of this source code is governed by a BSD-style * license that can be found in the BSD_LICENSE file. */ #ifdef __cplusplus extern "C" { #endif /* Invokes a ATA PASS-THROUGH (12 or 16) SCSI command (SAT). If cdb_len * is 12 then a ATA PASS-THROUGH (12) command is called. If cdb_len is 16 * then a ATA PASS-THROUGH (16) command is called. If cdb_len is any other * value -1 is returned. After copying from cdbp to an internal buffer, * the first byte (i.e. offset 0) is set to 0xa1 if cdb_len is 12; or is * set to 0x85 if cdb_len is 16. The last byte (offset 11 or offset 15) is * set to 0x0 in the internal buffer. If timeout_secs <= 0 then the timeout * is set to 60 seconds. For data in or out transfers set dinp or doutp, * and dlen to the number of bytes to transfer. If dlen is zero then no data * transfer is assumed. If sense buffer obtained then it is written to * sensep, else sensep[0] is set to 0x0. If ATA return descriptor is obtained * then written to ata_return_dp, else ata_return_dp[0] is set to 0x0. Either * sensep or ata_return_dp (or both) may be NULL pointers. Returns SCSI * status value (>= 0) or -1 if other error. Users are expected to check the * sense buffer themselves. If available the data in resid is written to * residp. */ extern int sg_ll_ata_pt(int sg_fd, const unsigned char * cdbp, int cdb_len, int timeout_secs, void * dinp, void * doutp, int dlen, unsigned char * sensep, int max_sense_len, unsigned char * ata_return_dp, int max_ata_return_len, int * residp, int verbose); /* Invokes a FORMAT UNIT (SBC-3) command. Return of 0 -> success, * SG_LIB_CAT_INVALID_OP -> Format unit not supported, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_UNIT_ATTENTION, * SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND, * -1 -> other failure */ extern int sg_ll_format_unit(int sg_fd, int fmtpinfo, int longlist, int fmtdata, int cmplist, int dlist_format, int timeout_secs, void * paramp, int param_len, int noisy, int verbose); /* Invokes a SCSI GET LBA STATUS command (SBC). Returns 0 -> success, * SG_LIB_CAT_INVALID_OP -> GET LBA STATUS not supported, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_ABORTED_COMMAND, * SG_LIB_CAT_NOT_READY -> device not ready, -1 -> other failure */ extern int sg_ll_get_lba_status(int sg_fd, uint64_t start_llba, void * resp, int alloc_len, int noisy, int verbose); /* Invokes a SCSI PERSISTENT RESERVE IN command (SPC). Returns 0 * when successful, SG_LIB_CAT_INVALID_OP if command not supported, * SG_LIB_CAT_ILLEGAL_REQ if field in cdb not supported, * SG_LIB_CAT_UNIT_ATTENTION, SG_LIB_CAT_ABORTED_COMMAND, else -1 */ extern int sg_ll_persistent_reserve_in(int sg_fd, int rq_servact, void * resp, int mx_resp_len, int noisy, int verbose); /* Invokes a SCSI PERSISTENT RESERVE OUT command (SPC). Returns 0 * when successful, SG_LIB_CAT_INVALID_OP if command not supported, * SG_LIB_CAT_ILLEGAL_REQ if field in cdb not supported, * SG_LIB_CAT_UNIT_ATTENTION, SG_LIB_CAT_ABORTED_COMMAND, else -1 */ extern int sg_ll_persistent_reserve_out(int sg_fd, int rq_servact, int rq_scope, unsigned int rq_type, void * paramp, int param_len, int noisy, int verbose); /* Invokes a SCSI READ BLOCK LIMITS command. Return of 0 -> success, * SG_LIB_CAT_INVALID_OP -> READ BLOCK LIMITS not supported, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_ABORTED_COMMAND, * SG_LIB_NOT_READY (shouldn't happen), -1 -> other failure */ extern int sg_ll_read_block_limits(int sg_fd, void * resp, int mx_resp_len, int noisy, int verbose); /* Invokes a SCSI READ BUFFER command (SPC). Return of 0 -> * success, SG_LIB_CAT_INVALID_OP -> invalid opcode, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_UNIT_ATTENTION, * SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND, * -1 -> other failure */ extern int sg_ll_read_buffer(int sg_fd, int mode, int buffer_id, int buffer_offset, void * resp, int mx_resp_len, int noisy, int verbose); /* Invokes a SCSI READ DEFECT DATA (10) command (SBC). Return of 0 -> * success, SG_LIB_CAT_INVALID_OP -> invalid opcode, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_UNIT_ATTENTION, * SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND, * -1 -> other failure */ extern int sg_ll_read_defect10(int sg_fd, int req_plist, int req_glist, int dl_format, void * resp, int mx_resp_len, int noisy, int verbose); /* Invokes a SCSI READ LONG (10) command (SBC). Note that 'xfer_len' * is in bytes. Returns 0 -> success, * SG_LIB_CAT_INVALID_OP -> READ LONG(10) not supported, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, * SG_LIB_CAT_ILLEGAL_REQ_WITH_INFO -> bad field in cdb, with info * field written to 'offsetp', SG_LIB_CAT_UNIT_ATTENTION, * SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND, * -1 -> other failure */ extern int sg_ll_read_long10(int sg_fd, int pblock, int correct, unsigned int lba, void * resp, int xfer_len, int * offsetp, int noisy, int verbose); /* Invokes a SCSI READ LONG (16) command (SBC). Note that 'xfer_len' * is in bytes. Returns 0 -> success, * SG_LIB_CAT_INVALID_OP -> READ LONG(16) not supported, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, * SG_LIB_CAT_ILLEGAL_REQ_WITH_INFO -> bad field in cdb, with info * field written to 'offsetp', SG_LIB_CAT_UNIT_ATTENTION, * SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND, * -1 -> other failure */ extern int sg_ll_read_long16(int sg_fd, int pblock, int correct, uint64_t llba, void * resp, int xfer_len, int * offsetp, int noisy, int verbose); /* Invokes a SCSI READ MEDIA SERIAL NUMBER command. Return of 0 -> success, * SG_LIB_CAT_INVALID_OP -> Read media serial number not supported, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_UNIT_ATTENTION, * SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND, * -1 -> other failure */ extern int sg_ll_read_media_serial_num(int sg_fd, void * resp, int mx_resp_len, int noisy, int verbose); /* Invokes a SCSI REASSIGN BLOCKS command. Return of 0 -> success, * SG_LIB_CAT_INVALID_OP -> invalid opcode, SG_LIB_CAT_UNIT_ATTENTION, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_ABORTED_COMMAND, * SG_LIB_CAT_NOT_READY -> device not ready, -1 -> other failure */ extern int sg_ll_reassign_blocks(int sg_fd, int longlba, int longlist, void * paramp, int param_len, int noisy, int verbose); /* Invokes a SCSI RECEIVE DIAGNOSTIC RESULTS command. Return of 0 -> success, * SG_LIB_CAT_INVALID_OP -> Receive diagnostic results not supported, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_UNIT_ATTENTION, * SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND, * -1 -> other failure */ extern int sg_ll_receive_diag(int sg_fd, int pcv, int pg_code, void * resp, int mx_resp_len, int noisy, int verbose); /* Invokes a SCSI REPORT IDENTIFYING INFORMATION command. This command was * called REPORT DEVICE IDENTIFIER prior to spc4r07. Return of 0 -> success, * SG_LIB_CAT_INVALID_OP -> Report identifying information not supported, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_UNIT_ATTENTION, * SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND, * -1 -> other failure */ extern int sg_ll_report_id_info(int sg_fd, int itype, void * resp, int max_resp_len, int noisy, int verbose); /* Invokes a SCSI REPORT TARGET PORT GROUPS command. Return of 0 -> success, * SG_LIB_CAT_INVALID_OP -> Report Target Port Groups not supported, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_ABORTED_COMMAND, * SG_LIB_CAT_UNIT_ATTENTION, -1 -> other failure */ extern int sg_ll_report_tgt_prt_grp(int sg_fd, void * resp, int mx_resp_len, int noisy, int verbose); /* Invokes a SCSI SET TARGET PORT GROUPS command. Return of 0 -> success, * SG_LIB_CAT_INVALID_OP -> Report Target Port Groups not supported, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_ABORTED_COMMAND, * SG_LIB_CAT_UNIT_ATTENTION, -1 -> other failure */ extern int sg_ll_set_tgt_prt_grp(int sg_fd, void * paramp, int param_len, int noisy, int verbose); /* Invokes a SCSI REPORT REFERRALS command. Return of 0 -> success, * SG_LIB_CAT_INVALID_OP -> Report Referrals not supported, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_ABORTED_COMMAND, * SG_LIB_CAT_UNIT_ATTENTION, -1 -> other failure */ extern int sg_ll_report_referrals(int sg_fd, uint64_t start_llba, int one_seg, void * resp,int mx_resp_len, int noisy, int verbose); /* Invokes a SCSI SEND DIAGNOSTIC command. Foreground, extended self tests can * take a long time, if so set long_duration flag. Return of 0 -> success, * SG_LIB_CAT_INVALID_OP -> Send diagnostic not supported, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_UNIT_ATTENTION, * SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND, * -1 -> other failure */ extern int sg_ll_send_diag(int sg_fd, int sf_code, int pf_bit, int sf_bit, int devofl_bit, int unitofl_bit, int long_duration, void * paramp, int param_len, int noisy, int verbose); /* Invokes a SCSI SET IDENTIFYING INFORMATION command. This command was * called SET DEVICE IDENTIFIER prior to spc4r07. Return of 0 -> success, * SG_LIB_CAT_INVALID_OP -> Set identifying information not supported, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_UNIT_ATTENTION, * SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND, * -1 -> other failure */ extern int sg_ll_set_id_info(int sg_fd, int itype, void * paramp, int param_len, int noisy, int verbose); /* Invokes a SCSI UNMAP (SBC-3) command. Return of 0 -> success, * SG_LIB_CAT_INVALID_OP -> command not supported, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_ABORTED_COMMAND, * SG_LIB_CAT_UNIT_ATTENTION, -1 -> other failure */ extern int sg_ll_unmap(int sg_fd, int group_num, int timeout_secs, void * paramp, int param_len, int noisy, int verbose); /* Invokes a SCSI UNMAP (SBC-3) command. Version 2 adds anchor field * (sbc3r22). Otherwise same as sg_ll_unmap() . */ extern int sg_ll_unmap_v2(int sg_fd, int anchor, int group_num, int timeout_secs, void * paramp, int param_len, int noisy, int verbose); /* Invokes a SCSI VERIFY (10) command (SBC and MMC). * Note that 'veri_len' is in blocks while 'data_out_len' is in bytes. * Returns of 0 -> success, * SG_LIB_CAT_INVALID_OP -> Verify(10) not supported, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_UNIT_ATTENTION, * SG_LIB_CAT_MEDIUM_HARD -> medium or hardware error, no valid info, * SG_LIB_CAT_MEDIUM_HARD_WITH_INFO -> as previous, with valid info, * SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND, * -1 -> other failure */ extern int sg_ll_verify10(int sg_fd, int vrprotect, int dpo, int bytechk, unsigned int lba, int veri_len, void * data_out, int data_out_len, unsigned int * infop, int noisy, int verbose); /* Invokes a SCSI VERIFY (16) command (SBC). * Note that 'veri_len' is in blocks while 'data_out_len' is in bytes. * Returns of 0 -> success, * SG_LIB_CAT_INVALID_OP -> Verify(16) not supported, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_UNIT_ATTENTION, * SG_LIB_CAT_MEDIUM_HARD -> medium or hardware error, no valid info, * SG_LIB_CAT_MEDIUM_HARD_WITH_INFO -> as previous, with valid info, * SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND, * -1 -> other failure */ extern int sg_ll_verify16(int sg_fd, int vrprotect, int dpo, int bytechk, uint64_t llba, int veri_len, int group_num, void * data_out, int data_out_len, uint64_t * infop, int noisy, int verbose); /* Invokes a SCSI WRITE BUFFER command (SPC). Return of 0 -> * success, SG_LIB_CAT_INVALID_OP -> invalid opcode, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_UNIT_ATTENTION, * SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND, * -1 -> other failure */ extern int sg_ll_write_buffer(int sg_fd, int mode, int buffer_id, int buffer_offset, void * paramp, int param_len, int noisy, int verbose); /* Invokes a SCSI WRITE LONG (10) command (SBC). Note that 'xfer_len' * is in bytes. Returns 0 -> success, * SG_LIB_CAT_INVALID_OP -> WRITE LONG(10) not supported, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, * SG_LIB_CAT_ILLEGAL_REQ_WITH_INFO -> bad field in cdb, with info * field written to 'offsetp', SG_LIB_CAT_UNIT_ATTENTION, * SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND, * -1 -> other failure */ extern int sg_ll_write_long10(int sg_fd, int cor_dis, int wr_uncor, int pblock, unsigned int lba, void * data_out, int xfer_len, int * offsetp, int noisy, int verbose); /* Invokes a SCSI WRITE LONG (16) command (SBC). Note that 'xfer_len' * is in bytes. Returns 0 -> success, * SG_LIB_CAT_INVALID_OP -> WRITE LONG(16) not supported, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, * SG_LIB_CAT_ILLEGAL_REQ_WITH_INFO -> bad field in cdb, with info * field written to 'offsetp', SG_LIB_CAT_UNIT_ATTENTION, * SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND, * -1 -> other failure */ extern int sg_ll_write_long16(int sg_fd, int cor_dis, int wr_uncor, int pblock, uint64_t llba, void * data_out, int xfer_len, int * offsetp, int noisy, int verbose); #ifdef __cplusplus } #endif #endif ddpt-0.92/include/Makefile.am0000644000175000017500000000256411215540460015057 0ustar douggdougg scsiincludedir = $(includedir)/scsi if OS_LINUX scsiinclude_HEADERS = \ sg_lib.h \ sg_lib_data.h \ sg_cmds.h \ sg_cmds_basic.h \ sg_cmds_extra.h \ sg_cmds_mmc.h \ sg_pt.h \ sg_linux_inc.h \ sg_io_linux.h noinst_HEADERS = \ sg_pt_win32.h endif if OS_WIN32_MINGW scsiinclude_HEADERS = \ sg_lib.h \ sg_lib_data.h \ sg_cmds.h \ sg_cmds_basic.h \ sg_cmds_extra.h \ sg_cmds_mmc.h \ sg_pt.h \ sg_pt_win32.h noinst_HEADERS = \ sg_linux_inc.h \ sg_io_linux.h endif if OS_WIN32_CYGWIN scsiinclude_HEADERS = \ sg_lib.h \ sg_lib_data.h \ sg_cmds.h \ sg_cmds_basic.h \ sg_cmds_extra.h \ sg_cmds_mmc.h \ sg_pt.h \ sg_pt_win32.h noinst_HEADERS = \ sg_linux_inc.h \ sg_io_linux.h endif if OS_FREEBSD scsiinclude_HEADERS = \ sg_lib.h \ sg_lib_data.h \ sg_cmds.h \ sg_cmds_basic.h \ sg_cmds_extra.h \ sg_cmds_mmc.h \ sg_pt.h noinst_HEADERS = \ sg_linux_inc.h \ sg_io_linux.h \ sg_pt_win32.h endif if OS_SOLARIS scsiinclude_HEADERS = \ sg_lib.h \ sg_lib_data.h \ sg_cmds.h \ sg_cmds_basic.h \ sg_cmds_extra.h \ sg_cmds_mmc.h \ sg_pt.h noinst_HEADERS = \ sg_linux_inc.h \ sg_io_linux.h \ sg_pt_win32.h endif if OS_OSF scsiinclude_HEADERS = \ sg_lib.h \ sg_lib_data.h \ sg_cmds.h \ sg_cmds_basic.h \ sg_cmds_extra.h \ sg_cmds_mmc.h \ sg_pt.h noinst_HEADERS = \ sg_linux_inc.h \ sg_io_linux.h \ sg_pt_win32.h endif ddpt-0.92/include/sg_pt.h0000644000175000017500000001453311524334352014313 0ustar douggdougg#ifndef SG_PT_H #define SG_PT_H /* * Copyright (c) 2005-2011 Douglas Gilbert. * All rights reserved. * Use of this source code is governed by a BSD-style * license that can be found in the BSD_LICENSE file. */ #include #ifdef __cplusplus extern "C" { #endif /* This declaration hides the fact that each implementation has its own * structure "derived" (using a C++ term) from this one. It compiles * because 'struct sg_pt_base' is only referenced (by pointer: 'objp') * in this interface. An instance of this structure represents the * context of one SCSI command. */ struct sg_pt_base; /* The format of the version string is like this: "2.01 20090201". * The leading digit will be incremented if this interface changes * in a way that may impact backward compatibility. */ extern const char * scsi_pt_version(); /* Returns >= 0 if successful. If error in Unix returns negated errno. */ extern int scsi_pt_open_device(const char * device_name, int read_only, int verbose); /* Similar to scsi_pt_open_device() but takes Unix style open flags OR-ed * together. Returns valid file descriptor( >= 0 ) if successful, otherwise * returns -1 or a negated errno. */ extern int scsi_pt_open_flags(const char * device_name, int flags, int verbose); /* Returns 0 if successful. If error in Unix returns negated errno. */ extern int scsi_pt_close_device(int device_fd); /* Creates an object that can be used to issue one or more SCSI commands * (or task management functions). Returns NULL if problem. * Once this object has been created it should be destroyed with * destruct_scsi_pt_obj() when it is no longer needed. */ extern struct sg_pt_base * construct_scsi_pt_obj(void); /* Clear state information held in *objp . This allows this object to be * used to issue more than one SCSI command. */ extern void clear_scsi_pt_obj(struct sg_pt_base * objp); /* Set the CDB (command descriptor block) */ extern void set_scsi_pt_cdb(struct sg_pt_base * objp, const unsigned char * cdb, int cdb_len); /* Set the sense buffer and the maximum length that it can handle */ extern void set_scsi_pt_sense(struct sg_pt_base * objp, unsigned char * sense, int max_sense_len); /* Set a pointer and length to be used for data transferred from device */ extern void set_scsi_pt_data_in(struct sg_pt_base * objp, /* from device */ unsigned char * dxferp, int dxfer_len); /* Set a pointer and length to be used for data transferred to device */ extern void set_scsi_pt_data_out(struct sg_pt_base * objp, /* to device */ const unsigned char * dxferp, int dxfer_len); /* The following "set_"s implementations may be dummies */ extern void set_scsi_pt_packet_id(struct sg_pt_base * objp, int pack_id); extern void set_scsi_pt_tag(struct sg_pt_base * objp, uint64_t tag); extern void set_scsi_pt_task_management(struct sg_pt_base * objp, int tmf_code); extern void set_scsi_pt_task_attr(struct sg_pt_base * objp, int attribute, int priority); /* Following is a guard which is defined when set_scsi_pt_flags() is * present. Older versions of this library may not have this function. */ #define SCSI_PT_FLAGS_FUNCTION 1 /* If neither QUEUE_AT_HEAD nor QUEUE_AT_TAIL are given, or both * are given, use the pass-through default. */ #define SCSI_PT_FLAGS_QUEUE_AT_TAIL 0x10 #define SCSI_PT_FLAGS_QUEUE_AT_HEAD 0x20 /* Set (potentially OS dependant) flags for pass-through mechanism. * Apart from contradictions, flags can be OR-ed together. */ extern void set_scsi_pt_flags(struct sg_pt_base * objp, int flags); #define SCSI_PT_DO_START_OK 0 #define SCSI_PT_DO_BAD_PARAMS 1 #define SCSI_PT_DO_TIMEOUT 2 /* If OS error prior to or during command submission then returns negated * error value (e.g. Unix '-errno'). This includes interrupted system calls * (e.g. by a signal) in which case -EINTR would be returned. Note that * system call errors also can be fetched with get_scsi_pt_os_err(). * Return 0 if okay (i.e. at the very least: command sent). Positive * return values are errors (see SCSI_PT_DO_* defines). */ extern int do_scsi_pt(struct sg_pt_base * objp, int fd, int timeout_secs, int verbose); #define SCSI_PT_RESULT_GOOD 0 #define SCSI_PT_RESULT_STATUS 1 /* other than GOOD and CHECK CONDITION */ #define SCSI_PT_RESULT_SENSE 2 #define SCSI_PT_RESULT_TRANSPORT_ERR 3 #define SCSI_PT_RESULT_OS_ERR 4 /* highest numbered applicable category returned */ extern int get_scsi_pt_result_category(const struct sg_pt_base * objp); /* If not available return 0 */ extern int get_scsi_pt_resid(const struct sg_pt_base * objp); /* Returns SCSI status value (from device that received the command). */ extern int get_scsi_pt_status_response(const struct sg_pt_base * objp); /* Actual sense length returned. If sense data is present but actual sense length is not known, return 'max_sense_len' */ extern int get_scsi_pt_sense_len(const struct sg_pt_base * objp); /* If not available return 0 */ extern int get_scsi_pt_os_err(const struct sg_pt_base * objp); extern char * get_scsi_pt_os_err_str(const struct sg_pt_base * objp, int max_b_len, char * b); /* If not available return 0 */ extern int get_scsi_pt_transport_err(const struct sg_pt_base * objp); extern char * get_scsi_pt_transport_err_str(const struct sg_pt_base * objp, int max_b_len, char * b); /* If not available return -1 */ extern int get_scsi_pt_duration_ms(const struct sg_pt_base * objp); /* Should be invoked once per objp after other processing is complete in * order to clean up resources. For ever successful construct_scsi_pt_obj() * call there should be one destruct_scsi_pt_obj(). */ extern void destruct_scsi_pt_obj(struct sg_pt_base * objp); #ifdef SG_LIB_WIN32 #define SG_LIB_WIN32_DIRECT 1 /* Request SPT direct interface when state_direct is 1, state_direct set * to 0 for the SPT indirect interface. Default setting selected by build * (i.e. library compile time) and is usually indirect. */ extern void scsi_pt_win32_direct(int state_direct); /* Returns current SPT interface state, 1 for direct, 0 for indirect */ extern int scsi_pt_win32_spt_state(void); #endif #ifdef __cplusplus } #endif #endif ddpt-0.92/include/sg_cmds.h0000644000175000017500000000151710756351213014615 0ustar douggdougg#ifndef SG_CMDS_H #define SG_CMDS_H /******************************************************************** * This header did contain wrapper declarations for many SCSI commands * up until sg3_utils version 1.22 . In that version, the command * wrappers were broken into two groups, the 'basic' ones found in the * "sg_cmds_basic.h" header and the 'extra' ones found in the * "sg_cmds_extra.h" header. This header now simply includes those two * headers. * In sg3_utils version 1.26 the sg_cmds_mmc.h header was added and * contains some MMC specific commands. * The corresponding function definitions are found in the sg_cmds_basic.c, * sg_cmds_extra.c and sg_cmds_mmc.c files. ********************************************************************/ #include "sg_cmds_basic.h" #include "sg_cmds_extra.h" #include "sg_cmds_mmc.h" #endif ddpt-0.92/lib/0000755000175000017500000000000011527261465012152 5ustar douggdouggddpt-0.92/lib/sg_io_linux.c0000644000175000017500000001655411346470114014640 0ustar douggdougg/* * Copyright (c) 1999-2010 Douglas Gilbert. * All rights reserved. * Use of this source code is governed by a BSD-style * license that can be found in the BSD_LICENSE file. */ #include #include #include #include // need to include the file in the build when sg_scan is built for Win32. // Hence the following guard ... // #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef SG_LIB_LINUX #include "sg_io_linux.h" /* Version 1.03 20100312 */ void sg_print_masked_status(int masked_status) { int scsi_status = (masked_status << 1) & 0x7e; sg_print_scsi_status(scsi_status); } static const char * linux_host_bytes[] = { "DID_OK", "DID_NO_CONNECT", "DID_BUS_BUSY", "DID_TIME_OUT", "DID_BAD_TARGET", "DID_ABORT", "DID_PARITY", "DID_ERROR", "DID_RESET", "DID_BAD_INTR", "DID_PASSTHROUGH", "DID_SOFT_ERROR", "DID_IMM_RETRY", "DID_REQUEUE" }; #define LINUX_HOST_BYTES_SZ \ (int)(sizeof(linux_host_bytes) / sizeof(linux_host_bytes[0])) void sg_print_host_status(int host_status) { if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; fprintf(sg_warnings_strm, "Host_status=0x%02x ", host_status); if ((host_status < 0) || (host_status >= LINUX_HOST_BYTES_SZ)) fprintf(sg_warnings_strm, "is invalid "); else fprintf(sg_warnings_strm, "[%s] ", linux_host_bytes[host_status]); } static const char * linux_driver_bytes[] = { "DRIVER_OK", "DRIVER_BUSY", "DRIVER_SOFT", "DRIVER_MEDIA", "DRIVER_ERROR", "DRIVER_INVALID", "DRIVER_TIMEOUT", "DRIVER_HARD", "DRIVER_SENSE" }; #define LINUX_DRIVER_BYTES_SZ \ (int)(sizeof(linux_driver_bytes) / sizeof(linux_driver_bytes[0])) static const char * linux_driver_suggests[] = { "SUGGEST_OK", "SUGGEST_RETRY", "SUGGEST_ABORT", "SUGGEST_REMAP", "SUGGEST_DIE", "UNKNOWN","UNKNOWN","UNKNOWN", "SUGGEST_SENSE" }; #define LINUX_DRIVER_SUGGESTS_SZ \ (int)(sizeof(linux_driver_suggests) / sizeof(linux_driver_suggests[0])) void sg_print_driver_status(int driver_status) { int driv, sugg; const char * driv_cp = "invalid"; const char * sugg_cp = "invalid"; driv = driver_status & SG_LIB_DRIVER_MASK; if (driv < LINUX_DRIVER_BYTES_SZ) driv_cp = linux_driver_bytes[driv]; sugg = (driver_status & SG_LIB_SUGGEST_MASK) >> 4; if (sugg < LINUX_DRIVER_SUGGESTS_SZ) sugg_cp = linux_driver_suggests[sugg]; if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; fprintf(sg_warnings_strm, "Driver_status=0x%02x", driver_status); fprintf(sg_warnings_strm, " [%s, %s] ", driv_cp, sugg_cp); } /* Returns 1 if no errors found and thus nothing printed; otherwise prints error/warning (prefix by 'leadin') and returns 0. */ static int sg_linux_sense_print(const char * leadin, int scsi_status, int host_status, int driver_status, const unsigned char * sense_buffer, int sb_len, int raw_sinfo) { int done_leadin = 0; int done_sense = 0; if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; scsi_status &= 0x7e; /*sanity */ if ((0 == scsi_status) && (0 == host_status) && (0 == driver_status)) return 1; /* No problems */ if (0 != scsi_status) { if (leadin) fprintf(sg_warnings_strm, "%s: ", leadin); done_leadin = 1; fprintf(sg_warnings_strm, "SCSI status: "); sg_print_scsi_status(scsi_status); fprintf(sg_warnings_strm, "\n"); if (sense_buffer && ((scsi_status == SAM_STAT_CHECK_CONDITION) || (scsi_status == SAM_STAT_COMMAND_TERMINATED))) { /* SAM_STAT_COMMAND_TERMINATED is obsolete */ sg_print_sense(0, sense_buffer, sb_len, raw_sinfo); done_sense = 1; } } if (0 != host_status) { if (leadin && (! done_leadin)) fprintf(sg_warnings_strm, "%s: ", leadin); if (done_leadin) fprintf(sg_warnings_strm, "plus...: "); else done_leadin = 1; sg_print_host_status(host_status); fprintf(sg_warnings_strm, "\n"); } if (0 != driver_status) { if (done_sense && (SG_LIB_DRIVER_SENSE == (SG_LIB_DRIVER_MASK & driver_status))) return 0; if (leadin && (! done_leadin)) fprintf(sg_warnings_strm, "%s: ", leadin); if (done_leadin) fprintf(sg_warnings_strm, "plus...: "); else done_leadin = 1; sg_print_driver_status(driver_status); fprintf(sg_warnings_strm, "\n"); if (sense_buffer && (! done_sense) && (SG_LIB_DRIVER_SENSE == (SG_LIB_DRIVER_MASK & driver_status))) sg_print_sense(0, sense_buffer, sb_len, raw_sinfo); } return 0; } #ifdef SG_IO int sg_normalize_sense(const struct sg_io_hdr * hp, struct sg_scsi_sense_hdr * sshp) { if ((NULL == hp) || (0 == hp->sb_len_wr)) { if (sshp) memset(sshp, 0, sizeof(struct sg_scsi_sense_hdr)); return 0; } return sg_scsi_normalize_sense(hp->sbp, hp->sb_len_wr, sshp); } /* Returns 1 if no errors found and thus nothing printed; otherwise returns 0. */ int sg_chk_n_print3(const char * leadin, struct sg_io_hdr * hp, int raw_sinfo) { return sg_linux_sense_print(leadin, hp->status, hp->host_status, hp->driver_status, hp->sbp, hp->sb_len_wr, raw_sinfo); } #endif /* Returns 1 if no errors found and thus nothing printed; otherwise returns 0. */ int sg_chk_n_print(const char * leadin, int masked_status, int host_status, int driver_status, const unsigned char * sense_buffer, int sb_len, int raw_sinfo) { int scsi_status = (masked_status << 1) & 0x7e; return sg_linux_sense_print(leadin, scsi_status, host_status, driver_status, sense_buffer, sb_len, raw_sinfo); } #ifdef SG_IO int sg_err_category3(struct sg_io_hdr * hp) { return sg_err_category_new(hp->status, hp->host_status, hp->driver_status, hp->sbp, hp->sb_len_wr); } #endif int sg_err_category(int masked_status, int host_status, int driver_status, const unsigned char * sense_buffer, int sb_len) { int scsi_status = (masked_status << 1) & 0x7e; return sg_err_category_new(scsi_status, host_status, driver_status, sense_buffer, sb_len); } int sg_err_category_new(int scsi_status, int host_status, int driver_status, const unsigned char * sense_buffer, int sb_len) { int masked_driver_status = (SG_LIB_DRIVER_MASK & driver_status); scsi_status &= 0x7e; if ((0 == scsi_status) && (0 == host_status) && (0 == masked_driver_status)) return SG_LIB_CAT_CLEAN; if ((SAM_STAT_CHECK_CONDITION == scsi_status) || (SAM_STAT_COMMAND_TERMINATED == scsi_status) || (SG_LIB_DRIVER_SENSE == masked_driver_status)) return sg_err_category_sense(sense_buffer, sb_len); if (0 != host_status) { if ((SG_LIB_DID_NO_CONNECT == host_status) || (SG_LIB_DID_BUS_BUSY == host_status) || (SG_LIB_DID_TIME_OUT == host_status)) return SG_LIB_CAT_TIMEOUT; } if (SG_LIB_DRIVER_TIMEOUT == masked_driver_status) return SG_LIB_CAT_TIMEOUT; return SG_LIB_CAT_OTHER; } #endif ddpt-0.92/lib/sg_cmds_extra.c0000644000175000017500000022716311524334352015144 0ustar douggdougg/* * Copyright (c) 1999-2011 Douglas Gilbert. * All rights reserved. * Use of this source code is governed by a BSD-style * license that can be found in the BSD_LICENSE file. */ #include #include #include #include #define __STDC_FORMAT_MACROS 1 #include #include "sg_lib.h" #include "sg_cmds_basic.h" #include "sg_cmds_extra.h" #include "sg_pt.h" #ifdef HAVE_CONFIG_H #include "config.h" #endif #define SENSE_BUFF_LEN 32 /* Arbitrary, could be larger */ #define DEF_PT_TIMEOUT 60 /* 60 seconds */ #define LONG_PT_TIMEOUT 7200 /* 7,200 seconds == 120 minutes */ #define SERVICE_ACTION_IN_16_CMD 0x9e #define SERVICE_ACTION_IN_16_CMDLEN 16 #define SERVICE_ACTION_OUT_16_CMD 0x9f #define SERVICE_ACTION_OUT_16_CMDLEN 16 #define MAINTENANCE_IN_CMD 0xa3 #define MAINTENANCE_IN_CMDLEN 12 #define MAINTENANCE_OUT_CMD 0xa4 #define MAINTENANCE_OUT_CMDLEN 12 #define ATA_PT_12_CMD 0xa1 #define ATA_PT_12_CMDLEN 12 #define ATA_PT_16_CMD 0x85 #define ATA_PT_16_CMDLEN 16 #define FORMAT_UNIT_CMD 0x4 #define FORMAT_UNIT_CMDLEN 6 #define PERSISTENT_RESERVE_IN_CMD 0x5e #define PERSISTENT_RESERVE_IN_CMDLEN 10 #define PERSISTENT_RESERVE_OUT_CMD 0x5f #define PERSISTENT_RESERVE_OUT_CMDLEN 10 #define READ_BLOCK_LIMITS_CMD 0x5 #define READ_BLOCK_LIMITS_CMDLEN 6 #define READ_BUFFER_CMD 0x3c #define READ_BUFFER_CMDLEN 10 #define READ_DEFECT10_CMD 0x37 #define READ_DEFECT10_CMDLEN 10 #define REASSIGN_BLKS_CMD 0x7 #define REASSIGN_BLKS_CMDLEN 6 #define RECEIVE_DIAGNOSTICS_CMD 0x1c #define RECEIVE_DIAGNOSTICS_CMDLEN 6 #define SEND_DIAGNOSTIC_CMD 0x1d #define SEND_DIAGNOSTIC_CMDLEN 6 #define SERVICE_ACTION_IN_12_CMD 0xab #define SERVICE_ACTION_IN_12_CMDLEN 12 #define READ_LONG10_CMD 0x3e #define READ_LONG10_CMDLEN 10 #define UNMAP_CMD 0x42 #define UNMAP_CMDLEN 10 #define VERIFY10_CMD 0x2f #define VERIFY10_CMDLEN 10 #define VERIFY16_CMD 0x8f #define VERIFY16_CMDLEN 16 #define WRITE_LONG10_CMD 0x3f #define WRITE_LONG10_CMDLEN 10 #define WRITE_BUFFER_CMD 0x3b #define WRITE_BUFFER_CMDLEN 10 #define GET_LBA_STATUS_SA 0x12 #define READ_LONG_16_SA 0x11 #define READ_MEDIA_SERIAL_NUM_SA 0x1 #define REPORT_IDENTIFYING_INFORMATION_SA 0x5 #define REPORT_TGT_PRT_GRP_SA 0xa #define SET_IDENTIFYING_INFORMATION_SA 0x6 #define SET_TGT_PRT_GRP_SA 0xa #define WRITE_LONG_16_SA 0x11 #define REPORT_REFERRALS_SA 0x13 /* Invokes a SCSI GET LBA STATUS command (SBC). Returns 0 -> success, * SG_LIB_CAT_INVALID_OP -> GET LBA STATUS not supported, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_ABORTED_COMMAND, * SG_LIB_CAT_NOT_READY -> device not ready, -1 -> other failure */ int sg_ll_get_lba_status(int sg_fd, uint64_t start_llba, void * resp, int alloc_len, int noisy, int verbose) { int k, res, sense_cat, ret; unsigned char getLbaStatCmd[SERVICE_ACTION_IN_16_CMDLEN]; unsigned char sense_b[SENSE_BUFF_LEN]; struct sg_pt_base * ptvp; memset(getLbaStatCmd, 0, sizeof(getLbaStatCmd)); getLbaStatCmd[0] = SERVICE_ACTION_IN_16_CMD; getLbaStatCmd[1] = GET_LBA_STATUS_SA; getLbaStatCmd[2] = (start_llba >> 56) & 0xff; getLbaStatCmd[3] = (start_llba >> 48) & 0xff; getLbaStatCmd[4] = (start_llba >> 40) & 0xff; getLbaStatCmd[5] = (start_llba >> 32) & 0xff; getLbaStatCmd[6] = (start_llba >> 24) & 0xff; getLbaStatCmd[7] = (start_llba >> 16) & 0xff; getLbaStatCmd[8] = (start_llba >> 8) & 0xff; getLbaStatCmd[9] = start_llba & 0xff; getLbaStatCmd[10] = (alloc_len >> 24) & 0xff; getLbaStatCmd[11] = (alloc_len >> 16) & 0xff; getLbaStatCmd[12] = (alloc_len >> 8) & 0xff; getLbaStatCmd[13] = alloc_len & 0xff; if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; if (verbose) { fprintf(sg_warnings_strm, " Get LBA status cmd: "); for (k = 0; k < SERVICE_ACTION_IN_16_CMDLEN; ++k) fprintf(sg_warnings_strm, "%02x ", getLbaStatCmd[k]); fprintf(sg_warnings_strm, "\n"); } ptvp = construct_scsi_pt_obj(); if (NULL == ptvp) { fprintf(sg_warnings_strm, "get LBA status: out of memory\n"); return -1; } set_scsi_pt_cdb(ptvp, getLbaStatCmd, sizeof(getLbaStatCmd)); set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); set_scsi_pt_data_in(ptvp, (unsigned char *)resp, alloc_len); res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, "get LBA status", res, alloc_len, sense_b, noisy, verbose, &sense_cat); if (-1 == ret) ; else if (-2 == ret) { switch (sense_cat) { case SG_LIB_CAT_NOT_READY: case SG_LIB_CAT_ILLEGAL_REQ: case SG_LIB_CAT_INVALID_OP: case SG_LIB_CAT_UNIT_ATTENTION: case SG_LIB_CAT_ABORTED_COMMAND: ret = sense_cat; break; case SG_LIB_CAT_RECOVERED: case SG_LIB_CAT_NO_SENSE: ret = 0; break; default: ret = -1; break; } } else ret = 0; destruct_scsi_pt_obj(ptvp); return ret; } /* Invokes a SCSI REPORT TARGET PORT GROUPS command. Return of 0 -> success, * SG_LIB_CAT_INVALID_OP -> Report Target Port Groups not supported, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_ABORTED_COMMAND, * SG_LIB_CAT_UNIT_ATTENTION, -1 -> other failure */ int sg_ll_report_tgt_prt_grp(int sg_fd, void * resp, int mx_resp_len, int noisy, int verbose) { int k, res, ret, sense_cat; unsigned char rtpgCmdBlk[MAINTENANCE_IN_CMDLEN] = {MAINTENANCE_IN_CMD, REPORT_TGT_PRT_GRP_SA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; unsigned char sense_b[SENSE_BUFF_LEN]; struct sg_pt_base * ptvp; rtpgCmdBlk[6] = (mx_resp_len >> 24) & 0xff; rtpgCmdBlk[7] = (mx_resp_len >> 16) & 0xff; rtpgCmdBlk[8] = (mx_resp_len >> 8) & 0xff; rtpgCmdBlk[9] = mx_resp_len & 0xff; if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; if (verbose) { fprintf(sg_warnings_strm, " report target port groups cdb: "); for (k = 0; k < MAINTENANCE_IN_CMDLEN; ++k) fprintf(sg_warnings_strm, "%02x ", rtpgCmdBlk[k]); fprintf(sg_warnings_strm, "\n"); } ptvp = construct_scsi_pt_obj(); if (NULL == ptvp) { fprintf(sg_warnings_strm, "report target port groups: out of " "memory\n"); return -1; } set_scsi_pt_cdb(ptvp, rtpgCmdBlk, sizeof(rtpgCmdBlk)); set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); set_scsi_pt_data_in(ptvp, (unsigned char *)resp, mx_resp_len); res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, "report target port group", res, mx_resp_len, sense_b, noisy, verbose, &sense_cat); if (-1 == ret) ; else if (-2 == ret) { switch (sense_cat) { case SG_LIB_CAT_INVALID_OP: case SG_LIB_CAT_ILLEGAL_REQ: case SG_LIB_CAT_UNIT_ATTENTION: case SG_LIB_CAT_ABORTED_COMMAND: ret = sense_cat; break; case SG_LIB_CAT_RECOVERED: case SG_LIB_CAT_NO_SENSE: ret = 0; break; default: ret = -1; break; } } else ret = 0; destruct_scsi_pt_obj(ptvp); return ret; } /* Invokes a SCSI SET TARGET PORT GROUPS command. Return of 0 -> success, * SG_LIB_CAT_INVALID_OP -> Set Target Port Groups not supported, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_ABORTED_COMMAND, * SG_LIB_CAT_UNIT_ATTENTION, -1 -> other failure */ int sg_ll_set_tgt_prt_grp(int sg_fd, void * paramp, int param_len, int noisy, int verbose) { int k, res, ret, sense_cat; unsigned char stpgCmdBlk[MAINTENANCE_OUT_CMDLEN] = {MAINTENANCE_OUT_CMD, SET_TGT_PRT_GRP_SA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; unsigned char sense_b[SENSE_BUFF_LEN]; struct sg_pt_base * ptvp; stpgCmdBlk[6] = (param_len >> 24) & 0xff; stpgCmdBlk[7] = (param_len >> 16) & 0xff; stpgCmdBlk[8] = (param_len >> 8) & 0xff; stpgCmdBlk[9] = param_len & 0xff; if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; if (verbose) { fprintf(sg_warnings_strm, " set target port groups cdb: "); for (k = 0; k < MAINTENANCE_OUT_CMDLEN; ++k) fprintf(sg_warnings_strm, "%02x ", stpgCmdBlk[k]); fprintf(sg_warnings_strm, "\n"); if ((verbose > 1) && paramp && param_len) { fprintf(sg_warnings_strm, " set target port groups " "parameter list:\n"); dStrHex((const char *)paramp, param_len, -1); } } ptvp = construct_scsi_pt_obj(); if (NULL == ptvp) { fprintf(sg_warnings_strm, "set target port groups: out of " "memory\n"); return -1; } set_scsi_pt_cdb(ptvp, stpgCmdBlk, sizeof(stpgCmdBlk)); set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); set_scsi_pt_data_out(ptvp, (unsigned char *)paramp, param_len); res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, "set target port group", res, 0, sense_b, noisy, verbose, &sense_cat); if (-1 == ret) ; else if (-2 == ret) { switch (sense_cat) { case SG_LIB_CAT_INVALID_OP: case SG_LIB_CAT_ILLEGAL_REQ: case SG_LIB_CAT_UNIT_ATTENTION: case SG_LIB_CAT_ABORTED_COMMAND: ret = sense_cat; break; case SG_LIB_CAT_RECOVERED: case SG_LIB_CAT_NO_SENSE: ret = 0; break; default: ret = -1; break; } } else ret = 0; destruct_scsi_pt_obj(ptvp); return ret; } /* Invokes a SCSI REPORT REFERRALS command. Return of 0 -> success, * SG_LIB_CAT_INVALID_OP -> Report Referrals not supported, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_ABORTED_COMMAND, * SG_LIB_CAT_UNIT_ATTENTION, -1 -> other failure */ int sg_ll_report_referrals(int sg_fd, uint64_t start_llba, int one_seg, void * resp, int mx_resp_len, int noisy, int verbose) { int k, res, ret, sense_cat; unsigned char repRefCmdBlk[SERVICE_ACTION_IN_16_CMDLEN] = {SERVICE_ACTION_IN_16_CMD, REPORT_REFERRALS_SA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; unsigned char sense_b[SENSE_BUFF_LEN]; struct sg_pt_base * ptvp; repRefCmdBlk[2] = (start_llba >> 56) & 0xff; repRefCmdBlk[3] = (start_llba >> 48) & 0xff; repRefCmdBlk[4] = (start_llba >> 40) & 0xff; repRefCmdBlk[5] = (start_llba >> 32) & 0xff; repRefCmdBlk[6] = (start_llba >> 24) & 0xff; repRefCmdBlk[7] = (start_llba >> 16) & 0xff; repRefCmdBlk[8] = (start_llba >> 8) & 0xff; repRefCmdBlk[9] = start_llba & 0xff; repRefCmdBlk[10] = (mx_resp_len >> 24) & 0xff; repRefCmdBlk[11] = (mx_resp_len >> 16) & 0xff; repRefCmdBlk[12] = (mx_resp_len >> 8) & 0xff; repRefCmdBlk[13] = mx_resp_len & 0xff; repRefCmdBlk[14] = one_seg & 0x1; if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; if (verbose) { fprintf(sg_warnings_strm, " report referrals cdb: "); for (k = 0; k < SERVICE_ACTION_IN_16_CMDLEN; ++k) fprintf(sg_warnings_strm, "%02x ", repRefCmdBlk[k]); fprintf(sg_warnings_strm, "\n"); } ptvp = construct_scsi_pt_obj(); if (NULL == ptvp) { fprintf(sg_warnings_strm, "report target port groups: out of " "memory\n"); return -1; } set_scsi_pt_cdb(ptvp, repRefCmdBlk, sizeof(repRefCmdBlk)); set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); set_scsi_pt_data_in(ptvp, (unsigned char *)resp, mx_resp_len); res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, "report referrals", res, mx_resp_len, sense_b, noisy, verbose, &sense_cat); if (-1 == ret) ; else if (-2 == ret) { switch (sense_cat) { case SG_LIB_CAT_INVALID_OP: case SG_LIB_CAT_ILLEGAL_REQ: case SG_LIB_CAT_UNIT_ATTENTION: case SG_LIB_CAT_ABORTED_COMMAND: ret = sense_cat; break; case SG_LIB_CAT_RECOVERED: case SG_LIB_CAT_NO_SENSE: ret = 0; break; default: ret = -1; break; } } else ret = 0; destruct_scsi_pt_obj(ptvp); return ret; } /* Invokes a SCSI SEND DIAGNOSTIC command. Foreground, extended self tests can * take a long time, if so set long_duration flag. Return of 0 -> success, * SG_LIB_CAT_INVALID_OP -> Send diagnostic not supported, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_UNIT_ATTENTION, * SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND, * -1 -> other failure */ int sg_ll_send_diag(int sg_fd, int sf_code, int pf_bit, int sf_bit, int devofl_bit, int unitofl_bit, int long_duration, void * paramp, int param_len, int noisy, int verbose) { int k, res, ret, sense_cat; unsigned char senddiagCmdBlk[SEND_DIAGNOSTIC_CMDLEN] = {SEND_DIAGNOSTIC_CMD, 0, 0, 0, 0, 0}; unsigned char sense_b[SENSE_BUFF_LEN]; struct sg_pt_base * ptvp; senddiagCmdBlk[1] = (unsigned char)((sf_code << 5) | (pf_bit << 4) | (sf_bit << 2) | (devofl_bit << 1) | unitofl_bit); senddiagCmdBlk[3] = (unsigned char)((param_len >> 8) & 0xff); senddiagCmdBlk[4] = (unsigned char)(param_len & 0xff); if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; if (verbose) { fprintf(sg_warnings_strm, " Send diagnostic cmd: "); for (k = 0; k < SEND_DIAGNOSTIC_CMDLEN; ++k) fprintf(sg_warnings_strm, "%02x ", senddiagCmdBlk[k]); fprintf(sg_warnings_strm, "\n"); if ((verbose > 1) && paramp && param_len) { fprintf(sg_warnings_strm, " Send diagnostic parameter " "list:\n"); dStrHex((const char *)paramp, param_len, -1); } } ptvp = construct_scsi_pt_obj(); if (NULL == ptvp) { fprintf(sg_warnings_strm, "send diagnostic: out of memory\n"); return -1; } set_scsi_pt_cdb(ptvp, senddiagCmdBlk, sizeof(senddiagCmdBlk)); set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); set_scsi_pt_data_out(ptvp, (unsigned char *)paramp, param_len); res = do_scsi_pt(ptvp, sg_fd, (long_duration ? LONG_PT_TIMEOUT : DEF_PT_TIMEOUT), verbose); ret = sg_cmds_process_resp(ptvp, "send diagnostic", res, 0, sense_b, noisy, verbose, &sense_cat); if (-1 == ret) ; else if (-2 == ret) { switch (sense_cat) { case SG_LIB_CAT_NOT_READY: case SG_LIB_CAT_INVALID_OP: case SG_LIB_CAT_ILLEGAL_REQ: case SG_LIB_CAT_UNIT_ATTENTION: case SG_LIB_CAT_ABORTED_COMMAND: ret = sense_cat; break; case SG_LIB_CAT_RECOVERED: case SG_LIB_CAT_NO_SENSE: ret = 0; break; default: ret = -1; break; } } else ret = 0; destruct_scsi_pt_obj(ptvp); return ret; } /* Invokes a SCSI RECEIVE DIAGNOSTIC RESULTS command. Return of 0 -> success, * SG_LIB_CAT_INVALID_OP -> Receive diagnostic results not supported, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_UNIT_ATTENTION, * SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND, * -1 -> other failure */ int sg_ll_receive_diag(int sg_fd, int pcv, int pg_code, void * resp, int mx_resp_len, int noisy, int verbose) { int k, res, ret, sense_cat; unsigned char rcvdiagCmdBlk[RECEIVE_DIAGNOSTICS_CMDLEN] = {RECEIVE_DIAGNOSTICS_CMD, 0, 0, 0, 0, 0}; unsigned char sense_b[SENSE_BUFF_LEN]; struct sg_pt_base * ptvp; rcvdiagCmdBlk[1] = (unsigned char)(pcv ? 0x1 : 0); rcvdiagCmdBlk[2] = (unsigned char)(pg_code); rcvdiagCmdBlk[3] = (unsigned char)((mx_resp_len >> 8) & 0xff); rcvdiagCmdBlk[4] = (unsigned char)(mx_resp_len & 0xff); if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; if (verbose) { fprintf(sg_warnings_strm, " Receive diagnostic results cmd: "); for (k = 0; k < RECEIVE_DIAGNOSTICS_CMDLEN; ++k) fprintf(sg_warnings_strm, "%02x ", rcvdiagCmdBlk[k]); fprintf(sg_warnings_strm, "\n"); } ptvp = construct_scsi_pt_obj(); if (NULL == ptvp) { fprintf(sg_warnings_strm, "receive diagnostic results: out of " "memory\n"); return -1; } set_scsi_pt_cdb(ptvp, rcvdiagCmdBlk, sizeof(rcvdiagCmdBlk)); set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); set_scsi_pt_data_in(ptvp, (unsigned char *)resp, mx_resp_len); res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, "receive diagnostic results", res, mx_resp_len, sense_b, noisy, verbose, &sense_cat); if (-1 == ret) ; else if (-2 == ret) { switch (sense_cat) { case SG_LIB_CAT_NOT_READY: case SG_LIB_CAT_INVALID_OP: case SG_LIB_CAT_ILLEGAL_REQ: case SG_LIB_CAT_UNIT_ATTENTION: case SG_LIB_CAT_ABORTED_COMMAND: ret = sense_cat; break; case SG_LIB_CAT_RECOVERED: case SG_LIB_CAT_NO_SENSE: ret = 0; break; default: ret = -1; break; } } else ret = 0; destruct_scsi_pt_obj(ptvp); return ret; } /* Invokes a SCSI READ DEFECT DATA (10) command (SBC). Return of 0 -> * success, SG_LIB_CAT_INVALID_OP -> invalid opcode, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_UNIT_ATTENTION, * SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND, * -1 -> other failure */ int sg_ll_read_defect10(int sg_fd, int req_plist, int req_glist, int dl_format, void * resp, int mx_resp_len, int noisy, int verbose) { int res, k, ret, sense_cat; unsigned char rdefCmdBlk[READ_DEFECT10_CMDLEN] = {READ_DEFECT10_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0}; unsigned char sense_b[SENSE_BUFF_LEN]; struct sg_pt_base * ptvp; rdefCmdBlk[2] = (unsigned char)(((req_plist << 4) & 0x10) | ((req_glist << 3) & 0x8) | (dl_format & 0x7)); rdefCmdBlk[7] = (unsigned char)((mx_resp_len >> 8) & 0xff); rdefCmdBlk[8] = (unsigned char)(mx_resp_len & 0xff); if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; if (mx_resp_len > 0xffff) { fprintf(sg_warnings_strm, "mx_resp_len too big\n"); return -1; } if (verbose) { fprintf(sg_warnings_strm, " read defect (10) cdb: "); for (k = 0; k < READ_DEFECT10_CMDLEN; ++k) fprintf(sg_warnings_strm, "%02x ", rdefCmdBlk[k]); fprintf(sg_warnings_strm, "\n"); } ptvp = construct_scsi_pt_obj(); if (NULL == ptvp) { fprintf(sg_warnings_strm, "read defect (10): out of memory\n"); return -1; } set_scsi_pt_cdb(ptvp, rdefCmdBlk, sizeof(rdefCmdBlk)); set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); set_scsi_pt_data_in(ptvp, (unsigned char *)resp, mx_resp_len); res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, "read defect (10)", res, mx_resp_len, sense_b, noisy, verbose, &sense_cat); if (-1 == ret) ; else if (-2 == ret) { switch (sense_cat) { case SG_LIB_CAT_NOT_READY: case SG_LIB_CAT_INVALID_OP: case SG_LIB_CAT_ILLEGAL_REQ: case SG_LIB_CAT_UNIT_ATTENTION: case SG_LIB_CAT_ABORTED_COMMAND: ret = sense_cat; break; case SG_LIB_CAT_RECOVERED: case SG_LIB_CAT_NO_SENSE: ret = 0; break; default: ret = -1; break; } } else { if ((verbose > 2) && (ret > 0)) { fprintf(sg_warnings_strm, " read defect (10): response%s\n", (ret > 256 ? ", first 256 bytes" : "")); dStrHex((const char *)resp, (ret > 256 ? 256 : ret), -1); } ret = 0; } destruct_scsi_pt_obj(ptvp); return ret; } /* Invokes a SCSI READ MEDIA SERIAL NUMBER command. Return of 0 -> success, * SG_LIB_CAT_INVALID_OP -> Read media serial number not supported, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_UNIT_ATTENTION, * SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND, * -1 -> other failure */ int sg_ll_read_media_serial_num(int sg_fd, void * resp, int mx_resp_len, int noisy, int verbose) { int k, res, ret, sense_cat; unsigned char rmsnCmdBlk[SERVICE_ACTION_IN_12_CMDLEN] = {SERVICE_ACTION_IN_12_CMD, READ_MEDIA_SERIAL_NUM_SA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; unsigned char sense_b[SENSE_BUFF_LEN]; struct sg_pt_base * ptvp; rmsnCmdBlk[6] = (mx_resp_len >> 24) & 0xff; rmsnCmdBlk[7] = (mx_resp_len >> 16) & 0xff; rmsnCmdBlk[8] = (mx_resp_len >> 8) & 0xff; rmsnCmdBlk[9] = mx_resp_len & 0xff; if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; if (verbose) { fprintf(sg_warnings_strm, " read media serial number cdb: "); for (k = 0; k < SERVICE_ACTION_IN_12_CMDLEN; ++k) fprintf(sg_warnings_strm, "%02x ", rmsnCmdBlk[k]); fprintf(sg_warnings_strm, "\n"); } ptvp = construct_scsi_pt_obj(); if (NULL == ptvp) { fprintf(sg_warnings_strm, "read media serial number: out of " "memory\n"); return -1; } set_scsi_pt_cdb(ptvp, rmsnCmdBlk, sizeof(rmsnCmdBlk)); set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); set_scsi_pt_data_in(ptvp, (unsigned char *)resp, mx_resp_len); res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, "read media serial number", res, mx_resp_len, sense_b, noisy, verbose, &sense_cat); if (-1 == ret) ; else if (-2 == ret) { switch (sense_cat) { case SG_LIB_CAT_NOT_READY: case SG_LIB_CAT_INVALID_OP: case SG_LIB_CAT_ILLEGAL_REQ: case SG_LIB_CAT_UNIT_ATTENTION: case SG_LIB_CAT_ABORTED_COMMAND: ret = sense_cat; break; case SG_LIB_CAT_RECOVERED: case SG_LIB_CAT_NO_SENSE: ret = 0; break; default: ret = -1; break; } } else { if ((verbose > 2) && (ret > 0)) { fprintf(sg_warnings_strm, " read media serial number: respon" "se%s\n", (ret > 256 ? ", first 256 bytes" : "")); dStrHex((const char *)resp, (ret > 256 ? 256 : ret), -1); } ret = 0; } destruct_scsi_pt_obj(ptvp); return ret; } /* Invokes a SCSI REPORT IDENTIFYING INFORMATION command. This command was * called REPORT DEVICE IDENTIFIER prior to spc4r07. Return of 0 -> success, * SG_LIB_CAT_INVALID_OP -> Report identifying information not supported, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_UNIT_ATTENTION, * SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND, * -1 -> other failure */ int sg_ll_report_id_info(int sg_fd, int itype, void * resp, int max_resp_len, int noisy, int verbose) { int k, res, ret, sense_cat; unsigned char riiCmdBlk[MAINTENANCE_IN_CMDLEN] = {MAINTENANCE_IN_CMD, REPORT_IDENTIFYING_INFORMATION_SA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; unsigned char sense_b[SENSE_BUFF_LEN]; struct sg_pt_base * ptvp; riiCmdBlk[6] = (max_resp_len >> 24) & 0xff; riiCmdBlk[7] = (max_resp_len >> 16) & 0xff; riiCmdBlk[8] = (max_resp_len >> 8) & 0xff; riiCmdBlk[9] = max_resp_len & 0xff; riiCmdBlk[10] |= (itype << 1) & 0xfe; if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; if (verbose) { fprintf(sg_warnings_strm, " Report identifying information cdb: "); for (k = 0; k < MAINTENANCE_IN_CMDLEN; ++k) fprintf(sg_warnings_strm, "%02x ", riiCmdBlk[k]); fprintf(sg_warnings_strm, "\n"); } ptvp = construct_scsi_pt_obj(); if (NULL == ptvp) { fprintf(sg_warnings_strm, "report identifying information: out of " "memory\n"); return -1; } set_scsi_pt_cdb(ptvp, riiCmdBlk, sizeof(riiCmdBlk)); set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); set_scsi_pt_data_in(ptvp, (unsigned char *)resp, max_resp_len); res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, "report identifying information", res, max_resp_len, sense_b, noisy, verbose, &sense_cat); if (-1 == ret) ; else if (-2 == ret) { switch (sense_cat) { case SG_LIB_CAT_NOT_READY: case SG_LIB_CAT_INVALID_OP: case SG_LIB_CAT_ILLEGAL_REQ: case SG_LIB_CAT_UNIT_ATTENTION: case SG_LIB_CAT_ABORTED_COMMAND: ret = sense_cat; break; case SG_LIB_CAT_RECOVERED: case SG_LIB_CAT_NO_SENSE: ret = 0; break; default: ret = -1; break; } } else { if ((verbose > 2) && (ret > 0)) { fprintf(sg_warnings_strm, " report identifying information: " "response%s\n", (ret > 256 ? ", first 256 bytes" : "")); dStrHex((const char *)resp, (ret > 256 ? 256 : ret), -1); } ret = 0; } destruct_scsi_pt_obj(ptvp); return ret; } /* Invokes a SCSI SET IDENTIFYING INFORMATION command. This command was * called SET DEVICE IDENTIFIER prior to spc4r07. Return of 0 -> success, * SG_LIB_CAT_INVALID_OP -> Set identifying information not supported, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_UNIT_ATTENTION, * SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND, * -1 -> other failure */ int sg_ll_set_id_info(int sg_fd, int itype, void * paramp, int param_len, int noisy, int verbose) { int k, res, ret, sense_cat; unsigned char siiCmdBlk[MAINTENANCE_OUT_CMDLEN] = {MAINTENANCE_OUT_CMD, SET_IDENTIFYING_INFORMATION_SA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; unsigned char sense_b[SENSE_BUFF_LEN]; struct sg_pt_base * ptvp; siiCmdBlk[6] = (param_len >> 24) & 0xff; siiCmdBlk[7] = (param_len >> 16) & 0xff; siiCmdBlk[8] = (param_len >> 8) & 0xff; siiCmdBlk[9] = param_len & 0xff; siiCmdBlk[10] |= (itype << 1) & 0xfe; if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; if (verbose) { fprintf(sg_warnings_strm, " Set identifying information cdb: "); for (k = 0; k < MAINTENANCE_OUT_CMDLEN; ++k) fprintf(sg_warnings_strm, "%02x ", siiCmdBlk[k]); fprintf(sg_warnings_strm, "\n"); if ((verbose > 1) && paramp && param_len) { fprintf(sg_warnings_strm, " Set identifying information " "parameter list:\n"); dStrHex((const char *)paramp, param_len, -1); } } ptvp = construct_scsi_pt_obj(); if (NULL == ptvp) { fprintf(sg_warnings_strm, "Set identifying information: out of " "memory\n"); return -1; } set_scsi_pt_cdb(ptvp, siiCmdBlk, sizeof(siiCmdBlk)); set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); set_scsi_pt_data_out(ptvp, (unsigned char *)paramp, param_len); res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, "set identifying information", res, 0, sense_b, noisy, verbose, &sense_cat); if (-1 == ret) ; else if (-2 == ret) { switch (sense_cat) { case SG_LIB_CAT_NOT_READY: case SG_LIB_CAT_INVALID_OP: case SG_LIB_CAT_ILLEGAL_REQ: case SG_LIB_CAT_UNIT_ATTENTION: case SG_LIB_CAT_ABORTED_COMMAND: ret = sense_cat; break; case SG_LIB_CAT_RECOVERED: case SG_LIB_CAT_NO_SENSE: ret = 0; break; default: ret = -1; break; } } else ret = 0; destruct_scsi_pt_obj(ptvp); return ret; } /* Invokes a FORMAT UNIT (SBC-3) command. Return of 0 -> success, * SG_LIB_CAT_INVALID_OP -> Format unit not supported, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_UNIT_ATTENTION, * SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND, * -1 -> other failure */ int sg_ll_format_unit(int sg_fd, int fmtpinfo, int longlist, int fmtdata, int cmplst, int dlist_format, int timeout_secs, void * paramp, int param_len, int noisy, int verbose) { int k, res, ret, sense_cat, tmout; unsigned char fuCmdBlk[FORMAT_UNIT_CMDLEN] = {FORMAT_UNIT_CMD, 0, 0, 0, 0, 0}; unsigned char sense_b[SENSE_BUFF_LEN]; struct sg_pt_base * ptvp; if (fmtpinfo) fuCmdBlk[1] |= (fmtpinfo << 6); if (longlist) fuCmdBlk[1] |= 0x20; if (fmtdata) fuCmdBlk[1] |= 0x10; if (cmplst) fuCmdBlk[1] |= 0x8; if (dlist_format) fuCmdBlk[1] |= (dlist_format & 0x7); if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; tmout = (timeout_secs > 0) ? timeout_secs : DEF_PT_TIMEOUT; if (verbose) { fprintf(sg_warnings_strm, " format cdb: "); for (k = 0; k < 6; ++k) fprintf(sg_warnings_strm, "%02x ", fuCmdBlk[k]); fprintf(sg_warnings_strm, "\n"); } if ((verbose > 1) && (param_len > 0)) { fprintf(sg_warnings_strm, " format parameter list:\n"); dStrHex((const char *)paramp, param_len, -1); } ptvp = construct_scsi_pt_obj(); if (NULL == ptvp) { fprintf(sg_warnings_strm, "format unit: out of memory\n"); return -1; } set_scsi_pt_cdb(ptvp, fuCmdBlk, sizeof(fuCmdBlk)); set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); set_scsi_pt_data_out(ptvp, (unsigned char *)paramp, param_len); res = do_scsi_pt(ptvp, sg_fd, tmout, verbose); ret = sg_cmds_process_resp(ptvp, "format unit", res, 0, sense_b, noisy, verbose, &sense_cat); if (-1 == ret) ; else if (-2 == ret) { switch (sense_cat) { case SG_LIB_CAT_NOT_READY: case SG_LIB_CAT_INVALID_OP: case SG_LIB_CAT_ILLEGAL_REQ: case SG_LIB_CAT_UNIT_ATTENTION: case SG_LIB_CAT_ABORTED_COMMAND: ret = sense_cat; break; case SG_LIB_CAT_RECOVERED: case SG_LIB_CAT_NO_SENSE: ret = 0; break; default: ret = -1; break; } } else ret = 0; destruct_scsi_pt_obj(ptvp); return ret; } /* Invokes a SCSI REASSIGN BLOCKS command. Return of 0 -> success, * SG_LIB_CAT_INVALID_OP -> invalid opcode, SG_LIB_CAT_UNIT_ATTENTION, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_ABORTED_COMMAND, * SG_LIB_CAT_NOT_READY -> device not ready, -1 -> other failure */ int sg_ll_reassign_blocks(int sg_fd, int longlba, int longlist, void * paramp, int param_len, int noisy, int verbose) { int res, k, ret, sense_cat; unsigned char reassCmdBlk[REASSIGN_BLKS_CMDLEN] = {REASSIGN_BLKS_CMD, 0, 0, 0, 0, 0}; unsigned char sense_b[SENSE_BUFF_LEN]; struct sg_pt_base * ptvp; reassCmdBlk[1] = (unsigned char)(((longlba << 1) & 0x2) | (longlist & 0x1)); if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; if (verbose) { fprintf(sg_warnings_strm, " reassign blocks cdb: "); for (k = 0; k < REASSIGN_BLKS_CMDLEN; ++k) fprintf(sg_warnings_strm, "%02x ", reassCmdBlk[k]); fprintf(sg_warnings_strm, "\n"); } if (verbose > 1) { fprintf(sg_warnings_strm, " reassign blocks parameter list\n"); dStrHex((const char *)paramp, param_len, -1); } ptvp = construct_scsi_pt_obj(); if (NULL == ptvp) { fprintf(sg_warnings_strm, "reassign blocks: out of memory\n"); return -1; } set_scsi_pt_cdb(ptvp, reassCmdBlk, sizeof(reassCmdBlk)); set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); set_scsi_pt_data_out(ptvp, (unsigned char *)paramp, param_len); res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, "reassign blocks", res, 0, sense_b, noisy, verbose, &sense_cat); if (-1 == ret) ; else if (-2 == ret) { switch (sense_cat) { case SG_LIB_CAT_NOT_READY: case SG_LIB_CAT_INVALID_OP: case SG_LIB_CAT_ILLEGAL_REQ: case SG_LIB_CAT_UNIT_ATTENTION: case SG_LIB_CAT_ABORTED_COMMAND: ret = sense_cat; break; case SG_LIB_CAT_RECOVERED: case SG_LIB_CAT_NO_SENSE: ret = 0; break; default: ret = -1; break; } } else ret = 0; destruct_scsi_pt_obj(ptvp); return ret; } /* Invokes a SCSI PERSISTENT RESERVE IN command (SPC). Returns 0 * when successful, SG_LIB_CAT_INVALID_OP if command not supported, * SG_LIB_CAT_ILLEGAL_REQ if field in cdb not supported, * SG_LIB_CAT_UNIT_ATTENTION, SG_LIB_CAT_ABORTED_COMMAND, else -1 */ int sg_ll_persistent_reserve_in(int sg_fd, int rq_servact, void * resp, int mx_resp_len, int noisy, int verbose) { int res, k, ret, sense_cat; unsigned char prinCmdBlk[PERSISTENT_RESERVE_IN_CMDLEN] = {PERSISTENT_RESERVE_IN_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0}; unsigned char sense_b[SENSE_BUFF_LEN]; struct sg_pt_base * ptvp; if (rq_servact > 0) prinCmdBlk[1] = (unsigned char)(rq_servact & 0x1f); prinCmdBlk[7] = (unsigned char)((mx_resp_len >> 8) & 0xff); prinCmdBlk[8] = (unsigned char)(mx_resp_len & 0xff); if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; if (verbose) { fprintf(sg_warnings_strm, " Persistent Reservation In cmd: "); for (k = 0; k < PERSISTENT_RESERVE_IN_CMDLEN; ++k) fprintf(sg_warnings_strm, "%02x ", prinCmdBlk[k]); fprintf(sg_warnings_strm, "\n"); } ptvp = construct_scsi_pt_obj(); if (NULL == ptvp) { fprintf(sg_warnings_strm, "persistent reservation in: out of " "memory\n"); return -1; } set_scsi_pt_cdb(ptvp, prinCmdBlk, sizeof(prinCmdBlk)); set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); set_scsi_pt_data_in(ptvp, (unsigned char *)resp, mx_resp_len); res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, "persistent reservation in", res, mx_resp_len, sense_b, noisy, verbose, &sense_cat); if (-1 == ret) ; else if (-2 == ret) { switch (sense_cat) { case SG_LIB_CAT_INVALID_OP: case SG_LIB_CAT_ILLEGAL_REQ: case SG_LIB_CAT_UNIT_ATTENTION: case SG_LIB_CAT_ABORTED_COMMAND: ret = sense_cat; break; case SG_LIB_CAT_RECOVERED: case SG_LIB_CAT_NO_SENSE: ret = 0; break; default: ret = -1; break; } } else { if ((verbose > 2) && (ret > 0)) { fprintf(sg_warnings_strm, " persistent reserve in: " "response%s\n", (ret > 256 ? ", first 256 bytes" : "")); dStrHex((const char *)resp, (ret > 256 ? 256 : ret), -1); } ret = 0; } destruct_scsi_pt_obj(ptvp); return ret; } /* Invokes a SCSI PERSISTENT RESERVE OUT command (SPC). Returns 0 * when successful, SG_LIB_CAT_INVALID_OP if command not supported, * SG_LIB_CAT_ILLEGAL_REQ if field in cdb not supported, * SG_LIB_CAT_UNIT_ATTENTION, SG_LIB_CAT_ABORTED_COMMAND, else -1 */ int sg_ll_persistent_reserve_out(int sg_fd, int rq_servact, int rq_scope, unsigned int rq_type, void * paramp, int param_len, int noisy, int verbose) { int res, k, ret, sense_cat; unsigned char proutCmdBlk[PERSISTENT_RESERVE_OUT_CMDLEN] = {PERSISTENT_RESERVE_OUT_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0}; unsigned char sense_b[SENSE_BUFF_LEN]; struct sg_pt_base * ptvp; if (rq_servact > 0) proutCmdBlk[1] = (unsigned char)(rq_servact & 0x1f); proutCmdBlk[2] = (((rq_scope & 0xf) << 4) | (rq_type & 0xf)); proutCmdBlk[7] = (unsigned char)((param_len >> 8) & 0xff); proutCmdBlk[8] = (unsigned char)(param_len & 0xff); if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; if (verbose) { fprintf(sg_warnings_strm, " Persistent Reservation Out cmd: "); for (k = 0; k < PERSISTENT_RESERVE_OUT_CMDLEN; ++k) fprintf(sg_warnings_strm, "%02x ", proutCmdBlk[k]); fprintf(sg_warnings_strm, "\n"); if (verbose > 1) { fprintf(sg_warnings_strm, " Persistent Reservation Out parameters:\n"); dStrHex((const char *)paramp, param_len, 0); } } ptvp = construct_scsi_pt_obj(); if (NULL == ptvp) { fprintf(sg_warnings_strm, "persistent reserve out: out of memory\n"); return -1; } set_scsi_pt_cdb(ptvp, proutCmdBlk, sizeof(proutCmdBlk)); set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); set_scsi_pt_data_out(ptvp, (unsigned char *)paramp, param_len); res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, "persistent reserve out", res, 0, sense_b, noisy, verbose, &sense_cat); if (-1 == ret) ; else if (-2 == ret) { switch (sense_cat) { case SG_LIB_CAT_INVALID_OP: case SG_LIB_CAT_ILLEGAL_REQ: case SG_LIB_CAT_UNIT_ATTENTION: case SG_LIB_CAT_ABORTED_COMMAND: ret = sense_cat; break; case SG_LIB_CAT_RECOVERED: case SG_LIB_CAT_NO_SENSE: ret = 0; break; default: ret = -1; break; } } else ret = 0; destruct_scsi_pt_obj(ptvp); return ret; } static int has_blk_ili(unsigned char * sensep, int sb_len) { int resp_code; const unsigned char * cup; if (sb_len < 8) return 0; resp_code = (0x7f & sensep[0]); if (resp_code >= 0x72) { /* descriptor format */ /* find block command descriptor */ if ((cup = sg_scsi_sense_desc_find(sensep, sb_len, 0x5))) return ((cup[3] & 0x20) ? 1 : 0); } else /* fixed */ return ((sensep[2] & 0x20) ? 1 : 0); return 0; } /* Invokes a SCSI READ LONG (10) command (SBC). Note that 'xfer_len' * is in bytes. Returns 0 -> success, * SG_LIB_CAT_INVALID_OP -> READ LONG(10) not supported, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, * SG_LIB_CAT_ILLEGAL_REQ_WITH_INFO -> bad field in cdb, with info * field written to 'offsetp', SG_LIB_CAT_ABORTED_COMMAND, * SG_LIB_CAT_NOT_READY -> device not ready, -1 -> other failure */ int sg_ll_read_long10(int sg_fd, int pblock, int correct, unsigned int lba, void * resp, int xfer_len, int * offsetp, int noisy, int verbose) { int k, res, sense_cat, ret; unsigned char readLongCmdBlk[READ_LONG10_CMDLEN]; unsigned char sense_b[SENSE_BUFF_LEN]; struct sg_pt_base * ptvp; memset(readLongCmdBlk, 0, READ_LONG10_CMDLEN); readLongCmdBlk[0] = READ_LONG10_CMD; if (pblock) readLongCmdBlk[1] |= 0x4; if (correct) readLongCmdBlk[1] |= 0x2; readLongCmdBlk[2] = (lba >> 24) & 0xff; readLongCmdBlk[3] = (lba >> 16) & 0xff; readLongCmdBlk[4] = (lba >> 8) & 0xff; readLongCmdBlk[5] = lba & 0xff; readLongCmdBlk[7] = (xfer_len >> 8) & 0xff; readLongCmdBlk[8] = xfer_len & 0xff; if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; if (verbose) { fprintf(sg_warnings_strm, " Read Long (10) cmd: "); for (k = 0; k < READ_LONG10_CMDLEN; ++k) fprintf(sg_warnings_strm, "%02x ", readLongCmdBlk[k]); fprintf(sg_warnings_strm, "\n"); } ptvp = construct_scsi_pt_obj(); if (NULL == ptvp) { fprintf(sg_warnings_strm, "read long (10): out of memory\n"); return -1; } set_scsi_pt_cdb(ptvp, readLongCmdBlk, sizeof(readLongCmdBlk)); set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); set_scsi_pt_data_in(ptvp, (unsigned char *)resp, xfer_len); res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, "read long (10)", res, xfer_len, sense_b, noisy, verbose, &sense_cat); if (-1 == ret) ; else if (-2 == ret) { switch (sense_cat) { case SG_LIB_CAT_NOT_READY: case SG_LIB_CAT_INVALID_OP: case SG_LIB_CAT_UNIT_ATTENTION: case SG_LIB_CAT_ABORTED_COMMAND: ret = sense_cat; break; case SG_LIB_CAT_RECOVERED: case SG_LIB_CAT_NO_SENSE: ret = 0; break; case SG_LIB_CAT_ILLEGAL_REQ: { int valid, slen, ili; uint64_t ull = 0; slen = get_scsi_pt_sense_len(ptvp); valid = sg_get_sense_info_fld(sense_b, slen, &ull); ili = has_blk_ili(sense_b, slen); if (valid && ili) { if (offsetp) *offsetp = (int)(int64_t)ull; ret = SG_LIB_CAT_ILLEGAL_REQ_WITH_INFO; } else { if (verbose > 1) fprintf(sg_warnings_strm, " info field: 0x%" PRIx64 ", valid: %d, ili: %d\n", ull, valid, ili); ret = SG_LIB_CAT_ILLEGAL_REQ; } } break; default: ret = -1; break; } } else ret = 0; destruct_scsi_pt_obj(ptvp); return ret; } /* Invokes a SCSI READ LONG (16) command (SBC). Note that 'xfer_len' * is in bytes. Returns 0 -> success, * SG_LIB_CAT_INVALID_OP -> READ LONG(16) not supported, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, * SG_LIB_CAT_ILLEGAL_REQ_WITH_INFO -> bad field in cdb, with info * field written to 'offsetp', SG_LIB_CAT_ABORTED_COMMAND, * SG_LIB_CAT_NOT_READY -> device not ready, -1 -> other failure */ int sg_ll_read_long16(int sg_fd, int pblock, int correct, uint64_t llba, void * resp, int xfer_len, int * offsetp, int noisy, int verbose) { int k, res, sense_cat, ret; unsigned char readLongCmdBlk[SERVICE_ACTION_IN_16_CMDLEN]; unsigned char sense_b[SENSE_BUFF_LEN]; struct sg_pt_base * ptvp; memset(readLongCmdBlk, 0, sizeof(readLongCmdBlk)); readLongCmdBlk[0] = SERVICE_ACTION_IN_16_CMD; readLongCmdBlk[1] = READ_LONG_16_SA; if (pblock) readLongCmdBlk[14] |= 0x2; if (correct) readLongCmdBlk[14] |= 0x1; readLongCmdBlk[2] = (llba >> 56) & 0xff; readLongCmdBlk[3] = (llba >> 48) & 0xff; readLongCmdBlk[4] = (llba >> 40) & 0xff; readLongCmdBlk[5] = (llba >> 32) & 0xff; readLongCmdBlk[6] = (llba >> 24) & 0xff; readLongCmdBlk[7] = (llba >> 16) & 0xff; readLongCmdBlk[8] = (llba >> 8) & 0xff; readLongCmdBlk[9] = llba & 0xff; readLongCmdBlk[12] = (xfer_len >> 8) & 0xff; readLongCmdBlk[13] = xfer_len & 0xff; if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; if (verbose) { fprintf(sg_warnings_strm, " Read Long (16) cmd: "); for (k = 0; k < SERVICE_ACTION_IN_16_CMDLEN; ++k) fprintf(sg_warnings_strm, "%02x ", readLongCmdBlk[k]); fprintf(sg_warnings_strm, "\n"); } ptvp = construct_scsi_pt_obj(); if (NULL == ptvp) { fprintf(sg_warnings_strm, "read long (16): out of memory\n"); return -1; } set_scsi_pt_cdb(ptvp, readLongCmdBlk, sizeof(readLongCmdBlk)); set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); set_scsi_pt_data_in(ptvp, (unsigned char *)resp, xfer_len); res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, "read long (16)", res, xfer_len, sense_b, noisy, verbose, &sense_cat); if (-1 == ret) ; else if (-2 == ret) { switch (sense_cat) { case SG_LIB_CAT_NOT_READY: case SG_LIB_CAT_INVALID_OP: case SG_LIB_CAT_UNIT_ATTENTION: case SG_LIB_CAT_ABORTED_COMMAND: ret = sense_cat; break; case SG_LIB_CAT_RECOVERED: case SG_LIB_CAT_NO_SENSE: ret = 0; break; case SG_LIB_CAT_ILLEGAL_REQ: { int valid, slen, ili; uint64_t ull = 0; slen = get_scsi_pt_sense_len(ptvp); valid = sg_get_sense_info_fld(sense_b, slen, &ull); ili = has_blk_ili(sense_b, slen); if (valid && ili) { if (offsetp) *offsetp = (int)(int64_t)ull; ret = SG_LIB_CAT_ILLEGAL_REQ_WITH_INFO; } else { if (verbose > 1) fprintf(sg_warnings_strm, " info field: 0x%" PRIx64 ", valid: %d, ili: %d\n", ull, valid, ili); ret = SG_LIB_CAT_ILLEGAL_REQ; } } break; default: ret = -1; break; } } else ret = 0; destruct_scsi_pt_obj(ptvp); return ret; } /* Invokes a SCSI WRITE LONG (10) command (SBC). Note that 'xfer_len' * is in bytes. Returns 0 -> success, * SG_LIB_CAT_INVALID_OP -> WRITE LONG(10) not supported, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, * SG_LIB_CAT_ILLEGAL_REQ_WITH_INFO -> bad field in cdb, with info * field written to 'offsetp', SG_LIB_CAT_UNIT_ATTENTION, * SG_LIB_CAT_NOT_READY -> device not ready, * SG_LIB_CAT_ABORTED_COMMAND, -1 -> other failure */ int sg_ll_write_long10(int sg_fd, int cor_dis, int wr_uncor, int pblock, unsigned int lba, void * data_out, int xfer_len, int * offsetp, int noisy, int verbose) { int k, res, sense_cat, ret; unsigned char writeLongCmdBlk[WRITE_LONG10_CMDLEN]; unsigned char sense_b[SENSE_BUFF_LEN]; struct sg_pt_base * ptvp; memset(writeLongCmdBlk, 0, WRITE_LONG10_CMDLEN); writeLongCmdBlk[0] = WRITE_LONG10_CMD; if (cor_dis) writeLongCmdBlk[1] |= 0x80; if (wr_uncor) writeLongCmdBlk[1] |= 0x40; if (pblock) writeLongCmdBlk[1] |= 0x20; writeLongCmdBlk[2] = (lba >> 24) & 0xff; writeLongCmdBlk[3] = (lba >> 16) & 0xff; writeLongCmdBlk[4] = (lba >> 8) & 0xff; writeLongCmdBlk[5] = lba & 0xff; writeLongCmdBlk[7] = (xfer_len >> 8) & 0xff; writeLongCmdBlk[8] = xfer_len & 0xff; if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; if (verbose) { fprintf(sg_warnings_strm, " Write Long (10) cmd: "); for (k = 0; k < (int)sizeof(writeLongCmdBlk); ++k) fprintf(sg_warnings_strm, "%02x ", writeLongCmdBlk[k]); fprintf(sg_warnings_strm, "\n"); } ptvp = construct_scsi_pt_obj(); if (NULL == ptvp) { fprintf(sg_warnings_strm, "write long(10): out of memory\n"); return -1; } set_scsi_pt_cdb(ptvp, writeLongCmdBlk, sizeof(writeLongCmdBlk)); set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); set_scsi_pt_data_out(ptvp, (unsigned char *)data_out, xfer_len); res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, "write long(10)", res, 0, sense_b, noisy, verbose, &sense_cat); if (-1 == ret) ; else if (-2 == ret) { switch (sense_cat) { case SG_LIB_CAT_NOT_READY: case SG_LIB_CAT_UNIT_ATTENTION: case SG_LIB_CAT_INVALID_OP: case SG_LIB_CAT_ABORTED_COMMAND: ret = sense_cat; break; case SG_LIB_CAT_RECOVERED: case SG_LIB_CAT_NO_SENSE: ret = 0; break; case SG_LIB_CAT_ILLEGAL_REQ: { int valid, slen, ili; uint64_t ull = 0; slen = get_scsi_pt_sense_len(ptvp); valid = sg_get_sense_info_fld(sense_b, slen, &ull); ili = has_blk_ili(sense_b, slen); if (valid && ili) { if (offsetp) *offsetp = (int)(int64_t)ull; ret = SG_LIB_CAT_ILLEGAL_REQ_WITH_INFO; } else { if (verbose > 1) fprintf(sg_warnings_strm, " info field: 0x%" PRIx64 ", valid: %d, ili: %d\n", ull, valid, ili); ret = SG_LIB_CAT_ILLEGAL_REQ; } } break; default: ret = -1; break; } } else ret = 0; destruct_scsi_pt_obj(ptvp); return ret; } /* Invokes a SCSI WRITE LONG (16) command (SBC). Note that 'xfer_len' * is in bytes. Returns 0 -> success, * SG_LIB_CAT_INVALID_OP -> WRITE LONG(16) not supported, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, * SG_LIB_CAT_ILLEGAL_REQ_WITH_INFO -> bad field in cdb, with info * field written to 'offsetp', SG_LIB_CAT_UNIT_ATTENTION, * SG_LIB_CAT_NOT_READY -> device not ready, * SG_LIB_CAT_ABORTED_COMMAND, -1 -> other failure */ int sg_ll_write_long16(int sg_fd, int cor_dis, int wr_uncor, int pblock, uint64_t llba, void * data_out, int xfer_len, int * offsetp, int noisy, int verbose) { int k, res, sense_cat, ret; unsigned char writeLongCmdBlk[SERVICE_ACTION_OUT_16_CMDLEN]; unsigned char sense_b[SENSE_BUFF_LEN]; struct sg_pt_base * ptvp; memset(writeLongCmdBlk, 0, sizeof(writeLongCmdBlk)); writeLongCmdBlk[0] = SERVICE_ACTION_OUT_16_CMD; writeLongCmdBlk[1] = WRITE_LONG_16_SA; if (cor_dis) writeLongCmdBlk[1] |= 0x80; if (wr_uncor) writeLongCmdBlk[1] |= 0x40; if (pblock) writeLongCmdBlk[1] |= 0x20; writeLongCmdBlk[2] = (llba >> 56) & 0xff; writeLongCmdBlk[3] = (llba >> 48) & 0xff; writeLongCmdBlk[4] = (llba >> 40) & 0xff; writeLongCmdBlk[5] = (llba >> 32) & 0xff; writeLongCmdBlk[6] = (llba >> 24) & 0xff; writeLongCmdBlk[7] = (llba >> 16) & 0xff; writeLongCmdBlk[8] = (llba >> 8) & 0xff; writeLongCmdBlk[9] = llba & 0xff; writeLongCmdBlk[12] = (xfer_len >> 8) & 0xff; writeLongCmdBlk[13] = xfer_len & 0xff; if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; if (verbose) { fprintf(sg_warnings_strm, " Write Long (16) cmd: "); for (k = 0; k < SERVICE_ACTION_OUT_16_CMDLEN; ++k) fprintf(sg_warnings_strm, "%02x ", writeLongCmdBlk[k]); fprintf(sg_warnings_strm, "\n"); } ptvp = construct_scsi_pt_obj(); if (NULL == ptvp) { fprintf(sg_warnings_strm, "write long(16): out of memory\n"); return -1; } set_scsi_pt_cdb(ptvp, writeLongCmdBlk, sizeof(writeLongCmdBlk)); set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); set_scsi_pt_data_out(ptvp, (unsigned char *)data_out, xfer_len); res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, "write long(16)", res, 0, sense_b, noisy, verbose, &sense_cat); if (-1 == ret) ; else if (-2 == ret) { switch (sense_cat) { case SG_LIB_CAT_NOT_READY: case SG_LIB_CAT_UNIT_ATTENTION: case SG_LIB_CAT_INVALID_OP: case SG_LIB_CAT_ABORTED_COMMAND: ret = sense_cat; break; case SG_LIB_CAT_RECOVERED: case SG_LIB_CAT_NO_SENSE: ret = 0; break; case SG_LIB_CAT_ILLEGAL_REQ: { int valid, slen, ili; uint64_t ull = 0; slen = get_scsi_pt_sense_len(ptvp); valid = sg_get_sense_info_fld(sense_b, slen, &ull); ili = has_blk_ili(sense_b, slen); if (valid && ili) { if (offsetp) *offsetp = (int)(int64_t)ull; ret = SG_LIB_CAT_ILLEGAL_REQ_WITH_INFO; } else { if (verbose > 1) fprintf(sg_warnings_strm, " info field: 0x%" PRIx64 ", valid: %d, ili: %d\n", ull, valid, ili); ret = SG_LIB_CAT_ILLEGAL_REQ; } } break; default: ret = -1; break; } } else ret = 0; destruct_scsi_pt_obj(ptvp); return ret; } /* Invokes a SCSI VERIFY (10) command (SBC and MMC). * Note that 'veri_len' is in blocks while 'data_out_len' is in bytes. * Returns of 0 -> success, * SG_LIB_CAT_INVALID_OP -> Verify(10) not supported, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_UNIT_ATTENTION, * SG_LIB_CAT_MEDIUM_HARD -> medium or hardware error, no valid info, * SG_LIB_CAT_MEDIUM_HARD_WITH_INFO -> as previous, with valid info, * SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND, * -1 -> other failure */ int sg_ll_verify10(int sg_fd, int vrprotect, int dpo, int bytechk, unsigned int lba, int veri_len, void * data_out, int data_out_len, unsigned int * infop, int noisy, int verbose) { int k, res, ret, sense_cat; unsigned char vCmdBlk[VERIFY10_CMDLEN] = {VERIFY10_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0}; unsigned char sense_b[SENSE_BUFF_LEN]; struct sg_pt_base * ptvp; vCmdBlk[1] = ((vrprotect & 0x7) << 5) | ((dpo & 0x1) << 4) | ((bytechk & 0x1) << 1) ; vCmdBlk[2] = (unsigned char)((lba >> 24) & 0xff); vCmdBlk[3] = (unsigned char)((lba >> 16) & 0xff); vCmdBlk[4] = (unsigned char)((lba >> 8) & 0xff); vCmdBlk[5] = (unsigned char)(lba & 0xff); vCmdBlk[7] = (unsigned char)((veri_len >> 8) & 0xff); vCmdBlk[8] = (unsigned char)(veri_len & 0xff); if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; if (verbose > 1) { fprintf(sg_warnings_strm, " Verify(10) cdb: "); for (k = 0; k < VERIFY10_CMDLEN; ++k) fprintf(sg_warnings_strm, "%02x ", vCmdBlk[k]); fprintf(sg_warnings_strm, "\n"); } ptvp = construct_scsi_pt_obj(); if (NULL == ptvp) { fprintf(sg_warnings_strm, "verify (10): out of memory\n"); return -1; } set_scsi_pt_cdb(ptvp, vCmdBlk, sizeof(vCmdBlk)); set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); if (data_out_len > 0) set_scsi_pt_data_out(ptvp, (unsigned char *)data_out, data_out_len); res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, "verify (10)", res, 0, sense_b, noisy, verbose, &sense_cat); if (-1 == ret) ; else if (-2 == ret) { switch (sense_cat) { case SG_LIB_CAT_NOT_READY: case SG_LIB_CAT_INVALID_OP: case SG_LIB_CAT_ILLEGAL_REQ: case SG_LIB_CAT_UNIT_ATTENTION: case SG_LIB_CAT_ABORTED_COMMAND: ret = sense_cat; break; case SG_LIB_CAT_RECOVERED: case SG_LIB_CAT_NO_SENSE: ret = 0; break; case SG_LIB_CAT_MEDIUM_HARD: { int valid, slen; uint64_t ull = 0; slen = get_scsi_pt_sense_len(ptvp); valid = sg_get_sense_info_fld(sense_b, slen, &ull); if (valid) { if (infop) *infop = (unsigned int)ull; ret = SG_LIB_CAT_MEDIUM_HARD_WITH_INFO; } else ret = SG_LIB_CAT_MEDIUM_HARD; } break; default: ret = -1; break; } } else ret = 0; destruct_scsi_pt_obj(ptvp); return ret; } /* Invokes a SCSI VERIFY (16) command (SBC and MMC). * Note that 'veri_len' is in blocks while 'data_out_len' is in bytes. * Returns of 0 -> success, * SG_LIB_CAT_INVALID_OP -> Verify(16) not supported, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_UNIT_ATTENTION, * SG_LIB_CAT_MEDIUM_HARD -> medium or hardware error, no valid info, * SG_LIB_CAT_MEDIUM_HARD_WITH_INFO -> as previous, with valid info, * SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND, * -1 -> other failure */ int sg_ll_verify16(int sg_fd, int vrprotect, int dpo, int bytechk, uint64_t llba, int veri_len, int group_num, void * data_out, int data_out_len, uint64_t * infop, int noisy, int verbose) { int k, res, ret, sense_cat; unsigned char vCmdBlk[VERIFY16_CMDLEN] = {VERIFY16_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; unsigned char sense_b[SENSE_BUFF_LEN]; struct sg_pt_base * ptvp; vCmdBlk[1] = ((vrprotect & 0x7) << 5) | ((dpo & 0x1) << 4) | ((bytechk & 0x1) << 1) ; vCmdBlk[2] = (llba >> 56) & 0xff; vCmdBlk[3] = (llba >> 48) & 0xff; vCmdBlk[4] = (llba >> 40) & 0xff; vCmdBlk[5] = (llba >> 32) & 0xff; vCmdBlk[6] = (llba >> 24) & 0xff; vCmdBlk[7] = (llba >> 16) & 0xff; vCmdBlk[8] = (llba >> 8) & 0xff; vCmdBlk[9] = llba & 0xff; vCmdBlk[10] = (veri_len >> 24) & 0xff; vCmdBlk[11] = (veri_len >> 16) & 0xff; vCmdBlk[12] = (veri_len >> 8) & 0xff; vCmdBlk[13] = veri_len & 0xff; vCmdBlk[14] = group_num & 0x1f; if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; if (verbose > 1) { fprintf(sg_warnings_strm, " Verify(16) cdb: "); for (k = 0; k < VERIFY16_CMDLEN; ++k) fprintf(sg_warnings_strm, "%02x ", vCmdBlk[k]); fprintf(sg_warnings_strm, "\n"); } ptvp = construct_scsi_pt_obj(); if (NULL == ptvp) { fprintf(sg_warnings_strm, "verify (16): out of memory\n"); return -1; } set_scsi_pt_cdb(ptvp, vCmdBlk, sizeof(vCmdBlk)); set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); if (data_out_len > 0) set_scsi_pt_data_out(ptvp, (unsigned char *)data_out, data_out_len); res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, "verify (16)", res, 0, sense_b, noisy, verbose, &sense_cat); if (-1 == ret) ; else if (-2 == ret) { switch (sense_cat) { case SG_LIB_CAT_NOT_READY: case SG_LIB_CAT_INVALID_OP: case SG_LIB_CAT_ILLEGAL_REQ: case SG_LIB_CAT_UNIT_ATTENTION: case SG_LIB_CAT_ABORTED_COMMAND: ret = sense_cat; break; case SG_LIB_CAT_RECOVERED: case SG_LIB_CAT_NO_SENSE: ret = 0; break; case SG_LIB_CAT_MEDIUM_HARD: { int valid, slen; uint64_t ull = 0; slen = get_scsi_pt_sense_len(ptvp); valid = sg_get_sense_info_fld(sense_b, slen, &ull); if (valid) { if (infop) *infop = ull; ret = SG_LIB_CAT_MEDIUM_HARD_WITH_INFO; } else ret = SG_LIB_CAT_MEDIUM_HARD; } break; default: ret = -1; break; } } else ret = 0; destruct_scsi_pt_obj(ptvp); return ret; } /* Invokes a ATA PASS-THROUGH (12 or 16) SCSI command (SAT). If cdb_len * is 12 then a ATA PASS-THROUGH (12) command is called. If cdb_len is 16 * then a ATA PASS-THROUGH (16) command is called. If cdb_len is any other * value -1 is returned. After copying from cdbp to an internal buffer, * the first byte (i.e. offset 0) is set to 0xa1 if cdb_len is 12; or is * set to 0x85 if cdb_len is 16. The last byte (offset 11 or offset 15) is * set to 0x0 in the internal buffer. If timeout_secs <= 0 then the timeout * is set to 60 seconds. For data in or out transfers set dinp or doutp, * and dlen to the number of bytes to transfer. If dlen is zero then no data * transfer is assumed. If sense buffer obtained then it is written to * sensep, else sensep[0] is set to 0x0. If ATA return descriptor is obtained * then written to ata_return_dp, else ata_return_dp[0] is set to 0x0. Either * sensep or ata_return_dp (or both) may be NULL pointers. Returns SCSI * status value (>= 0) or -1 if other error. Users are expected to check the * sense buffer themselves. If available the data in resid is written to * residp. */ int sg_ll_ata_pt(int sg_fd, const unsigned char * cdbp, int cdb_len, int timeout_secs, void * dinp, void * doutp, int dlen, unsigned char * sensep, int max_sense_len, unsigned char * ata_return_dp, int max_ata_return_len, int * residp, int verbose) { int k, res, slen, duration; unsigned char aptCmdBlk[ATA_PT_16_CMDLEN] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; unsigned char sense_b[SENSE_BUFF_LEN]; unsigned char * sp; const unsigned char * ucp; struct sg_pt_base * ptvp; const char * cnamep; char b[256]; int ret = -1; b[0] = '\0'; if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; cnamep = (12 == cdb_len) ? "ATA pass through (12)" : "ATA pass through (16)"; if ((NULL == cdbp) || ((12 != cdb_len) && (16 != cdb_len))) { if (verbose) { if (NULL == cdbp) fprintf(sg_warnings_strm, "%s NULL cdb pointer\n", cnamep); else fprintf(sg_warnings_strm, "cdb_len must be 12 or 16\n"); } return -1; } aptCmdBlk[0] = (12 == cdb_len) ? ATA_PT_12_CMD : ATA_PT_16_CMD; if (sensep && (max_sense_len >= (int)sizeof(sense_b))) { sp = sensep; slen = max_sense_len; } else { sp = sense_b; slen = sizeof(sense_b); } if (12 == cdb_len) memcpy(aptCmdBlk + 1, cdbp + 1, ((cdb_len > 11) ? 10 : (cdb_len - 1))); else memcpy(aptCmdBlk + 1, cdbp + 1, ((cdb_len > 15) ? 14 : (cdb_len - 1))); if (verbose) { fprintf(sg_warnings_strm, " %s cdb: ", cnamep); for (k = 0; k < cdb_len; ++k) fprintf(sg_warnings_strm, "%02x ", aptCmdBlk[k]); fprintf(sg_warnings_strm, "\n"); } ptvp = construct_scsi_pt_obj(); if (NULL == ptvp) { fprintf(sg_warnings_strm, "%s: out of memory\n", cnamep); return -1; } set_scsi_pt_cdb(ptvp, aptCmdBlk, cdb_len); set_scsi_pt_sense(ptvp, sp, slen); if (dlen > 0) { if (dinp) set_scsi_pt_data_in(ptvp, (unsigned char *)dinp, dlen); else if (doutp) set_scsi_pt_data_out(ptvp, (unsigned char *)doutp, dlen); } res = do_scsi_pt(ptvp, sg_fd, ((timeout_secs > 0) ? timeout_secs : DEF_PT_TIMEOUT), verbose); if (SCSI_PT_DO_BAD_PARAMS == res) { if (verbose) fprintf(sg_warnings_strm, "%s: bad parameters\n", cnamep); goto out; } else if (SCSI_PT_DO_TIMEOUT == res) { if (verbose) fprintf(sg_warnings_strm, "%s: timeout\n", cnamep); goto out; } else if (res > 2) { if (verbose) fprintf(sg_warnings_strm, "%s: do_scsi_pt: errno=%d\n", cnamep, -res); } if ((verbose > 2) && ((duration = get_scsi_pt_duration_ms(ptvp)) >= 0)) fprintf(sg_warnings_strm, " duration=%d ms\n", duration); switch (get_scsi_pt_result_category(ptvp)) { case SCSI_PT_RESULT_GOOD: if ((sensep) && (max_sense_len > 0)) *sensep = 0; if ((ata_return_dp) && (max_ata_return_len > 0)) *ata_return_dp = 0; if (residp && (dlen > 0)) *residp = get_scsi_pt_resid(ptvp); ret = 0; break; case SCSI_PT_RESULT_STATUS: /* other than GOOD + CHECK CONDITION */ if ((sensep) && (max_sense_len > 0)) *sensep = 0; if ((ata_return_dp) && (max_ata_return_len > 0)) *ata_return_dp = 0; ret = get_scsi_pt_status_response(ptvp); break; case SCSI_PT_RESULT_SENSE: if (sensep && (sp != sensep)) { k = get_scsi_pt_sense_len(ptvp); k = (k > max_sense_len) ? max_sense_len : k; memcpy(sensep, sp, k); } if (ata_return_dp && (max_ata_return_len > 0)) { /* search for ATA return descriptor */ ucp = sg_scsi_sense_desc_find(sp, slen, 0x9); if (ucp) { k = ucp[1] + 2; k = (k > max_ata_return_len) ? max_ata_return_len : k; memcpy(ata_return_dp, ucp, k); } else ata_return_dp[0] = 0x0; } if (residp && (dlen > 0)) *residp = get_scsi_pt_resid(ptvp); ret = get_scsi_pt_status_response(ptvp); break; case SCSI_PT_RESULT_TRANSPORT_ERR: if (verbose) fprintf(sg_warnings_strm, "%s: transport error: %s\n", cnamep, get_scsi_pt_transport_err_str(ptvp, sizeof(b) , b)); break; case SCSI_PT_RESULT_OS_ERR: if (verbose) fprintf(sg_warnings_strm, "%s: os error: %s\n", cnamep, get_scsi_pt_os_err_str(ptvp, sizeof(b) , b)); break; default: if (verbose) fprintf(sg_warnings_strm, "%s: unknown pt_result_category=%d\n", cnamep, get_scsi_pt_result_category(ptvp)); break; } out: destruct_scsi_pt_obj(ptvp); return ret; } /* Invokes a SCSI READ BUFFER command (SPC). Return of 0 -> * success, SG_LIB_CAT_INVALID_OP -> invalid opcode, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_UNIT_ATTENTION, * SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND, * -1 -> other failure */ int sg_ll_read_buffer(int sg_fd, int mode, int buffer_id, int buffer_offset, void * resp, int mx_resp_len, int noisy, int verbose) { int res, k, ret, sense_cat; unsigned char rbufCmdBlk[READ_BUFFER_CMDLEN] = {READ_BUFFER_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0}; unsigned char sense_b[SENSE_BUFF_LEN]; struct sg_pt_base * ptvp; rbufCmdBlk[1] = (unsigned char)(mode & 0x1f); rbufCmdBlk[2] = (unsigned char)(buffer_id & 0xff); rbufCmdBlk[3] = (unsigned char)((buffer_offset >> 16) & 0xff); rbufCmdBlk[4] = (unsigned char)((buffer_offset >> 8) & 0xff); rbufCmdBlk[5] = (unsigned char)(buffer_offset & 0xff); rbufCmdBlk[6] = (unsigned char)((mx_resp_len >> 16) & 0xff); rbufCmdBlk[7] = (unsigned char)((mx_resp_len >> 8) & 0xff); rbufCmdBlk[8] = (unsigned char)(mx_resp_len & 0xff); if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; if (verbose) { fprintf(sg_warnings_strm, " read buffer cdb: "); for (k = 0; k < READ_BUFFER_CMDLEN; ++k) fprintf(sg_warnings_strm, "%02x ", rbufCmdBlk[k]); fprintf(sg_warnings_strm, "\n"); } ptvp = construct_scsi_pt_obj(); if (NULL == ptvp) { fprintf(sg_warnings_strm, "read buffer: out of memory\n"); return -1; } set_scsi_pt_cdb(ptvp, rbufCmdBlk, sizeof(rbufCmdBlk)); set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); set_scsi_pt_data_in(ptvp, (unsigned char *)resp, mx_resp_len); res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, "read buffer", res, mx_resp_len, sense_b, noisy, verbose, &sense_cat); if (-1 == ret) ; else if (-2 == ret) { switch (sense_cat) { case SG_LIB_CAT_NOT_READY: case SG_LIB_CAT_INVALID_OP: case SG_LIB_CAT_ILLEGAL_REQ: case SG_LIB_CAT_UNIT_ATTENTION: case SG_LIB_CAT_ABORTED_COMMAND: ret = sense_cat; break; case SG_LIB_CAT_RECOVERED: case SG_LIB_CAT_NO_SENSE: ret = 0; break; default: ret = -1; break; } } else { if ((verbose > 2) && (ret > 0)) { fprintf(sg_warnings_strm, " read buffer: response%s\n", (ret > 256 ? ", first 256 bytes" : "")); dStrHex((const char *)resp, (ret > 256 ? 256 : ret), -1); } ret = 0; } destruct_scsi_pt_obj(ptvp); return ret; } /* Invokes a SCSI WRITE BUFFER command (SPC). Return of 0 -> * success, SG_LIB_CAT_INVALID_OP -> invalid opcode, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_UNIT_ATTENTION, * SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND, * -1 -> other failure */ int sg_ll_write_buffer(int sg_fd, int mode, int buffer_id, int buffer_offset, void * paramp, int param_len, int noisy, int verbose) { int k, res, ret, sense_cat; unsigned char wbufCmdBlk[WRITE_BUFFER_CMDLEN] = {WRITE_BUFFER_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0}; unsigned char sense_b[SENSE_BUFF_LEN]; struct sg_pt_base * ptvp; wbufCmdBlk[1] = (unsigned char)(mode & 0x1f); wbufCmdBlk[2] = (unsigned char)(buffer_id & 0xff); wbufCmdBlk[3] = (unsigned char)((buffer_offset >> 16) & 0xff); wbufCmdBlk[4] = (unsigned char)((buffer_offset >> 8) & 0xff); wbufCmdBlk[5] = (unsigned char)(buffer_offset & 0xff); wbufCmdBlk[6] = (unsigned char)((param_len >> 16) & 0xff); wbufCmdBlk[7] = (unsigned char)((param_len >> 8) & 0xff); wbufCmdBlk[8] = (unsigned char)(param_len & 0xff); if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; if (verbose) { fprintf(sg_warnings_strm, " Write buffer cmd: "); for (k = 0; k < WRITE_BUFFER_CMDLEN; ++k) fprintf(sg_warnings_strm, "%02x ", wbufCmdBlk[k]); fprintf(sg_warnings_strm, "\n"); if ((verbose > 1) && paramp && param_len) { fprintf(sg_warnings_strm, " Write buffer parameter list%s:\n", ((param_len > 256) ? " (first 256 bytes)" : "")); dStrHex((const char *)paramp, ((param_len > 256) ? 256 : param_len), -1); } } ptvp = construct_scsi_pt_obj(); if (NULL == ptvp) { fprintf(sg_warnings_strm, "write buffer: out of memory\n"); return -1; } set_scsi_pt_cdb(ptvp, wbufCmdBlk, sizeof(wbufCmdBlk)); set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); set_scsi_pt_data_out(ptvp, (unsigned char *)paramp, param_len); res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, "write buffer", res, 0, sense_b, noisy, verbose, &sense_cat); if (-1 == ret) ; else if (-2 == ret) { switch (sense_cat) { case SG_LIB_CAT_NOT_READY: case SG_LIB_CAT_INVALID_OP: case SG_LIB_CAT_ILLEGAL_REQ: case SG_LIB_CAT_UNIT_ATTENTION: case SG_LIB_CAT_ABORTED_COMMAND: ret = sense_cat; break; case SG_LIB_CAT_RECOVERED: case SG_LIB_CAT_NO_SENSE: ret = 0; break; default: ret = -1; break; } } else ret = 0; destruct_scsi_pt_obj(ptvp); return ret; } /* Invokes a SCSI UNMAP command. Return of 0 -> success, * SG_LIB_CAT_INVALID_OP -> command not supported, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_ABORTED_COMMAND, * SG_LIB_CAT_UNIT_ATTENTION, -1 -> other failure */ int sg_ll_unmap(int sg_fd, int group_num, int timeout_secs, void * paramp, int param_len, int noisy, int verbose) { return sg_ll_unmap_v2(sg_fd, 0, group_num, timeout_secs, paramp, param_len, noisy, verbose); } /* Invokes a SCSI UNMAP (SBC-3) command. Version 2 adds anchor field * (sbc3r22). Otherwise same as sg_ll_unmap() . */ int sg_ll_unmap_v2(int sg_fd, int anchor, int group_num, int timeout_secs, void * paramp, int param_len, int noisy, int verbose) { int k, res, ret, sense_cat, tmout; unsigned char uCmdBlk[UNMAP_CMDLEN] = {UNMAP_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0}; unsigned char sense_b[SENSE_BUFF_LEN]; struct sg_pt_base * ptvp; if (anchor) uCmdBlk[1] |= 0x1; tmout = (timeout_secs > 0) ? timeout_secs : DEF_PT_TIMEOUT; uCmdBlk[7] = group_num & 0x1f; uCmdBlk[7] = (param_len >> 8) & 0xff; uCmdBlk[8] = param_len & 0xff; if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; if (verbose) { fprintf(sg_warnings_strm, " unmap cdb: "); for (k = 0; k < UNMAP_CMDLEN; ++k) fprintf(sg_warnings_strm, "%02x ", uCmdBlk[k]); fprintf(sg_warnings_strm, "\n"); if ((verbose > 1) && paramp && param_len) { fprintf(sg_warnings_strm, " unmap parameter list:\n"); dStrHex((const char *)paramp, param_len, -1); } } ptvp = construct_scsi_pt_obj(); if (NULL == ptvp) { fprintf(sg_warnings_strm, "unmap: out of memory\n"); return -1; } set_scsi_pt_cdb(ptvp, uCmdBlk, sizeof(uCmdBlk)); set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); set_scsi_pt_data_out(ptvp, (unsigned char *)paramp, param_len); res = do_scsi_pt(ptvp, sg_fd, tmout, verbose); ret = sg_cmds_process_resp(ptvp, "unmap", res, 0, sense_b, noisy, verbose, &sense_cat); if (-1 == ret) ; else if (-2 == ret) { switch (sense_cat) { case SG_LIB_CAT_INVALID_OP: case SG_LIB_CAT_ILLEGAL_REQ: case SG_LIB_CAT_UNIT_ATTENTION: case SG_LIB_CAT_ABORTED_COMMAND: ret = sense_cat; break; case SG_LIB_CAT_RECOVERED: case SG_LIB_CAT_NO_SENSE: ret = 0; break; default: ret = -1; break; } } else ret = 0; destruct_scsi_pt_obj(ptvp); return ret; } /* Invokes a SCSI READ BLOCK LIMITS command. Return of 0 -> success, * SG_LIB_CAT_INVALID_OP -> Read block limits not supported, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, * SG_LIB_CAT_ABORTED_COMMAND, * SG_LIB_NOT_READY (shouldn't happen), -1 -> other failure */ int sg_ll_read_block_limits(int sg_fd, void * resp, int mx_resp_len, int noisy, int verbose) { int k, ret, res, sense_cat; unsigned char rlCmdBlk[READ_BLOCK_LIMITS_CMDLEN] = {READ_BLOCK_LIMITS_CMD, 0, 0, 0, 0, 0}; unsigned char sense_b[SENSE_BUFF_LEN]; struct sg_pt_base * ptvp; if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; if (verbose) { fprintf(sg_warnings_strm, " read block limits cdb: "); for (k = 0; k < READ_BLOCK_LIMITS_CMDLEN; ++k) fprintf(sg_warnings_strm, "%02x ", rlCmdBlk[k]); fprintf(sg_warnings_strm, "\n"); } ptvp = construct_scsi_pt_obj(); if (NULL == ptvp) { fprintf(sg_warnings_strm, "read block limits: out of memory\n"); return -1; } set_scsi_pt_cdb(ptvp, rlCmdBlk, sizeof(rlCmdBlk)); set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); set_scsi_pt_data_in(ptvp, (unsigned char *)resp, mx_resp_len); res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, "read block limits", res, mx_resp_len, sense_b, noisy, verbose, &sense_cat); if (-1 == ret) ; else if (-2 == ret) { switch (sense_cat) { case SG_LIB_CAT_INVALID_OP: case SG_LIB_CAT_ILLEGAL_REQ: case SG_LIB_CAT_ABORTED_COMMAND: case SG_LIB_CAT_NOT_READY: /* shouldn't happen ?? */ ret = sense_cat; break; case SG_LIB_CAT_RECOVERED: case SG_LIB_CAT_NO_SENSE: ret = 0; break; default: ret = -1; break; } } else ret = 0; destruct_scsi_pt_obj(ptvp); return ret; } ddpt-0.92/lib/sg_pt_common.c0000644000175000017500000000062311524334352014774 0ustar douggdougg/* * Copyright (c) 2009-2011 Douglas Gilbert. * All rights reserved. * Use of this source code is governed by a BSD-style * license that can be found in the BSD_LICENSE file. */ #include #include "sg_pt.h" #ifdef HAVE_CONFIG_H #include "config.h" #endif static const char * scsi_pt_version_str = "2.08 20110207"; const char * scsi_pt_version() { return scsi_pt_version_str; } ddpt-0.92/lib/sg_pt_win32.c0000644000175000017500000005724711525020611014453 0ustar douggdougg/* * Copyright (c) 2006-2011 Douglas Gilbert. * All rights reserved. * Use of this source code is governed by a BSD-style * license that can be found in the BSD_LICENSE file. */ /* sg_pt_win32 version 1.13 20110207 */ #include #include #include #include #include #include #include "sg_pt.h" #include "sg_lib.h" #include "sg_pt_win32.h" #ifdef HAVE_CONFIG_H #include "config.h" #endif /* Use the Microsoft SCSI Pass Through (SPT) interface. It has two * variants: "SPT" where data is double buffered; and "SPTD" where data * pointers to the user space are passed to the OS. Only Windows * 2000 and later (i.e. not 95,98 or ME). * There is no ASPI interface which relies on a dll from adaptec. * This code uses cygwin facilities and is built in a cygwin * shell. It can be run in a normal DOS shell if the cygwin1.dll * file is put in an appropriate place. * This code can build in a MinGW environment. * * N.B. MSDN says that the "SPT" interface (i.e. double buffered) * should be used for small amounts of data (it says "< 16 KB"). * The direct variant (i.e. IOCTL_SCSI_PASS_THROUGH_DIRECT) should * be used for larger amounts of data but the buffer needs to be * "cache aligned". Is that 16 byte alignment or greater? * * This code will default to indirect (i.e. double buffered) access * unless the WIN32_SPT_DIRECT preprocessor constant is defined in * config.h . In version 1.12 runtime selection of direct and indirect * access was added; the default is still determined by the * WIN32_SPT_DIRECT preprocessor constant. */ #define DEF_TIMEOUT 60 /* 60 seconds */ #define MAX_OPEN_SIMULT 8 #define WIN32_FDOFFSET 32 struct sg_pt_handle { int in_use; HANDLE fh; char adapter[32]; int bus; int target; int lun; }; struct sg_pt_handle handle_arr[MAX_OPEN_SIMULT]; struct sg_pt_win32_scsi { unsigned char * dxferp; int dxfer_len; unsigned char * sensep; int sense_len; int scsi_status; int resid; int sense_resid; int in_err; int os_err; /* pseudo unix error */ int transport_err; /* windows error number */ union { SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER swb_d; /* Last entry in structure so data buffer can be extended */ SCSI_PASS_THROUGH_WITH_BUFFERS swb_i; }; }; /* embed pointer so can change on fly if (non-direct) data buffer * is not big enough */ struct sg_pt_base { struct sg_pt_win32_scsi * implp; }; #ifdef WIN32_SPT_DIRECT static int spt_direct = 1; #else static int spt_direct = 0; #endif /* Request SPT direct interface when state_direct is 1, state_direct set * to 0 for the SPT indirect interface. */ void scsi_pt_win32_direct(int state_direct) { spt_direct = state_direct; } /* Returns current SPT interface state, 1 for direct, 0 for indirect */ int scsi_pt_win32_spt_state(void) { return spt_direct; } /* Returns >= 0 if successful. If error in Unix returns negated errno. */ int scsi_pt_open_device(const char * device_name, int read_only, int verbose) { int oflags = 0 /* O_NONBLOCK*/ ; oflags |= (read_only ? 0 : 0); /* was ... ? O_RDONLY : O_RDWR) */ return scsi_pt_open_flags(device_name, oflags, verbose); } /* * Similar to scsi_pt_open_device() but takes Unix style open flags OR-ed * together. The 'flags' argument is ignored in Windows. * Returns >= 0 if successful, otherwise returns negated errno. * Optionally accept leading "\\.\". If given something of the form * "SCSI:,," where the values in angle brackets * are integers, then will attempt to open "\\.\SCSI:" and save the * other three values for the DeviceIoControl call. The trailing "." * is optionally and if not given 0 is assumed. Since "PhysicalDrive" * is a lot of keystrokes, "PD" is accepted and converted to the longer * form. */ int scsi_pt_open_flags(const char * device_name, int flags __attribute__ ((unused)), int verbose) { int len, k, adapter_num, bus, target, lun, off, got_scsi_name; int index, num, got_pd_name, pd_num; struct sg_pt_handle * shp; char buff[8]; if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; /* lock */ for (k = 0; k < MAX_OPEN_SIMULT; k++) if (0 == handle_arr[k].in_use) break; if (k == MAX_OPEN_SIMULT) { if (verbose) fprintf(sg_warnings_strm, "too many open handles " "(%d)\n", MAX_OPEN_SIMULT); return -EMFILE; } else handle_arr[k].in_use = 1; /* unlock */ index = k; shp = handle_arr + index; adapter_num = 0; bus = 0; /* also known as 'PathId' in MS docs */ target = 0; lun = 0; got_pd_name = 0; got_scsi_name = 0; len = strlen(device_name); if ((len > 4) && (0 == strncmp("\\\\.\\", device_name, 4))) off = 4; else off = 0; if (len > (off + 2)) { buff[0] = toupper((int)device_name[off + 0]); buff[1] = toupper((int)device_name[off + 1]); if (0 == strncmp("PD", buff, 2)) { num = sscanf(device_name + off + 2, "%d", &pd_num); if (1 == num) got_pd_name = 1; } if (0 == got_pd_name) { buff[2] = toupper((int)device_name[off + 2]); buff[3] = toupper((int)device_name[off + 3]); if (0 == strncmp("SCSI", buff, 4)) { num = sscanf(device_name + off + 4, "%d:%d,%d,%d", &adapter_num, &bus, &target, &lun); if (num < 3) { if (verbose) fprintf(sg_warnings_strm, "expected format like: " "'SCSI:.[.]'\n"); shp->in_use = 0; return -EINVAL; } got_scsi_name = 1; } } } shp->bus = bus; shp->target = target; shp->lun = lun; memset(shp->adapter, 0, sizeof(shp->adapter)); strncpy(shp->adapter, "\\\\.\\", 4); if (got_pd_name) snprintf(shp->adapter + 4, sizeof(shp->adapter) - 5, "PhysicalDrive%d", pd_num); else if (got_scsi_name) snprintf(shp->adapter + 4, sizeof(shp->adapter) - 5, "SCSI%d:", adapter_num); else snprintf(shp->adapter + 4, sizeof(shp->adapter) - 5, "%s", device_name + off); shp->fh = CreateFile(shp->adapter, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (shp->fh == INVALID_HANDLE_VALUE) { if (verbose) fprintf(sg_warnings_strm, "Windows CreateFile error=%ld\n", GetLastError()); shp->in_use = 0; return -ENODEV; } return index + WIN32_FDOFFSET; } /* Returns 0 if successful. If error in Unix returns negated errno. */ int scsi_pt_close_device(int device_fd) { struct sg_pt_handle * shp; int index; index = device_fd - WIN32_FDOFFSET; if ((index < 0) || (index >= WIN32_FDOFFSET)) return -ENODEV; shp = handle_arr + index; CloseHandle(shp->fh); shp->bus = 0; shp->target = 0; shp->lun = 0; memset(shp->adapter, 0, sizeof(shp->adapter)); shp->in_use = 0; return 0; } struct sg_pt_base * construct_scsi_pt_obj() { struct sg_pt_win32_scsi * psp; struct sg_pt_base * vp = NULL; psp = (struct sg_pt_win32_scsi *)calloc(sizeof(struct sg_pt_win32_scsi), 1); if (psp) { if (spt_direct) { psp->swb_d.spt.DataIn = SCSI_IOCTL_DATA_UNSPECIFIED; psp->swb_d.spt.SenseInfoLength = SCSI_MAX_SENSE_LEN; psp->swb_d.spt.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS, ucSenseBuf); psp->swb_d.spt.TimeOutValue = DEF_TIMEOUT; } else { psp->swb_i.spt.DataIn = SCSI_IOCTL_DATA_UNSPECIFIED; psp->swb_i.spt.SenseInfoLength = SCSI_MAX_SENSE_LEN; psp->swb_i.spt.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS, ucSenseBuf); psp->swb_i.spt.TimeOutValue = DEF_TIMEOUT; } vp = malloc(sizeof(struct sg_pt_win32_scsi *)); // yes a pointer if (vp) vp->implp = psp; else free(psp); } return vp; } void destruct_scsi_pt_obj(struct sg_pt_base * vp) { if (vp) { struct sg_pt_win32_scsi * psp = vp->implp; if (psp) { free(psp); } free(vp); } } void clear_scsi_pt_obj(struct sg_pt_base * vp) { struct sg_pt_win32_scsi * psp = vp->implp; if (psp) { memset(psp, 0, sizeof(struct sg_pt_win32_scsi)); if (spt_direct) { psp->swb_d.spt.DataIn = SCSI_IOCTL_DATA_UNSPECIFIED; psp->swb_d.spt.SenseInfoLength = SCSI_MAX_SENSE_LEN; psp->swb_d.spt.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS, ucSenseBuf); psp->swb_d.spt.TimeOutValue = DEF_TIMEOUT; } else { psp->swb_i.spt.DataIn = SCSI_IOCTL_DATA_UNSPECIFIED; psp->swb_i.spt.SenseInfoLength = SCSI_MAX_SENSE_LEN; psp->swb_i.spt.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS, ucSenseBuf); psp->swb_i.spt.TimeOutValue = DEF_TIMEOUT; } } } void set_scsi_pt_cdb(struct sg_pt_base * vp, const unsigned char * cdb, int cdb_len) { struct sg_pt_win32_scsi * psp = vp->implp; if (spt_direct) { if (psp->swb_d.spt.CdbLength > 0) ++psp->in_err; if (cdb_len > (int)sizeof(psp->swb_d.spt.Cdb)) { ++psp->in_err; return; } memcpy(psp->swb_d.spt.Cdb, cdb, cdb_len); psp->swb_d.spt.CdbLength = cdb_len; } else { if (psp->swb_i.spt.CdbLength > 0) ++psp->in_err; if (cdb_len > (int)sizeof(psp->swb_i.spt.Cdb)) { ++psp->in_err; return; } memcpy(psp->swb_i.spt.Cdb, cdb, cdb_len); psp->swb_i.spt.CdbLength = cdb_len; } } void set_scsi_pt_sense(struct sg_pt_base * vp, unsigned char * sense, int sense_len) { struct sg_pt_win32_scsi * psp = vp->implp; if (psp->sensep) ++psp->in_err; memset(sense, 0, sense_len); psp->sensep = sense; psp->sense_len = sense_len; } /* from device */ void set_scsi_pt_data_in(struct sg_pt_base * vp, unsigned char * dxferp, int dxfer_len) { struct sg_pt_win32_scsi * psp = vp->implp; if (psp->dxferp) ++psp->in_err; if (dxfer_len > 0) { psp->dxferp = dxferp; psp->dxfer_len = dxfer_len; if (spt_direct) psp->swb_d.spt.DataIn = SCSI_IOCTL_DATA_IN; else psp->swb_i.spt.DataIn = SCSI_IOCTL_DATA_IN; } } /* to device */ void set_scsi_pt_data_out(struct sg_pt_base * vp, const unsigned char * dxferp, int dxfer_len) { struct sg_pt_win32_scsi * psp = vp->implp; if (psp->dxferp) ++psp->in_err; if (dxfer_len > 0) { psp->dxferp = (unsigned char *)dxferp; psp->dxfer_len = dxfer_len; if (spt_direct) psp->swb_d.spt.DataIn = SCSI_IOCTL_DATA_OUT; else psp->swb_i.spt.DataIn = SCSI_IOCTL_DATA_OUT; } } void set_scsi_pt_packet_id(struct sg_pt_base * vp __attribute__ ((unused)), int pack_id __attribute__ ((unused))) { } void set_scsi_pt_tag(struct sg_pt_base * vp, uint64_t tag __attribute__ ((unused))) { struct sg_pt_win32_scsi * psp = vp->implp; ++psp->in_err; } void set_scsi_pt_task_management(struct sg_pt_base * vp, int tmf_code __attribute__ ((unused))) { struct sg_pt_win32_scsi * psp = vp->implp; ++psp->in_err; } void set_scsi_pt_task_attr(struct sg_pt_base * vp, int attrib __attribute__ ((unused)), int priority __attribute__ ((unused))) { struct sg_pt_win32_scsi * psp = vp->implp; ++psp->in_err; } void set_scsi_pt_flags(struct sg_pt_base * objp, int flags) { /* do nothing, suppress warnings */ objp = objp; flags = flags; } /* Executes SCSI command (or at least forwards it to lower layers) * using direct interface. Clears os_err field prior to active call (whose * result may set it again). */ int do_scsi_pt_direct(struct sg_pt_base * vp, int device_fd, int time_secs, int verbose) { int index = device_fd - WIN32_FDOFFSET; struct sg_pt_win32_scsi * psp = vp->implp; struct sg_pt_handle * shp; BOOL status; ULONG returned; if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; psp->os_err = 0; if (psp->in_err) { if (verbose) fprintf(sg_warnings_strm, "Replicated or unused set_scsi_pt...\n"); return SCSI_PT_DO_BAD_PARAMS; } if (0 == psp->swb_d.spt.CdbLength) { if (verbose) fprintf(sg_warnings_strm, "No command (cdb) given\n"); return SCSI_PT_DO_BAD_PARAMS; } index = device_fd - WIN32_FDOFFSET; if ((index < 0) || (index >= WIN32_FDOFFSET)) { if (verbose) fprintf(sg_warnings_strm, "Bad file descriptor\n"); psp->os_err = ENODEV; return -psp->os_err; } shp = handle_arr + index; if (0 == shp->in_use) { if (verbose) fprintf(sg_warnings_strm, "File descriptor closed??\n"); psp->os_err = ENODEV; return -psp->os_err; } psp->swb_d.spt.Length = sizeof (SCSI_PASS_THROUGH_DIRECT); psp->swb_d.spt.PathId = shp->bus; psp->swb_d.spt.TargetId = shp->target; psp->swb_d.spt.Lun = shp->lun; psp->swb_d.spt.TimeOutValue = time_secs; psp->swb_d.spt.DataTransferLength = psp->dxfer_len; if (verbose > 4) { fprintf(stderr, " spt_direct, adapter: %s Length=%d ScsiStatus=%d " "PathId=%d TargetId=%d Lun=%d\n", shp->adapter, (int)psp->swb_d.spt.Length, (int)psp->swb_d.spt.ScsiStatus, (int)psp->swb_d.spt.PathId, (int)psp->swb_d.spt.TargetId, (int)psp->swb_d.spt.Lun); fprintf(stderr, " CdbLength=%d SenseInfoLength=%d DataIn=%d " "DataTransferLength=%lu\n", (int)psp->swb_d.spt.CdbLength, (int)psp->swb_d.spt.SenseInfoLength, (int)psp->swb_d.spt.DataIn, psp->swb_d.spt.DataTransferLength); fprintf(stderr, " TimeOutValue=%lu SenseInfoOffset=%lu\n", psp->swb_d.spt.TimeOutValue, psp->swb_d.spt.SenseInfoOffset); } psp->swb_d.spt.DataBuffer = psp->dxferp; status = DeviceIoControl(shp->fh, IOCTL_SCSI_PASS_THROUGH_DIRECT, &psp->swb_d, sizeof(psp->swb_d), &psp->swb_d, sizeof(psp->swb_d), &returned, NULL); if (! status) { psp->transport_err = GetLastError(); if (verbose) fprintf(sg_warnings_strm, "Windows DeviceIoControl error=%d\n", psp->transport_err); psp->os_err = EIO; return 0; /* let app find transport error */ } psp->scsi_status = psp->swb_d.spt.ScsiStatus; if ((SAM_STAT_CHECK_CONDITION == psp->scsi_status) || (SAM_STAT_COMMAND_TERMINATED == psp->scsi_status)) memcpy(psp->sensep, psp->swb_d.ucSenseBuf, psp->sense_len); else psp->sense_len = 0; psp->sense_resid = 0; if ((psp->dxfer_len > 0) && (psp->swb_d.spt.DataTransferLength > 0)) psp->resid = psp->dxfer_len - psp->swb_d.spt.DataTransferLength; else psp->resid = 0; return 0; } /* Executes SCSI command (or at least forwards it to lower layers) using * indirect interface. Clears os_err field prior to active call (whose * result may set it again). */ static int do_scsi_pt_indirect(struct sg_pt_base * vp, int device_fd, int time_secs, int verbose) { int index = device_fd - WIN32_FDOFFSET; struct sg_pt_win32_scsi * psp = vp->implp; struct sg_pt_handle * shp; BOOL status; ULONG returned; if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; psp->os_err = 0; if (psp->in_err) { if (verbose) fprintf(sg_warnings_strm, "Replicated or unused " "set_scsi_pt...\n"); return SCSI_PT_DO_BAD_PARAMS; } if (0 == psp->swb_i.spt.CdbLength) { if (verbose) fprintf(sg_warnings_strm, "No command (cdb) given\n"); return SCSI_PT_DO_BAD_PARAMS; } index = device_fd - WIN32_FDOFFSET; if ((index < 0) || (index >= WIN32_FDOFFSET)) { if (verbose) fprintf(sg_warnings_strm, "Bad file descriptor\n"); psp->os_err = ENODEV; return -psp->os_err; } shp = handle_arr + index; if (0 == shp->in_use) { if (verbose) fprintf(sg_warnings_strm, "File descriptor closed??\n"); psp->os_err = ENODEV; return -psp->os_err; } if (psp->dxfer_len > (int)sizeof(psp->swb_i.ucDataBuf)) { int extra = psp->dxfer_len - (int)sizeof(psp->swb_i.ucDataBuf); struct sg_pt_win32_scsi * epsp; if (verbose > 4) fprintf(sg_warnings_strm, "spt_indirect: dxfer_len (%d) too " "large for initial data\n buffer (%d bytes), try " "enlarging\n", psp->dxfer_len, sizeof(psp->swb_i.ucDataBuf)); epsp = (struct sg_pt_win32_scsi *) calloc(sizeof(struct sg_pt_win32_scsi) + extra, 1); if (NULL == epsp) { fprintf(sg_warnings_strm, "do_scsi_pt: failed to enlarge data " "buffer to %d bytes\n", psp->dxfer_len); psp->os_err = ENOMEM; return -psp->os_err; } memcpy(epsp, psp, sizeof(struct sg_pt_win32_scsi)); free(psp); vp->implp = epsp; psp = epsp; } psp->swb_i.spt.Length = sizeof (SCSI_PASS_THROUGH); psp->swb_i.spt.DataBufferOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS, ucDataBuf); psp->swb_i.spt.PathId = shp->bus; psp->swb_i.spt.TargetId = shp->target; psp->swb_i.spt.Lun = shp->lun; psp->swb_i.spt.TimeOutValue = time_secs; psp->swb_i.spt.DataTransferLength = psp->dxfer_len; if (verbose > 4) { fprintf(stderr, " spt_indirect, adapter: %s Length=%d ScsiStatus=%d " "PathId=%d TargetId=%d Lun=%d\n", shp->adapter, (int)psp->swb_i.spt.Length, (int)psp->swb_i.spt.ScsiStatus, (int)psp->swb_i.spt.PathId, (int)psp->swb_i.spt.TargetId, (int)psp->swb_i.spt.Lun); fprintf(stderr, " CdbLength=%d SenseInfoLength=%d DataIn=%d " "DataTransferLength=%lu\n", (int)psp->swb_i.spt.CdbLength, (int)psp->swb_i.spt.SenseInfoLength, (int)psp->swb_i.spt.DataIn, psp->swb_i.spt.DataTransferLength); fprintf(stderr, " TimeOutValue=%lu DataBufferOffset=%lu " "SenseInfoOffset=%lu\n", psp->swb_i.spt.TimeOutValue, psp->swb_i.spt.DataBufferOffset, psp->swb_i.spt.SenseInfoOffset); } if ((psp->dxfer_len > 0) && (SCSI_IOCTL_DATA_OUT == psp->swb_i.spt.DataIn)) memcpy(psp->swb_i.ucDataBuf, psp->dxferp, psp->dxfer_len); status = DeviceIoControl(shp->fh, IOCTL_SCSI_PASS_THROUGH, &psp->swb_i, sizeof(psp->swb_i), &psp->swb_i, sizeof(psp->swb_i), &returned, NULL); if (! status) { psp->transport_err = GetLastError(); if (verbose) fprintf(sg_warnings_strm, "Windows DeviceIoControl error=%d\n", psp->transport_err); psp->os_err = EIO; return 0; /* let app find transport error */ } if ((psp->dxfer_len > 0) && (SCSI_IOCTL_DATA_IN == psp->swb_i.spt.DataIn)) memcpy(psp->dxferp, psp->swb_i.ucDataBuf, psp->dxfer_len); psp->scsi_status = psp->swb_i.spt.ScsiStatus; if ((SAM_STAT_CHECK_CONDITION == psp->scsi_status) || (SAM_STAT_COMMAND_TERMINATED == psp->scsi_status)) memcpy(psp->sensep, psp->swb_i.ucSenseBuf, psp->sense_len); else psp->sense_len = 0; psp->sense_resid = 0; if ((psp->dxfer_len > 0) && (psp->swb_i.spt.DataTransferLength > 0)) psp->resid = psp->dxfer_len - psp->swb_i.spt.DataTransferLength; else psp->resid = 0; return 0; } /* Executes SCSI command (or at least forwards it to lower layers). * Clears os_err field prior to active call (whose result may set it * again). */ int do_scsi_pt(struct sg_pt_base * vp, int device_fd, int time_secs, int verbose) { if (spt_direct) return do_scsi_pt_direct(vp, device_fd, time_secs, verbose); else return do_scsi_pt_indirect(vp, device_fd, time_secs, verbose); } int get_scsi_pt_result_category(const struct sg_pt_base * vp) { const struct sg_pt_win32_scsi * psp = vp->implp; if (psp->transport_err) /* give transport error highest priority */ return SCSI_PT_RESULT_TRANSPORT_ERR; else if (psp->os_err) return SCSI_PT_RESULT_OS_ERR; else if ((SAM_STAT_CHECK_CONDITION == psp->scsi_status) || (SAM_STAT_COMMAND_TERMINATED == psp->scsi_status)) return SCSI_PT_RESULT_SENSE; else if (psp->scsi_status) return SCSI_PT_RESULT_STATUS; else return SCSI_PT_RESULT_GOOD; } int get_scsi_pt_resid(const struct sg_pt_base * vp) { const struct sg_pt_win32_scsi * psp = vp->implp; return psp->resid; } int get_scsi_pt_status_response(const struct sg_pt_base * vp) { const struct sg_pt_win32_scsi * psp = vp->implp; return psp->scsi_status; } int get_scsi_pt_sense_len(const struct sg_pt_base * vp) { const struct sg_pt_win32_scsi * psp = vp->implp; int len; len = psp->sense_len - psp->sense_resid; return (len > 0) ? len : 0; } int get_scsi_pt_duration_ms(const struct sg_pt_base * vp __attribute__ ((unused))) { // const struct sg_pt_freebsd_scsi * psp = vp->implp; return -1; } int get_scsi_pt_transport_err(const struct sg_pt_base * vp) { const struct sg_pt_win32_scsi * psp = vp->implp; return psp->transport_err; } int get_scsi_pt_os_err(const struct sg_pt_base * vp) { const struct sg_pt_win32_scsi * psp = vp->implp; return psp->os_err; } char * get_scsi_pt_transport_err_str(const struct sg_pt_base * vp, int max_b_len, char * b) { struct sg_pt_win32_scsi * psp = (struct sg_pt_win32_scsi *)vp->implp; LPVOID lpMsgBuf; int k, num, ch; if (max_b_len < 2) { if (1 == max_b_len) b[0] = '\0'; return b; } memset(b, 0, max_b_len); FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, psp->transport_err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL ); num = lstrlen((LPCTSTR)lpMsgBuf); if (num < 1) return b; num = (num < max_b_len) ? num : (max_b_len - 1); for (k = 0; k < num; ++k) { ch = *((LPCTSTR)lpMsgBuf + k); if ((ch >= 0x0) && (ch < 0x7f)) b[k] = ch & 0x7f; else b[k] = '?'; } return b; } char * get_scsi_pt_os_err_str(const struct sg_pt_base * vp, int max_b_len, char * b) { const struct sg_pt_win32_scsi * psp = vp->implp; const char * cp; cp = safe_strerror(psp->os_err); strncpy(b, cp, max_b_len); if ((int)strlen(cp) >= max_b_len) b[max_b_len - 1] = '\0'; return b; } ddpt-0.92/lib/sg_pt_linux.c0000644000175000017500000006630011435514071014646 0ustar douggdougg/* * Copyright (c) 2005-2010 Douglas Gilbert. * All rights reserved. * Use of this source code is governed by a BSD-style * license that can be found in the BSD_LICENSE file. */ /* sg_pt_linux version 1.15 20100827 */ #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sg_pt.h" #include "sg_lib.h" #include "sg_linux_inc.h" #define DEF_TIMEOUT 60000 /* 60,000 millisecs (60 seconds) */ static const char * linux_host_bytes[] = { "DID_OK", "DID_NO_CONNECT", "DID_BUS_BUSY", "DID_TIME_OUT", "DID_BAD_TARGET", "DID_ABORT", "DID_PARITY", "DID_ERROR", "DID_RESET", "DID_BAD_INTR", "DID_PASSTHROUGH", "DID_SOFT_ERROR", "DID_IMM_RETRY", "DID_REQUEUE" }; #define LINUX_HOST_BYTES_SZ \ (int)(sizeof(linux_host_bytes) / sizeof(linux_host_bytes[0])) static const char * linux_driver_bytes[] = { "DRIVER_OK", "DRIVER_BUSY", "DRIVER_SOFT", "DRIVER_MEDIA", "DRIVER_ERROR", "DRIVER_INVALID", "DRIVER_TIMEOUT", "DRIVER_HARD", "DRIVER_SENSE" }; #define LINUX_DRIVER_BYTES_SZ \ (int)(sizeof(linux_driver_bytes) / sizeof(linux_driver_bytes[0])) static const char * linux_driver_suggests[] = { "SUGGEST_OK", "SUGGEST_RETRY", "SUGGEST_ABORT", "SUGGEST_REMAP", "SUGGEST_DIE", "UNKNOWN","UNKNOWN","UNKNOWN", "SUGGEST_SENSE" }; #define LINUX_DRIVER_SUGGESTS_SZ \ (int)(sizeof(linux_driver_suggests) / sizeof(linux_driver_suggests[0])) /* * These defines are for constants that should be visible in the * /usr/include/scsi directory (brought in by sg_linux_inc.h). * Redefined and aliased here to decouple this code from * sg_io_linux.h */ #ifndef DRIVER_MASK #define DRIVER_MASK 0x0f #endif #ifndef SUGGEST_MASK #define SUGGEST_MASK 0xf0 #endif #ifndef DRIVER_SENSE #define DRIVER_SENSE 0x08 #endif #define SG_LIB_DRIVER_MASK DRIVER_MASK #define SG_LIB_SUGGEST_MASK SUGGEST_MASK #define SG_LIB_DRIVER_SENSE DRIVER_SENSE // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< #if defined(IGNORE_LINUX_BSG) || ! defined(HAVE_LINUX_BSG_H) /* * sg(v3) via SG_IO ioctl on a sg node or other node that accepts that ioctl. * Decision has been made at compile time because either: * a) no /usr/include/linux/bsg.h header file was found, or * b) the builder gave the '--enable-no-linux-bsg' option to ./configure */ struct sg_pt_linux_scsi { struct sg_io_hdr io_hdr; int in_err; int os_err; }; struct sg_pt_base { struct sg_pt_linux_scsi impl; }; /* Returns >= 0 if successful. If error in Unix returns negated errno. */ int scsi_pt_open_device(const char * device_name, int read_only, int verbose) { int oflags = O_NONBLOCK; oflags |= (read_only ? O_RDONLY : O_RDWR); return scsi_pt_open_flags(device_name, oflags, verbose); } /* Similar to scsi_pt_open_device() but takes Unix style open flags OR-ed */ /* together. The 'flags' argument is advisory and may be ignored. */ /* Returns >= 0 if successful, otherwise returns negated errno. */ int scsi_pt_open_flags(const char * device_name, int flags, int verbose) { int fd; if (verbose > 1) { if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; fprintf(sg_warnings_strm, "open %s with flags=0x%x\n", device_name, flags); } fd = open(device_name, flags); if (fd < 0) fd = -errno; return fd; } /* Returns 0 if successful. If error in Unix returns negated errno. */ int scsi_pt_close_device(int device_fd) { int res; res = close(device_fd); if (res < 0) res = -errno; return res; } struct sg_pt_base * construct_scsi_pt_obj() { struct sg_pt_linux_scsi * ptp; ptp = (struct sg_pt_linux_scsi *) calloc(1, sizeof(struct sg_pt_linux_scsi)); if (ptp) { ptp->io_hdr.interface_id = 'S'; ptp->io_hdr.dxfer_direction = SG_DXFER_NONE; } return (struct sg_pt_base *)ptp; } void destruct_scsi_pt_obj(struct sg_pt_base * vp) { struct sg_pt_linux_scsi * ptp = &vp->impl; if (ptp) free(ptp); } void clear_scsi_pt_obj(struct sg_pt_base * vp) { struct sg_pt_linux_scsi * ptp = &vp->impl; if (ptp) { memset(ptp, 0, sizeof(struct sg_pt_linux_scsi)); ptp->io_hdr.interface_id = 'S'; ptp->io_hdr.dxfer_direction = SG_DXFER_NONE; } } void set_scsi_pt_cdb(struct sg_pt_base * vp, const unsigned char * cdb, int cdb_len) { struct sg_pt_linux_scsi * ptp = &vp->impl; if (ptp->io_hdr.cmdp) ++ptp->in_err; ptp->io_hdr.cmdp = (unsigned char *)cdb; ptp->io_hdr.cmd_len = cdb_len; } void set_scsi_pt_sense(struct sg_pt_base * vp, unsigned char * sense, int max_sense_len) { struct sg_pt_linux_scsi * ptp = &vp->impl; if (ptp->io_hdr.sbp) ++ptp->in_err; memset(sense, 0, max_sense_len); ptp->io_hdr.sbp = sense; ptp->io_hdr.mx_sb_len = max_sense_len; } /* Setup for data transfer from device */ void set_scsi_pt_data_in(struct sg_pt_base * vp, unsigned char * dxferp, int dxfer_len) { struct sg_pt_linux_scsi * ptp = &vp->impl; if (ptp->io_hdr.dxferp) ++ptp->in_err; if (dxfer_len > 0) { ptp->io_hdr.dxferp = dxferp; ptp->io_hdr.dxfer_len = dxfer_len; ptp->io_hdr.dxfer_direction = SG_DXFER_FROM_DEV; } } /* Setup for data transfer toward device */ void set_scsi_pt_data_out(struct sg_pt_base * vp, const unsigned char * dxferp, int dxfer_len) { struct sg_pt_linux_scsi * ptp = &vp->impl; if (ptp->io_hdr.dxferp) ++ptp->in_err; if (dxfer_len > 0) { ptp->io_hdr.dxferp = (unsigned char *)dxferp; ptp->io_hdr.dxfer_len = dxfer_len; ptp->io_hdr.dxfer_direction = SG_DXFER_TO_DEV; } } void set_scsi_pt_packet_id(struct sg_pt_base * vp, int pack_id) { struct sg_pt_linux_scsi * ptp = &vp->impl; ptp->io_hdr.pack_id = pack_id; } void set_scsi_pt_tag(struct sg_pt_base * vp, uint64_t tag) { struct sg_pt_linux_scsi * ptp = &vp->impl; ++ptp->in_err; tag = tag; /* dummy to silence compiler */ } /* Note that task management function codes are transport specific */ void set_scsi_pt_task_management(struct sg_pt_base * vp, int tmf_code) { struct sg_pt_linux_scsi * ptp = &vp->impl; ++ptp->in_err; tmf_code = tmf_code; /* dummy to silence compiler */ } void set_scsi_pt_task_attr(struct sg_pt_base * vp, int attribute, int priority) { struct sg_pt_linux_scsi * ptp = &vp->impl; ++ptp->in_err; attribute = attribute; /* dummy to silence compiler */ priority = priority; /* dummy to silence compiler */ } #ifndef SG_FLAG_Q_AT_TAIL #define SG_FLAG_Q_AT_TAIL 0x10 #endif #ifndef SG_FLAG_Q_AT_HEAD #define SG_FLAG_Q_AT_HEAD 0x20 #endif void set_scsi_pt_flags(struct sg_pt_base * vp, int flags) { struct sg_pt_linux_scsi * ptp = &vp->impl; /* default action of SG (v3) is QUEUE_AT_HEAD */ /* default action of block layer SG_IO ioctl is QUEUE_AT_TAIL */ if (SCSI_PT_FLAGS_QUEUE_AT_TAIL & flags) { ptp->io_hdr.flags |= SG_FLAG_Q_AT_TAIL; ptp->io_hdr.flags &= ~SG_FLAG_Q_AT_HEAD; } if (SCSI_PT_FLAGS_QUEUE_AT_HEAD & flags) { ptp->io_hdr.flags |= SG_FLAG_Q_AT_HEAD; ptp->io_hdr.flags &= ~SG_FLAG_Q_AT_TAIL; } } /* Executes SCSI command (or at least forwards it to lower layers). * Clears os_err field prior to active call (whose result may set it * again). */ int do_scsi_pt(struct sg_pt_base * vp, int fd, int time_secs, int verbose) { struct sg_pt_linux_scsi * ptp = &vp->impl; if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; ptp->os_err = 0; if (ptp->in_err) { if (verbose) fprintf(sg_warnings_strm, "Replicated or unused set_scsi_pt... " "functions\n"); return SCSI_PT_DO_BAD_PARAMS; } if (NULL == ptp->io_hdr.cmdp) { if (verbose) fprintf(sg_warnings_strm, "No SCSI command (cdb) given\n"); return SCSI_PT_DO_BAD_PARAMS; } /* io_hdr.timeout is in milliseconds */ ptp->io_hdr.timeout = ((time_secs > 0) ? (time_secs * 1000) : DEF_TIMEOUT); if (ptp->io_hdr.sbp && (ptp->io_hdr.mx_sb_len > 0)) memset(ptp->io_hdr.sbp, 0, ptp->io_hdr.mx_sb_len); if (ioctl(fd, SG_IO, &ptp->io_hdr) < 0) { ptp->os_err = errno; if (verbose > 1) fprintf(sg_warnings_strm, "ioctl(SG_IO) failed: %s (errno=%d)\n", strerror(ptp->os_err), ptp->os_err); return -ptp->os_err; } return 0; } int get_scsi_pt_result_category(const struct sg_pt_base * vp) { const struct sg_pt_linux_scsi * ptp = &vp->impl; int dr_st = ptp->io_hdr.driver_status & SG_LIB_DRIVER_MASK; int scsi_st = ptp->io_hdr.status & 0x7e; if (ptp->os_err) return SCSI_PT_RESULT_OS_ERR; else if (ptp->io_hdr.host_status) return SCSI_PT_RESULT_TRANSPORT_ERR; else if (dr_st && (SG_LIB_DRIVER_SENSE != dr_st)) return SCSI_PT_RESULT_TRANSPORT_ERR; else if ((SG_LIB_DRIVER_SENSE == dr_st) || (SAM_STAT_CHECK_CONDITION == scsi_st) || (SAM_STAT_COMMAND_TERMINATED == scsi_st)) return SCSI_PT_RESULT_SENSE; else if (scsi_st) return SCSI_PT_RESULT_STATUS; else return SCSI_PT_RESULT_GOOD; } int get_scsi_pt_resid(const struct sg_pt_base * vp) { const struct sg_pt_linux_scsi * ptp = &vp->impl; return ptp->io_hdr.resid; } int get_scsi_pt_status_response(const struct sg_pt_base * vp) { const struct sg_pt_linux_scsi * ptp = &vp->impl; return ptp->io_hdr.status; } int get_scsi_pt_sense_len(const struct sg_pt_base * vp) { const struct sg_pt_linux_scsi * ptp = &vp->impl; return ptp->io_hdr.sb_len_wr; } int get_scsi_pt_duration_ms(const struct sg_pt_base * vp) { const struct sg_pt_linux_scsi * ptp = &vp->impl; return ptp->io_hdr.duration; } int get_scsi_pt_transport_err(const struct sg_pt_base * vp) { const struct sg_pt_linux_scsi * ptp = &vp->impl; return (ptp->io_hdr.host_status << 8) + ptp->io_hdr.driver_status; } int get_scsi_pt_os_err(const struct sg_pt_base * vp) { const struct sg_pt_linux_scsi * ptp = &vp->impl; return ptp->os_err; } char * get_scsi_pt_transport_err_str(const struct sg_pt_base * vp, int max_b_len, char * b) { const struct sg_pt_linux_scsi * ptp = &vp->impl; int ds = ptp->io_hdr.driver_status; int hs = ptp->io_hdr.host_status; int n, m; char * cp = b; int driv, sugg; const char * driv_cp = "invalid"; const char * sugg_cp = "invalid"; m = max_b_len; n = 0; if (hs) { if ((hs < 0) || (hs >= LINUX_HOST_BYTES_SZ)) n = snprintf(cp, m, "Host_status=0x%02x is invalid\n", hs); else n = snprintf(cp, m, "Host_status=0x%02x [%s]\n", hs, linux_host_bytes[hs]); } m -= n; if (m < 1) { b[max_b_len - 1] = '\0'; return b; } cp += n; driv = ds & SG_LIB_DRIVER_MASK; if (driv < LINUX_DRIVER_BYTES_SZ) driv_cp = linux_driver_bytes[driv]; sugg = (ds & SG_LIB_SUGGEST_MASK) >> 4; if (sugg < LINUX_DRIVER_SUGGESTS_SZ) sugg_cp = linux_driver_suggests[sugg]; n = snprintf(cp, m, "Driver_status=0x%02x [%s, %s]\n", ds, driv_cp, sugg_cp); m -= n; if (m < 1) b[max_b_len - 1] = '\0'; return b; } char * get_scsi_pt_os_err_str(const struct sg_pt_base * vp, int max_b_len, char * b) { const struct sg_pt_linux_scsi * ptp = &vp->impl; const char * cp; cp = safe_strerror(ptp->os_err); strncpy(b, cp, max_b_len); if ((int)strlen(cp) >= max_b_len) b[max_b_len - 1] = '\0'; return b; } // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< #else /* allow for runtime selection of sg v3 or v4 (via bsg) */ // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< /* * So bsg is an option. Thus we make a runtime decision. If all the following * are true we use sg v4 which is only currently supported on bsg device * nodes: * a) there is a bsg entry in the /proc/devices file * b) the device node given to scsi_pt_open() is a char device * c) the char major number of the device node given to scsi_pt_open() * matches the char major number of the bsg entry in /proc/devices * Otherwise the sg v3 interface is used. * * Note that in either case we prepare the data in a sg v4 structure. If * the runtime tests indicate that the v3 interface is needed then * do_scsi_pt_v3() transfers the input data into a v3 structure and * then the output data is transferred back into a sg v4 structure. * That implementation detail could change in the future. */ #include #include #ifdef HAVE_LINUX_KDEV_T_H #include #endif struct sg_pt_linux_scsi { struct sg_io_v4 io_hdr; /* use v4 header as it is more general */ int in_err; int os_err; unsigned char tmf_request[4]; }; struct sg_pt_base { struct sg_pt_linux_scsi impl; }; static int bsg_major_checked = 0; static int bsg_major = 0; static void find_bsg_major(int verbose) { const char * proc_devices = "/proc/devices"; FILE *fp; char a[128]; char b[128]; char * cp; int n; if (NULL == (fp = fopen(proc_devices, "r"))) { if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; if (verbose) fprintf(sg_warnings_strm, "fopen %s failed: %s\n", proc_devices, strerror(errno)); return; } while ((cp = fgets(b, sizeof(b), fp))) { if ((1 == sscanf(b, "%s", a)) && (0 == memcmp(a, "Character", 9))) break; } while (cp && (cp = fgets(b, sizeof(b), fp))) { if (2 == sscanf(b, "%d %s", &n, a)) { if (0 == strcmp("bsg", a)) { bsg_major = n; break; } } else break; } if (verbose > 3) { if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; if (cp) fprintf(sg_warnings_strm, "found bsg_major=%d\n", bsg_major); else fprintf(sg_warnings_strm, "found no bsg char device in %s\n", proc_devices); } fclose(fp); } /* Returns >= 0 if successful. If error in Unix returns negated errno. */ int scsi_pt_open_device(const char * device_name, int read_only, int verbose) { int oflags = O_NONBLOCK; oflags |= (read_only ? O_RDONLY : O_RDWR); return scsi_pt_open_flags(device_name, oflags, verbose); } /* Similar to scsi_pt_open_device() but takes Unix style open flags OR-ed */ /* together. The 'flags' argument is advisory and may be ignored. */ /* Returns >= 0 if successful, otherwise returns negated errno. */ int scsi_pt_open_flags(const char * device_name, int flags, int verbose) { int fd; if (! bsg_major_checked) { bsg_major_checked = 1; find_bsg_major(verbose); } if (verbose > 1) { if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; fprintf(sg_warnings_strm, "open %s with flags=0x%x\n", device_name, flags); } fd = open(device_name, flags); if (fd < 0) fd = -errno; return fd; } /* Returns 0 if successful. If error in Unix returns negated errno. */ int scsi_pt_close_device(int device_fd) { int res; res = close(device_fd); if (res < 0) res = -errno; return res; } struct sg_pt_base * construct_scsi_pt_obj() { struct sg_pt_linux_scsi * ptp; ptp = (struct sg_pt_linux_scsi *) calloc(1, sizeof(struct sg_pt_linux_scsi)); if (ptp) { ptp->io_hdr.guard = 'Q'; #ifdef BSG_PROTOCOL_SCSI ptp->io_hdr.protocol = BSG_PROTOCOL_SCSI; #endif #ifdef BSG_SUB_PROTOCOL_SCSI_CMD ptp->io_hdr.subprotocol = BSG_SUB_PROTOCOL_SCSI_CMD; #endif } return (struct sg_pt_base *)ptp; } void destruct_scsi_pt_obj(struct sg_pt_base * vp) { struct sg_pt_linux_scsi * ptp = &vp->impl; if (ptp) free(ptp); } void clear_scsi_pt_obj(struct sg_pt_base * vp) { struct sg_pt_linux_scsi * ptp = &vp->impl; if (ptp) { memset(ptp, 0, sizeof(struct sg_pt_linux_scsi)); ptp->io_hdr.guard = 'Q'; #ifdef BSG_PROTOCOL_SCSI ptp->io_hdr.protocol = BSG_PROTOCOL_SCSI; #endif #ifdef BSG_SUB_PROTOCOL_SCSI_CMD ptp->io_hdr.subprotocol = BSG_SUB_PROTOCOL_SCSI_CMD; #endif } } void set_scsi_pt_cdb(struct sg_pt_base * vp, const unsigned char * cdb, int cdb_len) { struct sg_pt_linux_scsi * ptp = &vp->impl; if (ptp->io_hdr.request) ++ptp->in_err; /* C99 has intptr_t instead of long */ ptp->io_hdr.request = (__u64)(long)cdb; ptp->io_hdr.request_len = cdb_len; } void set_scsi_pt_sense(struct sg_pt_base * vp, unsigned char * sense, int max_sense_len) { struct sg_pt_linux_scsi * ptp = &vp->impl; if (ptp->io_hdr.response) ++ptp->in_err; memset(sense, 0, max_sense_len); ptp->io_hdr.response = (__u64)(long)sense; ptp->io_hdr.max_response_len = max_sense_len; } /* Setup for data transfer from device */ void set_scsi_pt_data_in(struct sg_pt_base * vp, unsigned char * dxferp, int dxfer_len) { struct sg_pt_linux_scsi * ptp = &vp->impl; if (ptp->io_hdr.din_xferp) ++ptp->in_err; if (dxfer_len > 0) { ptp->io_hdr.din_xferp = (__u64)(long)dxferp; ptp->io_hdr.din_xfer_len = dxfer_len; } } /* Setup for data transfer toward device */ void set_scsi_pt_data_out(struct sg_pt_base * vp, const unsigned char * dxferp, int dxfer_len) { struct sg_pt_linux_scsi * ptp = &vp->impl; if (ptp->io_hdr.dout_xferp) ++ptp->in_err; if (dxfer_len > 0) { ptp->io_hdr.dout_xferp = (__u64)(long)dxferp; ptp->io_hdr.dout_xfer_len = dxfer_len; } } void set_scsi_pt_packet_id(struct sg_pt_base * vp, int pack_id) { struct sg_pt_linux_scsi * ptp = &vp->impl; ptp->io_hdr.spare_in = pack_id; } void set_scsi_pt_tag(struct sg_pt_base * vp, uint64_t tag) { struct sg_pt_linux_scsi * ptp = &vp->impl; ptp->io_hdr.request_tag = tag; } /* Note that task management function codes are transport specific */ void set_scsi_pt_task_management(struct sg_pt_base * vp, int tmf_code) { struct sg_pt_linux_scsi * ptp = &vp->impl; ptp->io_hdr.subprotocol = 1; /* SCSI task management function */ ptp->tmf_request[0] = (unsigned char)tmf_code; /* assume it fits */ ptp->io_hdr.request = (__u64)(long)(&(ptp->tmf_request[0])); ptp->io_hdr.request_len = 1; } void set_scsi_pt_task_attr(struct sg_pt_base * vp, int attribute, int priority) { struct sg_pt_linux_scsi * ptp = &vp->impl; ptp->io_hdr.request_attr = attribute; ptp->io_hdr.request_priority = priority; } #ifndef BSG_FLAG_Q_AT_TAIL #define BSG_FLAG_Q_AT_TAIL 0x10 #endif void set_scsi_pt_flags(struct sg_pt_base * vp, int flags) { struct sg_pt_linux_scsi * ptp = &vp->impl; /* default action of bsg (sg v4) is QUEUE_AT_HEAD */ if (SCSI_PT_FLAGS_QUEUE_AT_TAIL & flags) ptp->io_hdr.flags |= BSG_FLAG_Q_AT_TAIL; if (SCSI_PT_FLAGS_QUEUE_AT_HEAD & flags) ptp->io_hdr.flags &= ~BSG_FLAG_Q_AT_TAIL; } /* N.B. Returns din_resid and ignores dout_resid */ int get_scsi_pt_resid(const struct sg_pt_base * vp) { const struct sg_pt_linux_scsi * ptp = &vp->impl; return ptp->io_hdr.din_resid; } int get_scsi_pt_status_response(const struct sg_pt_base * vp) { const struct sg_pt_linux_scsi * ptp = &vp->impl; return ptp->io_hdr.device_status; } int get_scsi_pt_sense_len(const struct sg_pt_base * vp) { const struct sg_pt_linux_scsi * ptp = &vp->impl; return ptp->io_hdr.response_len; } int get_scsi_pt_duration_ms(const struct sg_pt_base * vp) { const struct sg_pt_linux_scsi * ptp = &vp->impl; return ptp->io_hdr.duration; } int get_scsi_pt_transport_err(const struct sg_pt_base * vp) { const struct sg_pt_linux_scsi * ptp = &vp->impl; return ptp->io_hdr.transport_status; } /* Combine driver and transport (called "host" in linux kernel) statuses */ char * get_scsi_pt_transport_err_str(const struct sg_pt_base * vp, int max_b_len, char * b) { const struct sg_pt_linux_scsi * ptp = &vp->impl; int ds = ptp->io_hdr.driver_status; int hs = ptp->io_hdr.transport_status; int n, m; char * cp = b; int driv, sugg; const char * driv_cp = "invalid"; const char * sugg_cp = "invalid"; m = max_b_len; n = 0; if (hs) { if ((hs < 0) || (hs >= LINUX_HOST_BYTES_SZ)) n = snprintf(cp, m, "Host_status=0x%02x is invalid\n", hs); else n = snprintf(cp, m, "Host_status=0x%02x [%s]\n", hs, linux_host_bytes[hs]); } m -= n; if (m < 1) { b[max_b_len - 1] = '\0'; return b; } cp += n; driv = ds & SG_LIB_DRIVER_MASK; if (driv < LINUX_DRIVER_BYTES_SZ) driv_cp = linux_driver_bytes[driv]; sugg = (ds & SG_LIB_SUGGEST_MASK) >> 4; if (sugg < LINUX_DRIVER_SUGGESTS_SZ) sugg_cp = linux_driver_suggests[sugg]; n = snprintf(cp, m, "Driver_status=0x%02x [%s, %s]\n", ds, driv_cp, sugg_cp); m -= n; if (m < 1) b[max_b_len - 1] = '\0'; return b; } int get_scsi_pt_result_category(const struct sg_pt_base * vp) { const struct sg_pt_linux_scsi * ptp = &vp->impl; int dr_st = ptp->io_hdr.driver_status & SG_LIB_DRIVER_MASK; int scsi_st = ptp->io_hdr.device_status & 0x7e; if (ptp->os_err) return SCSI_PT_RESULT_OS_ERR; else if (ptp->io_hdr.transport_status) return SCSI_PT_RESULT_TRANSPORT_ERR; else if (dr_st && (SG_LIB_DRIVER_SENSE != dr_st)) return SCSI_PT_RESULT_TRANSPORT_ERR; else if ((SG_LIB_DRIVER_SENSE == dr_st) || (SAM_STAT_CHECK_CONDITION == scsi_st) || (SAM_STAT_COMMAND_TERMINATED == scsi_st)) return SCSI_PT_RESULT_SENSE; else if (scsi_st) return SCSI_PT_RESULT_STATUS; else return SCSI_PT_RESULT_GOOD; } int get_scsi_pt_os_err(const struct sg_pt_base * vp) { const struct sg_pt_linux_scsi * ptp = &vp->impl; return ptp->os_err; } char * get_scsi_pt_os_err_str(const struct sg_pt_base * vp, int max_b_len, char * b) { const struct sg_pt_linux_scsi * ptp = &vp->impl; const char * cp; cp = safe_strerror(ptp->os_err); strncpy(b, cp, max_b_len); if ((int)strlen(cp) >= max_b_len) b[max_b_len - 1] = '\0'; return b; } /* Executes SCSI command using sg v3 interface */ static int do_scsi_pt_v3(struct sg_pt_linux_scsi * ptp, int fd, int time_secs, int verbose) { struct sg_io_hdr v3_hdr; memset(&v3_hdr, 0, sizeof(v3_hdr)); /* convert v4 to v3 header */ v3_hdr.interface_id = 'S'; v3_hdr.dxfer_direction = SG_DXFER_NONE; v3_hdr.cmdp = (void *)(long)ptp->io_hdr.request; v3_hdr.cmd_len = (unsigned char)ptp->io_hdr.request_len; if (ptp->io_hdr.din_xfer_len > 0) { if (ptp->io_hdr.dout_xfer_len > 0) { if (verbose) fprintf(sg_warnings_strm, "sgv3 doesn't support bidi\n"); return SCSI_PT_DO_BAD_PARAMS; } v3_hdr.dxferp = (void *)(long)ptp->io_hdr.din_xferp; v3_hdr.dxfer_len = (unsigned int)ptp->io_hdr.din_xfer_len; v3_hdr.dxfer_direction = SG_DXFER_FROM_DEV; } else if (ptp->io_hdr.dout_xfer_len > 0) { v3_hdr.dxferp = (void *)(long)ptp->io_hdr.dout_xferp; v3_hdr.dxfer_len = (unsigned int)ptp->io_hdr.dout_xfer_len; v3_hdr.dxfer_direction = SG_DXFER_TO_DEV; } if (ptp->io_hdr.response && (ptp->io_hdr.max_response_len > 0)) { v3_hdr.sbp = (void *)(long)ptp->io_hdr.response; v3_hdr.mx_sb_len = (unsigned char)ptp->io_hdr.max_response_len; } v3_hdr.pack_id = (int)ptp->io_hdr.spare_in; if (NULL == v3_hdr.cmdp) { if (verbose) fprintf(sg_warnings_strm, "No SCSI command (cdb) given\n"); return SCSI_PT_DO_BAD_PARAMS; } /* io_hdr.timeout is in milliseconds, if greater than zero */ v3_hdr.timeout = ((time_secs > 0) ? (time_secs * 1000) : DEF_TIMEOUT); /* Finally do the v3 SG_IO ioctl */ if (ioctl(fd, SG_IO, &v3_hdr) < 0) { ptp->os_err = errno; if (verbose > 1) fprintf(sg_warnings_strm, "ioctl(SG_IO v3) failed: %s " "(errno=%d)\n", strerror(ptp->os_err), ptp->os_err); return -ptp->os_err; } ptp->io_hdr.device_status = (__u32)v3_hdr.status; ptp->io_hdr.driver_status = (__u32)v3_hdr.driver_status; ptp->io_hdr.transport_status = (__u32)v3_hdr.host_status; ptp->io_hdr.response_len = (__u32)v3_hdr.sb_len_wr; ptp->io_hdr.duration = (__u32)v3_hdr.duration; ptp->io_hdr.din_resid = (__s32)v3_hdr.resid; /* v3_hdr.info not passed back since no mapping defined (yet) */ return 0; } /* Executes SCSI command (or at least forwards it to lower layers). * Clears os_err field prior to active call (whose result may set it * again). */ int do_scsi_pt(struct sg_pt_base * vp, int fd, int time_secs, int verbose) { struct sg_pt_linux_scsi * ptp = &vp->impl; void * p; if (! bsg_major_checked) { bsg_major_checked = 1; find_bsg_major(verbose); } if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; ptp->os_err = 0; if (ptp->in_err) { if (verbose) fprintf(sg_warnings_strm, "Replicated or unused set_scsi_pt... " "functions\n"); return SCSI_PT_DO_BAD_PARAMS; } if (bsg_major <= 0) return do_scsi_pt_v3(ptp, fd, time_secs, verbose); else { struct stat a_stat; if (fstat(fd, &a_stat) < 0) { ptp->os_err = errno; if (verbose > 1) fprintf(sg_warnings_strm, "fstat() failed: %s (errno=%d)\n", strerror(ptp->os_err), ptp->os_err); return -ptp->os_err; } #ifdef HAVE_LINUX_KDEV_T_H if (! S_ISCHR(a_stat.st_mode) || (bsg_major != (int)MAJOR(a_stat.st_rdev))) return do_scsi_pt_v3(ptp, fd, time_secs, verbose); #else if (! S_ISCHR(a_stat.st_mode) || (bsg_major != (int)major(a_stat.st_rdev))) return do_scsi_pt_v3(ptp, fd, time_secs, verbose); #endif } if (! ptp->io_hdr.request) { if (verbose) fprintf(sg_warnings_strm, "No SCSI command (cdb) given (v4)\n"); return SCSI_PT_DO_BAD_PARAMS; } /* io_hdr.timeout is in milliseconds */ ptp->io_hdr.timeout = ((time_secs > 0) ? (time_secs * 1000) : DEF_TIMEOUT); if (ptp->io_hdr.response && (ptp->io_hdr.max_response_len > 0)) { p = (void *)(long)ptp->io_hdr.response; memset(p, 0, ptp->io_hdr.max_response_len); } if (ioctl(fd, SG_IO, &ptp->io_hdr) < 0) { ptp->os_err = errno; if (verbose > 1) fprintf(sg_warnings_strm, "ioctl(SG_IO v4) failed: %s " "(errno=%d)\n", strerror(ptp->os_err), ptp->os_err); return -ptp->os_err; } return 0; } #endif // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ddpt-0.92/lib/BSD_LICENSE0000644000175000017500000000275211346470114013645 0ustar douggdougg/* * Copyright (c) 1999-2010 Douglas Gilbert. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ ddpt-0.92/lib/sg_lib_data.c0000644000175000017500000014432011477045013014543 0ustar douggdougg/* * Copyright (c) 2007-2010 Douglas Gilbert. * All rights reserved. * Use of this source code is governed by a BSD-style * license that can be found in the BSD_LICENSE file. */ #include #include "sg_lib.h" #include "sg_lib_data.h" #ifdef HAVE_CONFIG_H #include "config.h" #endif const char * sg_lib_version_str = "1.65 20101205"; /* spc-4 rev 28 */ struct sg_lib_value_name_t sg_lib_normal_opcodes[] = { {0, 0, "Test Unit Ready"}, {0x1, 0, "Rezero Unit"}, {0x1, PDT_TAPE, "Rewind"}, {0x3, 0, "Request Sense"}, {0x4, 0, "Format Unit"}, {0x4, PDT_TAPE, "Format medium"}, {0x4, PDT_PRINTER, "Format"}, {0x5, 0, "Read Block Limits"}, {0x7, 0, "Reassign Blocks"}, {0x7, PDT_MCHANGER, "Initialize element status"}, {0x8, 0, "Read(6)"}, {0x8, PDT_PROCESSOR, "Receive"}, {0xa, 0, "Write(6)"}, {0xa, PDT_PRINTER, "Print"}, {0xa, PDT_PROCESSOR, "Send"}, {0xb, 0, "Seek(6)"}, {0xb, PDT_TAPE, "Set capacity"}, {0xb, PDT_PRINTER, "Slew and print"}, {0xf, 0, "Read reverse(6)"}, {0x10, 0, "Write filemarks(6)"}, {0x10, PDT_PRINTER, "Synchronize buffer"}, {0x11, 0, "Space(6)"}, {0x12, 0, "Inquiry"}, {0x13, 0, "Verify(6)"}, /* SSC */ {0x14, 0, "Recover buffered data"}, {0x15, 0, "Mode select(6)"}, {0x16, 0, "Reserve(6)"}, /* obsolete in SPC-4 r11 */ {0x16, PDT_MCHANGER, "Reserve element(6)"}, {0x17, 0, "Release(6)"}, /* obsolete in SPC-4 r11 */ {0x17, PDT_MCHANGER, "Release element(6)"}, {0x18, 0, "Copy"}, /* obsolete in SPC-4 r11 */ {0x19, 0, "Erase(6)"}, {0x1a, 0, "Mode sense(6)"}, {0x1b, 0, "Start stop unit"}, {0x1b, PDT_TAPE, "Load unload"}, {0x1b, PDT_ADC, "Load unload"}, {0x1b, PDT_PRINTER, "Stop print"}, {0x1c, 0, "Receive diagnostic results"}, {0x1d, 0, "Send diagnostic"}, {0x1e, 0, "Prevent allow medium removal"}, {0x23, 0, "Read Format capacities"}, {0x24, 0, "Set window"}, {0x25, 0, "Read capacity(10)"}, {0x25, PDT_OCRW, "Read card capacity"}, {0x28, 0, "Read(10)"}, {0x29, 0, "Read generation"}, {0x2a, 0, "Write(10)"}, {0x2b, 0, "Seek(10)"}, {0x2b, PDT_TAPE, "Locate(10)"}, {0x2b, PDT_MCHANGER, "Position to element"}, {0x2c, 0, "Erase(10)"}, {0x2d, 0, "Read updated block"}, {0x2e, 0, "Write and verify(10)"}, {0x2f, 0, "Verify(10)"}, {0x30, 0, "Search data high(10)"}, {0x31, 0, "Search data equal(10)"}, {0x32, 0, "Search data low(10)"}, {0x33, 0, "Set limits(10)"}, {0x34, 0, "Pre-fetch(10)"}, {0x34, PDT_TAPE, "Read position"}, {0x35, 0, "Synchronize cache(10)"}, {0x36, 0, "Lock unlock cache(10)"}, {0x37, 0, "Read defect data(10)"}, {0x37, PDT_MCHANGER, "Initialize element status with range"}, {0x38, 0, "Medium scan"}, {0x39, 0, "Compare"}, /* obsolete in SPC-4 r11 */ {0x3a, 0, "Copy and verify"}, /* obsolete in SPC-4 r11 */ {0x3b, 0, "Write buffer"}, {0x3c, 0, "Read buffer"}, {0x3d, 0, "Update block"}, {0x3e, 0, "Read long(10)"}, {0x3f, 0, "Write long(10)"}, {0x40, 0, "Change definition"}, /* obsolete in SPC-4 r11 */ {0x41, 0, "Write same(10)"}, {0x42, 0, "Unmap"}, /* added SPC-4 rev 18 */ {0x42, PDT_MMC, "Read sub-channel"}, {0x43, PDT_MMC, "Read TOC/PMA/ATIP"}, {0x44, 0, "Report density support"}, {0x45, PDT_MMC, "Play audio(10)"}, {0x46, PDT_MMC, "Get configuration"}, {0x47, PDT_MMC, "Play audio msf"}, {0x4a, PDT_MMC, "Get event status notification"}, {0x4b, PDT_MMC, "Pause/resume"}, {0x4c, 0, "Log select"}, {0x4d, 0, "Log sense"}, {0x4e, 0, "Stop play/scan"}, {0x50, 0, "Xdwrite(10)"}, {0x51, 0, "Xpwrite(10)"}, {0x51, PDT_MMC, "Read disk information"}, {0x52, 0, "Xdread(10)"}, {0x52, PDT_MMC, "Read track information"}, {0x53, 0, "Reserve track"}, {0x54, 0, "Send OPC information"}, {0x55, 0, "Mode select(10)"}, {0x56, 0, "Reserve(10)"}, /* obsolete in SPC-4 r11 */ {0x56, PDT_MCHANGER, "Reserve element(10)"}, {0x57, 0, "Release(10)"}, /* obsolete in SPC-4 r11 */ {0x57, PDT_MCHANGER, "Release element(10)"}, {0x58, 0, "Repair track"}, {0x5a, 0, "Mode sense(10)"}, {0x5b, 0, "Close track/session"}, {0x5c, 0, "Read buffer capacity"}, {0x5d, 0, "Send cue sheet"}, {0x5e, 0, "Persistent reserve in"}, {0x5f, 0, "Persistent reserve out"}, {0x7e, 0, "Extended cdb (XCBD)"}, /* added in SPC-4 r12 */ {0x80, 0, "Xdwrite extended(16)"}, {0x80, PDT_TAPE, "Write filemarks(16)"}, {0x81, 0, "Rebuild(16)"}, {0x81, PDT_TAPE, "Read reverse(16)"}, {0x82, 0, "Regenerate(16)"}, {0x83, 0, "Extended copy"}, {0x84, 0, "Receive copy results"}, {0x85, 0, "ATA command pass through(16)"}, /* was 0x98 in spc3 rev21c */ {0x86, 0, "Access control in"}, {0x87, 0, "Access control out"}, {0x88, 0, "Read(16)"}, {0x89, 0, "Compare and write"}, {0x8a, 0, "Write(16)"}, {0x8b, 0, "Orwrite(16)"}, {0x8c, 0, "Read attribute"}, {0x8d, 0, "Write attribute"}, {0x8e, 0, "Write and verify(16)"}, {0x8f, 0, "Verify(16)"}, {0x90, 0, "Pre-fetch(16)"}, {0x91, 0, "Synchronize cache(16)"}, {0x91, PDT_TAPE, "Space(16)"}, {0x92, 0, "Lock unlock cache(16)"}, {0x92, PDT_TAPE, "Locate(16)"}, {0x93, 0, "Write same(16)"}, {0x93, PDT_TAPE, "Erase(16)"}, {0x9e, 0, "Service action in(16)"}, {0x9f, 0, "Service action out(16)"}, {0xa0, 0, "Report luns"}, {0xa1, 0, "ATA command pass through(12)"}, {0xa1, PDT_MMC, "Blank"}, {0xa2, 0, "Security protocol in"}, {0xa3, 0, "Maintenance in"}, {0xa3, PDT_MMC, "Send key"}, {0xa4, 0, "Maintenance out"}, {0xa4, PDT_MMC, "Report key"}, {0xa5, 0, "Move medium"}, {0xa5, PDT_MMC, "Play audio(12)"}, {0xa6, 0, "Exchange medium"}, {0xa6, PDT_MMC, "Load/unload medium"}, {0xa7, 0, "Move medium attached"}, {0xa7, PDT_MMC, "Set read ahead"}, {0xa8, 0, "Read(12)"}, {0xa9, 0, "Service action out(12)"}, {0xaa, 0, "Write(12)"}, {0xab, 0, "Service action in(12)"}, {0xac, 0, "erase(12)"}, {0xac, PDT_MMC, "Get performance"}, {0xad, PDT_MMC, "Read DVD/BD structure"}, {0xae, 0, "Write and verify(12)"}, {0xaf, 0, "Verify(12)"}, {0xb0, 0, "Search data high(12)"}, {0xb1, 0, "Search data equal(12)"}, {0xb1, PDT_MCHANGER, "Open/close import/export element"}, {0xb2, 0, "Search data low(12)"}, {0xb3, 0, "Set limits(12)"}, {0xb4, 0, "Read element status attached"}, {0xb5, 0, "Security protocol out"}, {0xb5, PDT_MCHANGER, "Request volume element address"}, {0xb6, 0, "Send volume tag"}, {0xb6, PDT_MMC, "Set streaming"}, {0xb7, 0, "Read defect data(12)"}, {0xb8, 0, "Read element status"}, {0xb9, 0, "Read CD msf"}, {0xba, 0, "Redundancy group in"}, {0xba, PDT_MMC, "Scan"}, {0xbb, 0, "Redundancy group out"}, {0xbb, PDT_MMC, "Set CD speed"}, {0xbc, 0, "Spare in"}, {0xbd, 0, "Spare out"}, {0xbd, PDT_MMC, "Mechanism status"}, {0xbe, 0, "Volume set in"}, {0xbe, PDT_MMC, "Read CD"}, {0xbf, 0, "Volume set out"}, {0xbf, PDT_MMC, "Send DVD/BD structure"}, {0xffff, 0, NULL}, }; struct sg_lib_value_name_t sg_lib_maint_in_arr[] = { {0x5, 0, "Report identifying information"}, /* was "Report device identifier" prior to spc4r07 */ {0xa, 0, "Report target port groups"}, {0xb, 0, "Report aliases"}, {0xc, 0, "Report supported operation codes"}, {0xd, 0, "Report supported task management functions"}, {0xe, 0, "Report priority"}, {0xf, 0, "Report timestamp"}, {0x10, 0, "Maintenance in"}, {0xffff, 0, NULL}, }; struct sg_lib_value_name_t sg_lib_maint_out_arr[] = { {0x6, 0, "Set identifying information"}, /* was "Set device identifier" prior to spc4r07 */ {0xa, 0, "Set target port groups"}, {0xb, 0, "Change aliases"}, {0xe, 0, "Set priority"}, {0xf, 0, "Set timestamp"}, {0x10, 0, "Maintenance out"}, {0xffff, 0, NULL}, }; struct sg_lib_value_name_t sg_lib_serv_in12_arr[] = { {0x1, 0, "Read media serial number"}, {0xffff, 0, NULL}, }; struct sg_lib_value_name_t sg_lib_serv_out12_arr[] = { {0xff, 0, "Impossible command name"}, {0xffff, 0, NULL}, }; struct sg_lib_value_name_t sg_lib_serv_in16_arr[] = { {0x10, 0, "Read capacity(16)"}, {0x11, 0, "Read long(16)"}, {0x12, 0, "Get LBA status"}, {0x13, 0, "Report referrals"}, {0xffff, 0, NULL}, }; struct sg_lib_value_name_t sg_lib_serv_out16_arr[] = { {0x11, 0, "Write long(16)"}, {0x1f, PDT_ADC, "Notify data transfer device(16)"}, {0xffff, 0, NULL}, }; struct sg_lib_value_name_t sg_lib_pr_in_arr[] = { {0x0, 0, "Persistent reserve in, read keys"}, {0x1, 0, "Persistent reserve in, read reservation"}, {0x2, 0, "Persistent reserve in, report capabilities"}, {0x3, 0, "Persistent reserve in, read full status"}, {0xffff, 0, NULL}, }; struct sg_lib_value_name_t sg_lib_pr_out_arr[] = { {0x0, 0, "Persistent reserve out, register"}, {0x1, 0, "Persistent reserve out, reserve"}, {0x2, 0, "Persistent reserve out, release"}, {0x3, 0, "Persistent reserve out, clear"}, {0x4, 0, "Persistent reserve out, preempt"}, {0x5, 0, "Persistent reserve out, preempt and abort"}, {0x6, 0, "Persistent reserve out, register and ignore existing key"}, {0x7, 0, "Persistent reserve out, register and move"}, {0xffff, 0, NULL}, }; struct sg_lib_value_name_t sg_lib_variable_length_arr[] = { {0x1, 0, "Rebuild(32)"}, {0x2, 0, "Regenerate(32)"}, {0x3, 0, "Xdread(32)"}, {0x4, 0, "Xdwrite(32)"}, {0x5, 0, "Xdwrite extended(32)"}, {0x6, 0, "Xpwrite(32)"}, {0x7, 0, "Xdwriteread(32)"}, {0x8, 0, "Xdwrite extended(64)"}, {0x9, 0, "Read(32)"}, {0xa, 0, "Verify(32)"}, {0xb, 0, "Write(32)"}, {0xc, 0, "Write an verify(32)"}, {0xd, 0, "Write same(32)"}, {0xe, 0, "Orwrite(32)"}, /* added sbc3r25 */ {0x1800, 0, "Receive credential"}, {0x8801, 0, "Format OSD (osd)"}, {0x8802, 0, "Create (osd)"}, {0x8803, 0, "List (osd)"}, {0x8805, 0, "Read (osd)"}, {0x8806, 0, "Write (osd)"}, {0x8807, 0, "Append (osd)"}, {0x8808, 0, "Flush (osd)"}, {0x880a, 0, "Remove (osd)"}, {0x880b, 0, "Create partition (osd)"}, {0x880c, 0, "Remove partition (osd)"}, {0x880e, 0, "Get attributes (osd)"}, {0x880f, 0, "Set attributes (osd)"}, {0x8812, 0, "Create and write (osd)"}, {0x8815, 0, "Create collection (osd)"}, {0x8816, 0, "Remove collection (osd)"}, {0x8817, 0, "List collection (osd)"}, {0x8818, 0, "Set key (osd)"}, {0x8819, 0, "Set master key (osd)"}, {0x881a, 0, "Flush collection (osd)"}, {0x881b, 0, "Flush partition (osd)"}, {0x881c, 0, "Flush OSD (osd)"}, {0x8880, 0, "Object structure check (osd-2)"}, {0x8881, 0, "Format OSD (osd-2)"}, {0x8882, 0, "Create (osd-2)"}, {0x8883, 0, "List (osd-2)"}, {0x8884, 0, "Punch (osd-2)"}, {0x8885, 0, "Read (osd-2)"}, {0x8886, 0, "Write (osd-2)"}, {0x8887, 0, "Append (osd-2)"}, {0x8888, 0, "Flush (osd-2)"}, {0x8889, 0, "Clear (osd-2)"}, {0x888a, 0, "Remove (osd-2)"}, {0x888b, 0, "Create partition (osd-2)"}, {0x888c, 0, "Remove partition (osd-2)"}, {0x888e, 0, "Get attributes (osd-2)"}, {0x888f, 0, "Set attributes (osd-2)"}, {0x8892, 0, "Create and write (osd-2)"}, {0x8895, 0, "Create collection (osd-2)"}, {0x8896, 0, "Remove collection (osd-2)"}, {0x8897, 0, "List collection (osd-2)"}, {0x8898, 0, "Set key (osd-2)"}, {0x8899, 0, "Set master key (osd-2)"}, {0x889a, 0, "Flush collection (osd-2)"}, {0x889b, 0, "Flush partition (osd-2)"}, {0x889c, 0, "Flush OSD (osd-2)"}, {0x88a0, 0, "Query (osd-2)"}, {0x88a1, 0, "Remove member objects (osd-2)"}, {0x88a2, 0, "Get member attributes (osd-2)"}, {0x88a3, 0, "Set member attributes (osd-2)"}, {0x88b1, 0, "Read map (osd-2)"}, {0x8f7c, 0, "Perform SCSI command (osd-2)"}, {0x8f7d, 0, "Perform task management function (osd-2)"}, {0x8f7e, 0, "Perform SCSI command (osd)"}, {0x8f7f, 0, "Perform task management function (osd)"}, {0xffff, 0, NULL}, }; /* A conveniently formatted list of SCSI ASC/ASCQ codes and their * corresponding text can be found at: www.t10.org/lists/asc-num.txt */ struct sg_lib_asc_ascq_range_t sg_lib_asc_ascq_range[] = { {0x40,0x01,0x7f,"Ram failure [0x%x]"}, {0x40,0x80,0xff,"Diagnostic failure on component [0x%x]"}, {0x41,0x01,0xff,"Data path failure [0x%x]"}, {0x42,0x01,0xff,"Power-on or self-test failure [0x%x]"}, {0x4d,0x00,0xff,"Tagged overlapped commands [0x%x]"}, {0x70,0x00,0xff,"Decompression exception short algorithm id of 0x%x"}, {0, 0, 0, NULL} }; struct sg_lib_asc_ascq_t sg_lib_asc_ascq[] = { {0x00,0x00,"No additional sense information"}, {0x00,0x01,"Filemark detected"}, {0x00,0x02,"End-of-partition/medium detected"}, {0x00,0x03,"Setmark detected"}, {0x00,0x04,"Beginning-of-partition/medium detected"}, {0x00,0x05,"End-of-data detected"}, {0x00,0x06,"I/O process terminated"}, {0x00,0x07,"Programmable early warning detected"}, {0x00,0x11,"Audio play operation in progress"}, {0x00,0x12,"Audio play operation paused"}, {0x00,0x13,"Audio play operation successfully completed"}, {0x00,0x14,"Audio play operation stopped due to error"}, {0x00,0x15,"No current audio status to return"}, {0x00,0x16,"operation in progress"}, {0x00,0x17,"Cleaning requested"}, {0x00,0x18,"Erase operation in progress"}, {0x00,0x19,"Locate operation in progress"}, {0x00,0x1a,"Rewind operation in progress"}, {0x00,0x1b,"Set capacity operation in progress"}, {0x00,0x1c,"Verify operation in progress"}, {0x00,0x1d,"ATA pass through information available"}, {0x00,0x1e,"Conflicting SA creation request"}, {0x00,0x1f,"Logical unit transitioning to another power condition"}, {0x01,0x00,"No index/sector signal"}, {0x02,0x00,"No seek complete"}, {0x03,0x00,"Peripheral device write fault"}, {0x03,0x01,"No write current"}, {0x03,0x02,"Excessive write errors"}, {0x04,0x00,"Logical unit not ready, cause not reportable"}, {0x04,0x01,"Logical unit is in process of becoming ready"}, {0x04,0x02,"Logical unit not ready, " "initializing command required"}, {0x04,0x03,"Logical unit not ready, " "manual intervention required"}, {0x04,0x04,"Logical unit not ready, format in progress"}, {0x04,0x05,"Logical unit not ready, rebuild in progress"}, {0x04,0x06,"Logical unit not ready, recalculation in progress"}, {0x04,0x07,"Logical unit not ready, operation in progress"}, {0x04,0x08,"Logical unit not ready, long write in progress"}, {0x04,0x09,"Logical unit not ready, self-test in progress"}, {0x04,0x0a,"Logical unit " "not accessible, asymmetric access state transition"}, {0x04,0x0b,"Logical unit " "not accessible, target port in standby state"}, {0x04,0x0c,"Logical unit " "not accessible, target port in unavailable state"}, {0x04,0x0d,"Logical unit not ready, structure check required"}, {0x04,0x10,"Logical unit not ready, " "auxiliary memory not accessible"}, {0x04,0x11,"Logical unit not ready, " "notify (enable spinup) required"}, {0x04,0x12,"Logical unit not ready, offline"}, {0x04,0x13,"Logical unit not ready, SA creation in progress"}, {0x04,0x14,"Logical unit not ready, space allocation in progress"}, {0x04,0x15,"Logical unit not ready, robotics disabled"}, {0x04,0x16,"Logical unit not ready, configuration required"}, {0x04,0x17,"Logical unit not ready, calibration required"}, {0x04,0x18,"Logical unit not ready, a door is open"}, {0x04,0x19,"Logical unit not ready, operating in sequential mode"}, {0x04,0x1a,"Logical unit not ready, start stop unit command in progress"}, {0x05,0x00,"Logical unit does not respond to selection"}, {0x06,0x00,"No reference position found"}, {0x07,0x00,"Multiple peripheral devices selected"}, {0x08,0x00,"Logical unit communication failure"}, {0x08,0x01,"Logical unit communication time-out"}, {0x08,0x02,"Logical unit communication parity error"}, {0x08,0x03,"Logical unit communication CRC error (Ultra-DMA/32)"}, {0x08,0x04,"Unreachable copy target"}, {0x09,0x00,"Track following error"}, {0x09,0x01,"Tracking servo failure"}, {0x09,0x02,"Focus servo failure"}, {0x09,0x03,"Spindle servo failure"}, {0x09,0x04,"Head select fault"}, {0x0A,0x00,"Error log overflow"}, {0x0B,0x00,"Warning"}, {0x0B,0x01,"Warning - specified temperature exceeded"}, {0x0B,0x02,"Warning - enclosure degraded"}, {0x0B,0x03,"Warning - background self-test failed"}, {0x0B,0x04,"Warning - background pre-scan detected medium error"}, {0x0B,0x05,"Warning - background medium scan detected medium error"}, {0x0B,0x06,"Warning - non-volatile cache now volatile"}, {0x0B,0x07,"Warning - degraded power to non-volatile cache"}, {0x0B,0x08,"Warning - power loss expected"}, {0x0C,0x00,"Write error"}, {0x0C,0x01,"Write error - recovered with auto reallocation"}, {0x0C,0x02,"Write error - auto reallocation failed"}, {0x0C,0x03,"Write error - recommend reassignment"}, {0x0C,0x04,"Compression check miscompare error"}, {0x0C,0x05,"Data expansion occurred during compression"}, {0x0C,0x06,"Block not compressible"}, {0x0C,0x07,"Write error - recovery needed"}, {0x0C,0x08,"Write error - recovery failed"}, {0x0C,0x09,"Write error - loss of streaming"}, {0x0C,0x0A,"Write error - padding blocks added"}, {0x0C,0x0B,"Auxiliary memory write error"}, {0x0C,0x0C,"Write error - unexpected unsolicited data"}, {0x0C,0x0D,"Write error - not enough unsolicited data"}, {0x0C,0x0F,"Defects in error window"}, {0x0D,0x00,"Error detected by third party temporary initiator"}, {0x0D,0x01,"Third party device failure"}, {0x0D,0x02,"Copy target device not reachable"}, {0x0D,0x03,"Incorrect copy target device type"}, {0x0D,0x04,"Copy target device data underrun"}, {0x0D,0x05,"Copy target device data overrun"}, {0x0E,0x00,"Invalid information unit"}, {0x0E,0x01,"Information unit too short"}, {0x0E,0x02,"Information unit too long"}, {0x0E,0x03,"Invalid field in command information unit"}, {0x10,0x00,"Id CRC or ECC error"}, {0x10,0x01,"Logical block guard check failed"}, {0x10,0x02,"Logical block application tag check failed"}, {0x10,0x03,"Logical block reference tag check failed"}, {0x10,0x04,"Logical block protection error on recover buffered data"}, {0x10,0x05,"Logical block protection method error"}, {0x11,0x00,"Unrecovered read error"}, {0x11,0x01,"Read retries exhausted"}, {0x11,0x02,"Error too long to correct"}, {0x11,0x03,"Multiple read errors"}, {0x11,0x04,"Unrecovered read error - auto reallocate failed"}, {0x11,0x05,"L-EC uncorrectable error"}, {0x11,0x06,"CIRC unrecovered error"}, {0x11,0x07,"Data re-synchronization error"}, {0x11,0x08,"Incomplete block read"}, {0x11,0x09,"No gap found"}, {0x11,0x0A,"Miscorrected error"}, {0x11,0x0B,"Unrecovered read error - recommend reassignment"}, {0x11,0x0C,"Unrecovered read error - recommend rewrite the data"}, {0x11,0x0D,"De-compression CRC error"}, {0x11,0x0E,"Cannot decompress using declared algorithm"}, {0x11,0x0F,"Error reading UPC/EAN number"}, {0x11,0x10,"Error reading ISRC number"}, {0x11,0x11,"Read error - loss of streaming"}, {0x11,0x12,"Auxiliary memory read error"}, {0x11,0x13,"Read error - failed retransmission request"}, {0x11,0x14,"Read error - LBA marked bad by application client"}, {0x12,0x00,"Address mark not found for id field"}, {0x13,0x00,"Address mark not found for data field"}, {0x14,0x00,"Recorded entity not found"}, {0x14,0x01,"Record not found"}, {0x14,0x02,"Filemark or setmark not found"}, {0x14,0x03,"End-of-data not found"}, {0x14,0x04,"Block sequence error"}, {0x14,0x05,"Record not found - recommend reassignment"}, {0x14,0x06,"Record not found - data auto-reallocated"}, {0x14,0x07,"Locate operation failure"}, {0x15,0x00,"Random positioning error"}, {0x15,0x01,"Mechanical positioning error"}, {0x15,0x02,"Positioning error detected by read of medium"}, {0x16,0x00,"Data synchronization mark error"}, {0x16,0x01,"Data sync error - data rewritten"}, {0x16,0x02,"Data sync error - recommend rewrite"}, {0x16,0x03,"Data sync error - data auto-reallocated"}, {0x16,0x04,"Data sync error - recommend reassignment"}, {0x17,0x00,"Recovered data with no error correction applied"}, {0x17,0x01,"Recovered data with retries"}, {0x17,0x02,"Recovered data with positive head offset"}, {0x17,0x03,"Recovered data with negative head offset"}, {0x17,0x04,"Recovered data with retries and/or circ applied"}, {0x17,0x05,"Recovered data using previous sector id"}, {0x17,0x06,"Recovered data without ECC - data auto-reallocated"}, {0x17,0x07,"Recovered data without ECC - recommend reassignment"}, {0x17,0x08,"Recovered data without ECC - recommend rewrite"}, {0x17,0x09,"Recovered data without ECC - data rewritten"}, {0x18,0x00,"Recovered data with error correction applied"}, {0x18,0x01,"Recovered data with error corr. & retries applied"}, {0x18,0x02,"Recovered data - data auto-reallocated"}, {0x18,0x03,"Recovered data with CIRC"}, {0x18,0x04,"Recovered data with L-EC"}, {0x18,0x05,"Recovered data - recommend reassignment"}, {0x18,0x06,"Recovered data - recommend rewrite"}, {0x18,0x07,"Recovered data with ECC - data rewritten"}, {0x18,0x08,"Recovered data with linking"}, {0x19,0x00,"Defect list error"}, {0x19,0x01,"Defect list not available"}, {0x19,0x02,"Defect list error in primary list"}, {0x19,0x03,"Defect list error in grown list"}, {0x1A,0x00,"Parameter list length error"}, {0x1B,0x00,"Synchronous data transfer error"}, {0x1C,0x00,"Defect list not found"}, {0x1C,0x01,"Primary defect list not found"}, {0x1C,0x02,"Grown defect list not found"}, {0x1D,0x00,"Miscompare during verify operation"}, {0x1D,0x01,"Miscompare verify of unmapped lba"}, {0x1E,0x00,"Recovered id with ECC correction"}, {0x1F,0x00,"Partial defect list transfer"}, {0x20,0x00,"Invalid command operation code"}, {0x20,0x01,"Access denied - initiator pending-enrolled"}, {0x20,0x02,"Access denied - no access rights"}, {0x20,0x03,"Access denied - invalid mgmt id key"}, {0x20,0x04,"Illegal command while in write capable state"}, {0x20,0x05,"Write type operation while in read capable state (obs)"}, {0x20,0x06,"Illegal command while in explicit address mode"}, {0x20,0x07,"Illegal command while in implicit address mode"}, {0x20,0x08,"Access denied - enrollment conflict"}, {0x20,0x09,"Access denied - invalid LU identifier"}, {0x20,0x0A,"Access denied - invalid proxy token"}, {0x20,0x0B,"Access denied - ACL LUN conflict"}, {0x20,0x0C,"Illegal command when not in append-only mode"}, {0x21,0x00,"Logical block address out of range"}, {0x21,0x01,"Invalid element address"}, {0x21,0x02,"Invalid address for write"}, {0x21,0x03,"Invalid write crossing layer jump"}, {0x22,0x00,"Illegal function (use 20 00, 24 00, or 26 00)"}, {0x24,0x00,"Invalid field in cdb"}, {0x24,0x01,"CDB decryption error"}, {0x24,0x02,"Invalid cdb field while in explicit block model (obs)"}, {0x24,0x03,"Invalid cdb field while in implicit block model (obs)"}, {0x24,0x04,"Security audit value frozen"}, {0x24,0x05,"Security working key frozen"}, {0x24,0x06,"Nonce not unique"}, {0x24,0x07,"Nonce timestamp out of range"}, {0x24,0x08,"Invalid xcdb"}, {0x25,0x00,"Logical unit not supported"}, {0x26,0x00,"Invalid field in parameter list"}, {0x26,0x01,"Parameter not supported"}, {0x26,0x02,"Parameter value invalid"}, {0x26,0x03,"Threshold parameters not supported"}, {0x26,0x04,"Invalid release of persistent reservation"}, {0x26,0x05,"Data decryption error"}, {0x26,0x06,"Too many target descriptors"}, {0x26,0x07,"Unsupported target descriptor type code"}, {0x26,0x08,"Too many segment descriptors"}, {0x26,0x09,"Unsupported segment descriptor type code"}, {0x26,0x0A,"Unexpected inexact segment"}, {0x26,0x0B,"Inline data length exceeded"}, {0x26,0x0C,"Invalid operation for copy source or destination"}, {0x26,0x0D,"Copy segment granularity violation"}, {0x26,0x0E,"Invalid parameter while port is enabled"}, {0x26,0x0F,"Invalid data-out buffer integrity check value"}, {0x26,0x10,"Data decryption key fail limit reached"}, {0x26,0x11,"Incomplete key-associated data set"}, {0x26,0x12,"Vendor specific key reference not found"}, {0x27,0x00,"Write protected"}, {0x27,0x01,"Hardware write protected"}, {0x27,0x02,"Logical unit software write protected"}, {0x27,0x03,"Associated write protect"}, {0x27,0x04,"Persistent write protect"}, {0x27,0x05,"Permanent write protect"}, {0x27,0x06,"Conditional write protect"}, {0x27,0x07,"Space allocation failed write protect"}, {0x28,0x00,"Not ready to ready change, medium may have changed"}, {0x28,0x01,"Import or export element accessed"}, {0x28,0x02,"Format-layer may have changed"}, {0x28,0x03,"Import/export element accessed, medium changed"}, {0x29,0x00,"Power on, reset, or bus device reset occurred"}, {0x29,0x01,"Power on occurred"}, {0x29,0x02,"SCSI bus reset occurred"}, {0x29,0x03,"Bus device reset function occurred"}, {0x29,0x04,"Device internal reset"}, {0x29,0x05,"Transceiver mode changed to single-ended"}, {0x29,0x06,"Transceiver mode changed to lvd"}, {0x29,0x07,"I_T nexus loss occurred"}, {0x2A,0x00,"Parameters changed"}, {0x2A,0x01,"Mode parameters changed"}, {0x2A,0x02,"Log parameters changed"}, {0x2A,0x03,"Reservations preempted"}, {0x2A,0x04,"Reservations released"}, {0x2A,0x05,"Registrations preempted"}, {0x2A,0x06,"Asymmetric access state changed"}, {0x2A,0x07,"Implicit asymmetric access state transition failed"}, {0x2A,0x08,"Priority changed"}, {0x2A,0x09,"Capacity data has changed"}, {0x2A,0x0c, "Error recovery attributes have changed"}, {0x2A,0x0d, "Data encryption capabilities changed"}, {0x2A,0x10,"Timestamp changed"}, {0x2A,0x11,"Data encryption parameters changed by another i_t nexus"}, {0x2A,0x12,"Data encryption parameters changed by vendor specific event"}, {0x2A,0x13,"Data encryption key instance counter has changed"}, {0x2A,0x0a,"Error history i_t nexus cleared"}, {0x2A,0x0b,"Error history snapshot released"}, {0x2A,0x14,"SA creation capabilities data has changed"}, {0x2B,0x00,"Copy cannot execute since host cannot disconnect"}, {0x2C,0x00,"Command sequence error"}, {0x2C,0x01,"Too many windows specified"}, {0x2C,0x02,"Invalid combination of windows specified"}, {0x2C,0x03,"Current program area is not empty"}, {0x2C,0x04,"Current program area is empty"}, {0x2C,0x05,"Illegal power condition request"}, {0x2C,0x06,"Persistent prevent conflict"}, {0x2C,0x07,"Previous busy status"}, {0x2C,0x08,"Previous task set full status"}, {0x2C,0x09,"Previous reservation conflict status"}, {0x2C,0x0A,"Partition or collection contains user objects"}, {0x2C,0x0B,"Not reserved"}, {0x2C,0x0C,"ORWRITE generation does not match"}, {0x2D,0x00,"Overwrite error on update in place"}, {0x2E,0x00,"Insufficient time for operation"}, {0x2F,0x00,"Commands cleared by another initiator"}, {0x2F,0x01,"Commands cleared by power loss notification"}, {0x2F,0x02,"Commands cleared by device server"}, {0x30,0x00,"Incompatible medium installed"}, {0x30,0x01,"Cannot read medium - unknown format"}, {0x30,0x02,"Cannot read medium - incompatible format"}, {0x30,0x03,"Cleaning cartridge installed"}, {0x30,0x04,"Cannot write medium - unknown format"}, {0x30,0x05,"Cannot write medium - incompatible format"}, {0x30,0x06,"Cannot format medium - incompatible medium"}, {0x30,0x07,"Cleaning failure"}, {0x30,0x08,"Cannot write - application code mismatch"}, {0x30,0x09,"Current session not fixated for append"}, {0x30,0x0A,"Cleaning request rejected"}, {0x30,0x0B,"Cleaning tape expired"}, {0x30,0x0C,"WORM medium - overwrite attempted"}, {0x30,0x0D,"WORM medium - integrity check"}, {0x30,0x10,"Medium not formatted"}, {0x30,0x11,"Incompatible volume type"}, {0x30,0x12,"Incompatible volume qualifier"}, {0x30,0x13,"Cleaning volume expired"}, {0x31,0x00,"Medium format corrupted"}, {0x31,0x01,"Format command failed"}, {0x31,0x02,"Zoned formatting failed due to spare linking"}, {0x32,0x00,"No defect spare location available"}, {0x32,0x01,"Defect list update failure"}, {0x33,0x00,"Tape length error"}, {0x34,0x00,"Enclosure failure"}, {0x35,0x00,"Enclosure services failure"}, {0x35,0x01,"Unsupported enclosure function"}, {0x35,0x02,"Enclosure services unavailable"}, {0x35,0x03,"Enclosure services transfer failure"}, {0x35,0x04,"Enclosure services transfer refused"}, {0x35,0x05,"Enclosure services checksum error"}, {0x36,0x00,"Ribbon, ink, or toner failure"}, {0x37,0x00,"Rounded parameter"}, {0x38,0x00,"Event status notification"}, {0x38,0x02,"Esn - power management class event"}, {0x38,0x04,"Esn - media class event"}, {0x38,0x06,"Esn - device busy class event"}, {0x38,0x07,"Thin provisioning soft threshold reached"}, {0x39,0x00,"Saving parameters not supported"}, {0x3A,0x00,"Medium not present"}, {0x3A,0x01,"Medium not present - tray closed"}, {0x3A,0x02,"Medium not present - tray open"}, {0x3A,0x03,"Medium not present - loadable"}, {0x3A,0x04,"Medium not present - medium auxiliary memory accessible"}, {0x3B,0x00,"Sequential positioning error"}, {0x3B,0x01,"Tape position error at beginning-of-medium"}, {0x3B,0x02,"Tape position error at end-of-medium"}, {0x3B,0x03,"Tape or electronic vertical forms unit not ready"}, {0x3B,0x04,"Slew failure"}, {0x3B,0x05,"Paper jam"}, {0x3B,0x06,"Failed to sense top-of-form"}, {0x3B,0x07,"Failed to sense bottom-of-form"}, {0x3B,0x08,"Reposition error"}, {0x3B,0x09,"Read past end of medium"}, {0x3B,0x0A,"Read past beginning of medium"}, {0x3B,0x0B,"Position past end of medium"}, {0x3B,0x0C,"Position past beginning of medium"}, {0x3B,0x0D,"Medium destination element full"}, {0x3B,0x0E,"Medium source element empty"}, {0x3B,0x0F,"End of medium reached"}, {0x3B,0x11,"Medium magazine not accessible"}, {0x3B,0x12,"Medium magazine removed"}, {0x3B,0x13,"Medium magazine inserted"}, {0x3B,0x14,"Medium magazine locked"}, {0x3B,0x15,"Medium magazine unlocked"}, {0x3B,0x16,"Mechanical positioning or changer error"}, {0x3B,0x17,"Read past end of user object"}, {0x3B,0x18,"Element disabled"}, {0x3B,0x19,"Element enabled"}, {0x3B,0x1a,"Data transfer device removed"}, {0x3B,0x1b,"Data transfer device inserted"}, {0x3D,0x00,"Invalid bits in identify message"}, {0x3E,0x00,"Logical unit has not self-configured yet"}, {0x3E,0x01,"Logical unit failure"}, {0x3E,0x02,"Timeout on logical unit"}, {0x3E,0x03,"Logical unit failed self-test"}, {0x3E,0x04,"Logical unit unable to update self-test log"}, {0x3F,0x00,"Target operating conditions have changed"}, {0x3F,0x01,"Microcode has been changed"}, {0x3F,0x02,"Changed operating definition"}, {0x3F,0x03,"Inquiry data has changed"}, {0x3F,0x04,"Component device attached"}, {0x3F,0x05,"Device identifier changed"}, {0x3F,0x06,"Redundancy group created or modified"}, {0x3F,0x07,"Redundancy group deleted"}, {0x3F,0x08,"Spare created or modified"}, {0x3F,0x09,"Spare deleted"}, {0x3F,0x0A,"Volume set created or modified"}, {0x3F,0x0B,"Volume set deleted"}, {0x3F,0x0C,"Volume set deassigned"}, {0x3F,0x0D,"Volume set reassigned"}, {0x3F,0x0E,"Reported luns data has changed"}, {0x3F,0x0F,"Echo buffer overwritten"}, {0x3F,0x10,"Medium loadable"}, {0x3F,0x11,"Medium auxiliary memory accessible"}, {0x3F,0x12,"iSCSI IP address added"}, {0x3F,0x13,"iSCSI IP address removed"}, {0x3F,0x14,"iSCSI IP address changed"}, /* * ASC 0x40, 0x41 and 0x42 overridden by "additional2" array entries * for ascq > 1. Preferred error message for this group is * "Diagnostic failure on component nn (80h-ffh)". */ {0x40,0x00,"Ram failure (should use 40 nn)"}, {0x41,0x00,"Data path failure (should use 40 nn)"}, {0x42,0x00,"Power-on or self-test failure (should use 40 nn)"}, {0x43,0x00,"Message error"}, {0x44,0x00,"Internal target failure"}, {0x44,0x71,"ATA device failed Set Features"}, {0x45,0x00,"Select or reselect failure"}, {0x46,0x00,"Unsuccessful soft reset"}, {0x47,0x00,"SCSI parity error"}, {0x47,0x01,"Data phase CRC error detected"}, {0x47,0x02,"SCSI parity error detected during st data phase"}, {0x47,0x03,"Information unit iuCRC error detected"}, {0x47,0x04,"Asynchronous information protection error detected"}, {0x47,0x05,"Protocol service CRC error"}, {0x47,0x06,"Phy test function in progress"}, {0x47,0x7F,"Some commands cleared by iSCSI protocol event"}, {0x48,0x00,"Initiator detected error message received"}, {0x49,0x00,"Invalid message error"}, {0x4A,0x00,"Command phase error"}, {0x4B,0x00,"Data phase error"}, {0x4B,0x01,"Invalid target port transfer tag received"}, {0x4B,0x02,"Too much write data"}, {0x4B,0x03,"Ack/nak timeout"}, {0x4B,0x04,"Nak received"}, {0x4B,0x05,"Data offset error"}, {0x4B,0x06,"Initiator response timeout"}, {0x4B,0x07,"Connection lost"}, {0x4C,0x00,"Logical unit failed self-configuration"}, /* * ASC 0x4D overridden by an "additional2" array entry * so there is no need to have them here. */ /* {0x4D,0x00,"Tagged overlapped commands (nn = queue tag)"}, */ {0x4E,0x00,"Overlapped commands attempted"}, {0x50,0x00,"Write append error"}, {0x50,0x01,"Write append position error"}, {0x50,0x02,"Position error related to timing"}, {0x51,0x00,"Erase failure"}, {0x51,0x01,"Erase failure - incomplete erase operation detected"}, {0x52,0x00,"Cartridge fault"}, {0x53,0x00,"Media load or eject failed"}, {0x53,0x01,"Unload tape failure"}, {0x53,0x02,"Medium removal prevented"}, {0x53,0x03,"Medium removal prevented by data transfer element"}, {0x53,0x04,"Medium thread or unthread failure"}, {0x53,0x05,"Volume identifier invalid"}, {0x53,0x06,"Volume identifier missing"}, {0x53,0x07,"Duplicate volume identifier"}, {0x53,0x08,"Element status unknown"}, {0x54,0x00,"SCSI to host system interface failure"}, {0x55,0x00,"System resource failure"}, {0x55,0x01,"System buffer full"}, {0x55,0x02,"Insufficient reservation resources"}, {0x55,0x03,"Insufficient resources"}, {0x55,0x04,"Insufficient registration resources"}, {0x55,0x05,"Insufficient access control resources"}, {0x55,0x06,"Auxiliary memory out of space"}, {0x55,0x07,"Quota error"}, {0x55,0x08,"Maximum number of supplemental decryption keys exceeded"}, {0x55,0x09,"Medium auxiliary memory not accessible"}, {0x55,0x0a,"Data currently unavailable"}, {0x55,0x0b,"Insufficient power for operation"}, {0x57,0x00,"Unable to recover table-of-contents"}, {0x58,0x00,"Generation does not exist"}, {0x59,0x00,"Updated block read"}, {0x5A,0x00,"Operator request or state change input"}, {0x5A,0x01,"Operator medium removal request"}, {0x5A,0x02,"Operator selected write protect"}, {0x5A,0x03,"Operator selected write permit"}, {0x5B,0x00,"Log exception"}, {0x5B,0x01,"Threshold condition met"}, {0x5B,0x02,"Log counter at maximum"}, {0x5B,0x03,"Log list codes exhausted"}, {0x5C,0x00,"Rpl status change"}, {0x5C,0x01,"Spindles synchronized"}, {0x5C,0x02,"Spindles not synchronized"}, {0x5D,0x00,"Failure prediction threshold exceeded"}, {0x5D,0x01,"Media failure prediction threshold exceeded"}, {0x5D,0x02,"Logical unit failure prediction threshold exceeded"}, {0x5D,0x03,"spare area exhaustion prediction threshold exceeded"}, {0x5D,0x10,"Hardware impending failure general hard drive failure"}, {0x5D,0x11,"Hardware impending failure drive error rate too high" }, {0x5D,0x12,"Hardware impending failure data error rate too high" }, {0x5D,0x13,"Hardware impending failure seek error rate too high" }, {0x5D,0x14,"Hardware impending failure too many block reassigns"}, {0x5D,0x15,"Hardware impending failure access times too high" }, {0x5D,0x16,"Hardware impending failure start unit times too high" }, {0x5D,0x17,"Hardware impending failure channel parametrics"}, {0x5D,0x18,"Hardware impending failure controller detected"}, {0x5D,0x19,"Hardware impending failure throughput performance"}, {0x5D,0x1A,"Hardware impending failure seek time performance"}, {0x5D,0x1B,"Hardware impending failure spin-up retry count"}, {0x5D,0x1C,"Hardware impending failure drive calibration retry count"}, {0x5D,0x20,"Controller impending failure general hard drive failure"}, {0x5D,0x21,"Controller impending failure drive error rate too high" }, {0x5D,0x22,"Controller impending failure data error rate too high" }, {0x5D,0x23,"Controller impending failure seek error rate too high" }, {0x5D,0x24,"Controller impending failure too many block reassigns"}, {0x5D,0x25,"Controller impending failure access times too high" }, {0x5D,0x26,"Controller impending failure start unit times too high" }, {0x5D,0x27,"Controller impending failure channel parametrics"}, {0x5D,0x28,"Controller impending failure controller detected"}, {0x5D,0x29,"Controller impending failure throughput performance"}, {0x5D,0x2A,"Controller impending failure seek time performance"}, {0x5D,0x2B,"Controller impending failure spin-up retry count"}, {0x5D,0x2C,"Controller impending failure drive calibration retry count"}, {0x5D,0x30,"Data channel impending failure general hard drive failure"}, {0x5D,0x31,"Data channel impending failure drive error rate too high" }, {0x5D,0x32,"Data channel impending failure data error rate too high" }, {0x5D,0x33,"Data channel impending failure seek error rate too high" }, {0x5D,0x34,"Data channel impending failure too many block reassigns"}, {0x5D,0x35,"Data channel impending failure access times too high" }, {0x5D,0x36,"Data channel impending failure start unit times too high" }, {0x5D,0x37,"Data channel impending failure channel parametrics"}, {0x5D,0x38,"Data channel impending failure controller detected"}, {0x5D,0x39,"Data channel impending failure throughput performance"}, {0x5D,0x3A,"Data channel impending failure seek time performance"}, {0x5D,0x3B,"Data channel impending failure spin-up retry count"}, {0x5D,0x3C,"Data channel impending failure drive calibration retry count"}, {0x5D,0x40,"Servo impending failure general hard drive failure"}, {0x5D,0x41,"Servo impending failure drive error rate too high" }, {0x5D,0x42,"Servo impending failure data error rate too high" }, {0x5D,0x43,"Servo impending failure seek error rate too high" }, {0x5D,0x44,"Servo impending failure too many block reassigns"}, {0x5D,0x45,"Servo impending failure access times too high" }, {0x5D,0x46,"Servo impending failure start unit times too high" }, {0x5D,0x47,"Servo impending failure channel parametrics"}, {0x5D,0x48,"Servo impending failure controller detected"}, {0x5D,0x49,"Servo impending failure throughput performance"}, {0x5D,0x4A,"Servo impending failure seek time performance"}, {0x5D,0x4B,"Servo impending failure spin-up retry count"}, {0x5D,0x4C,"Servo impending failure drive calibration retry count"}, {0x5D,0x50,"Spindle impending failure general hard drive failure"}, {0x5D,0x51,"Spindle impending failure drive error rate too high" }, {0x5D,0x52,"Spindle impending failure data error rate too high" }, {0x5D,0x53,"Spindle impending failure seek error rate too high" }, {0x5D,0x54,"Spindle impending failure too many block reassigns"}, {0x5D,0x55,"Spindle impending failure access times too high" }, {0x5D,0x56,"Spindle impending failure start unit times too high" }, {0x5D,0x57,"Spindle impending failure channel parametrics"}, {0x5D,0x58,"Spindle impending failure controller detected"}, {0x5D,0x59,"Spindle impending failure throughput performance"}, {0x5D,0x5A,"Spindle impending failure seek time performance"}, {0x5D,0x5B,"Spindle impending failure spin-up retry count"}, {0x5D,0x5C,"Spindle impending failure drive calibration retry count"}, {0x5D,0x60,"Firmware impending failure general hard drive failure"}, {0x5D,0x61,"Firmware impending failure drive error rate too high" }, {0x5D,0x62,"Firmware impending failure data error rate too high" }, {0x5D,0x63,"Firmware impending failure seek error rate too high" }, {0x5D,0x64,"Firmware impending failure too many block reassigns"}, {0x5D,0x65,"Firmware impending failure access times too high" }, {0x5D,0x66,"Firmware impending failure start unit times too high" }, {0x5D,0x67,"Firmware impending failure channel parametrics"}, {0x5D,0x68,"Firmware impending failure controller detected"}, {0x5D,0x69,"Firmware impending failure throughput performance"}, {0x5D,0x6A,"Firmware impending failure seek time performance"}, {0x5D,0x6B,"Firmware impending failure spin-up retry count"}, {0x5D,0x6C,"Firmware impending failure drive calibration retry count"}, {0x5D,0xFF,"Failure prediction threshold exceeded (false)"}, {0x5E,0x00,"Low power condition on"}, {0x5E,0x01,"Idle condition activated by timer"}, {0x5E,0x02,"Standby condition activated by timer"}, {0x5E,0x03,"Idle condition activated by command"}, {0x5E,0x04,"Standby condition activated by command"}, {0x5E,0x05,"Idle_b condition activated by timer"}, {0x5E,0x06,"Idle_b condition activated by command"}, {0x5E,0x07,"Idle_c condition activated by timer"}, {0x5E,0x08,"Idle_c condition activated by command"}, {0x5E,0x09,"Standby_y condition activated by timer"}, {0x5E,0x0a,"Standby_y condition activated by command"}, {0x5E,0x41,"Power state change to active"}, {0x5E,0x42,"Power state change to idle"}, {0x5E,0x43,"Power state change to standby"}, {0x5E,0x45,"Power state change to sleep"}, {0x5E,0x47,"Power state change to device control"}, {0x60,0x00,"Lamp failure"}, {0x61,0x00,"Video acquisition error"}, {0x61,0x01,"Unable to acquire video"}, {0x61,0x02,"Out of focus"}, {0x62,0x00,"Scan head positioning error"}, {0x63,0x00,"End of user area encountered on this track"}, {0x63,0x01,"Packet does not fit in available space"}, {0x64,0x00,"Illegal mode for this track"}, {0x64,0x01,"Invalid packet size"}, {0x65,0x00,"Voltage fault"}, {0x66,0x00,"Automatic document feeder cover up"}, {0x66,0x01,"Automatic document feeder lift up"}, {0x66,0x02,"Document jam in automatic document feeder"}, {0x66,0x03,"Document miss feed automatic in document feeder"}, {0x67,0x00,"Configuration failure"}, {0x67,0x01,"Configuration of incapable logical units failed"}, {0x67,0x02,"Add logical unit failed"}, {0x67,0x03,"Modification of logical unit failed"}, {0x67,0x04,"Exchange of logical unit failed"}, {0x67,0x05,"Remove of logical unit failed"}, {0x67,0x06,"Attachment of logical unit failed"}, {0x67,0x07,"Creation of logical unit failed"}, {0x67,0x08,"Assign failure occurred"}, {0x67,0x09,"Multiply assigned logical unit"}, {0x67,0x0A,"Set target port groups command failed"}, {0x67,0x0B,"ATA device feature not enabled"}, {0x68,0x00,"Logical unit not configured"}, {0x69,0x00,"Data loss on logical unit"}, {0x69,0x01,"Multiple logical unit failures"}, {0x69,0x02,"Parity/data mismatch"}, {0x6A,0x00,"Informational, refer to log"}, {0x6B,0x00,"State change has occurred"}, {0x6B,0x01,"Redundancy level got better"}, {0x6B,0x02,"Redundancy level got worse"}, {0x6C,0x00,"Rebuild failure occurred"}, {0x6D,0x00,"Recalculate failure occurred"}, {0x6E,0x00,"Command to logical unit failed"}, {0x6F,0x00,"Copy protection key exchange failure - authentication " "failure"}, {0x6F,0x01,"Copy protection key exchange failure - key not present"}, {0x6F,0x02,"Copy protection key exchange failure - key not established"}, {0x6F,0x03,"Read of scrambled sector without authentication"}, {0x6F,0x04,"Media region code is mismatched to logical unit region"}, {0x6F,0x05,"Drive region must be permanent/region reset count error"}, {0x6F,0x06,"Insufficient block count for binding nonce recording"}, {0x6F,0x07,"Conflict in binding nonce recording"}, /* * ASC 0x70 overridden by an "additional2" array entry * so there is no need to have them here. */ /* {0x70,0x00,"Decompression exception short algorithm id of nn"}, */ {0x71,0x00,"Decompression exception long algorithm id"}, {0x72,0x00,"Session fixation error"}, {0x72,0x01,"Session fixation error writing lead-in"}, {0x72,0x02,"Session fixation error writing lead-out"}, {0x72,0x03,"Session fixation error - incomplete track in session"}, {0x72,0x04,"Empty or partially written reserved track"}, {0x72,0x05,"No more track reservations allowed"}, {0x72,0x06,"RMZ extension is not allowed"}, {0x72,0x07,"No more test zone extensions are allowed"}, {0x73,0x00,"CD control error"}, {0x73,0x01,"Power calibration area almost full"}, {0x73,0x02,"Power calibration area is full"}, {0x73,0x03,"Power calibration area error"}, {0x73,0x04,"Program memory area update failure"}, {0x73,0x05,"Program memory area is full"}, {0x73,0x06,"RMA/PMA is almost full"}, {0x73,0x10,"Current power calibration area almost full"}, {0x73,0x11,"Current power calibration area is full"}, {0x73,0x17,"RDZ is full"}, {0x74,0x00,"Security error"}, {0x74,0x01,"Unable to decrypt data"}, {0x74,0x02,"Unencrypted data encountered while decrypting"}, {0x74,0x03,"Incorrect data encryption key"}, {0x74,0x04,"Cryptographic integrity validation failed"}, {0x74,0x05,"Error decrypting data"}, {0x74,0x06,"Unknown signature verification key"}, {0x74,0x07,"Encryption parameters not useable"}, {0x74,0x08,"Digital signature validation failure"}, {0x74,0x09,"Encryption mode mismatch on read"}, {0x74,0x0a,"Encrypted block not raw read enabled"}, {0x74,0x0b,"Incorrect Encryption parameters"}, {0x74,0x0c,"Unable to decrypt parameter list"}, {0x74,0x0d,"Encryption algorithm disabled"}, {0x74,0x10,"SA creation parameter value invalid"}, {0x74,0x11,"SA creation parameter value rejected"}, {0x74,0x12,"Invalid SA usage"}, {0x74,0x21,"Data encryption configuration prevented"}, {0x74,0x30,"SA creation parameter not supported"}, {0x74,0x40,"Authentication failed"}, {0x74,0x61,"External data encryption key manager access error"}, {0x74,0x62,"External data encryption key manager error"}, {0x74,0x63,"External data encryption key not found"}, {0x74,0x64,"External data encryption request not authorized"}, {0x74,0x6e,"External data encryption control timeout"}, {0x74,0x6f,"External data encryption control error"}, {0x74,0x71,"Logical unit access not authorized"}, {0x74,0x79,"Security conflict in translated device"}, {0, 0, NULL} }; const char * sg_lib_sense_key_desc[] = { "No Sense", /* Filemark, ILI and/or EOM; progress indication (during FORMAT); power condition sensing (REQUEST SENSE) */ "Recovered Error", /* The last command completed successfully but used error correction */ "Not Ready", /* The addressed target is not ready */ "Medium Error", /* Data error detected on the medium */ "Hardware Error", /* Controller or device failure */ "Illegal Request", "Unit Attention", /* Removable medium was changed, or the target has been reset */ "Data Protect", /* Access to the data is blocked */ "Blank Check", /* Reached unexpected written or unwritten region of the medium */ "Key=9", /* Vendor specific */ "Copy Aborted", /* COPY or COMPARE was aborted */ "Aborted Command", /* The target aborted the command */ "Equal", /* SEARCH DATA found data equal (obsolete) */ "Volume Overflow", /* Medium full with data to be written */ "Miscompare", /* Source data and data on the medium do not agree */ "Completed" /* may occur for successful cmd (spc4r23) */ }; const char * sg_lib_pdt_strs[] = { /* 0 */ "disk", "tape", "printer", "processor", /* often SAF-TE (seldom scanner) device */ "write once optical disk", /* 5 */ "cd/dvd", "scanner", /* obsolete */ "optical memory device", "medium changer", "communications", /* obsolete */ /* 0xa */ "graphics [0xa]", /* obsolete */ "graphics [0xb]", /* obsolete */ "storage array controller", "enclosure services device", "simplified direct access device", "optical card reader/writer device", /* 0x10 */ "bridge controller commands", "object based storage", "automation/driver interface", "security manager device", "0x14", "0x15", "0x16", "0x17", "0x18", "0x19", "0x1a", "0x1b", "0x1c", "0x1d", "well known logical unit", "no physical device on this lu", }; const char * sg_lib_transport_proto_strs[] = { "Fibre Channel (FCP-2)", "Parallel SCSI (SPI-5)", "SSA (SSA-S3P)", "IEEE 1394 (SBP-3)", "Remote Direct Memory Access (RDMA)", "Internet SCSI (iSCSI)", "Serial Attached SCSI (SAS)", "Automation/Drive Interface (ADT-2)", "ATA Packet Interface (ATA/ATAPI-7)", "Ox9", "Oxa", "Oxb", "Oxc", "Oxd", "Oxe", "No specific protocol" }; ddpt-0.92/lib/sg_pt_solaris.c0000644000175000017500000002146511351460102015156 0ustar douggdougg/* * Copyright (c) 2007-2010 Douglas Gilbert. * All rights reserved. * Use of this source code is governed by a BSD-style * license that can be found in the BSD_LICENSE file. */ /* sg_pt_solaris version 1.03 20100321 */ #include #include #include #include #include #include #include #include /* Solaris headers */ #include #include #include #include #include "sg_pt.h" #include "sg_lib.h" #ifdef HAVE_CONFIG_H #include "config.h" #endif #define DEF_TIMEOUT 60 /* 60 seconds */ struct sg_pt_solaris_scsi { struct uscsi_cmd uscsi; int max_sense_len; int in_err; int os_err; }; struct sg_pt_base { struct sg_pt_solaris_scsi impl; }; /* Returns >= 0 if successful. If error in Unix returns negated errno. */ int scsi_pt_open_device(const char * device_name, int read_only, int verbose) { int oflags = 0 /* O_NONBLOCK*/ ; oflags |= (read_only ? O_RDONLY : O_RDWR); return scsi_pt_open_flags(device_name, oflags, verbose); } /* Similar to scsi_pt_open_device() but takes Unix style open flags OR-ed * together. The 'flags' argument is ignored in Solaris. * Returns >= 0 if successful, otherwise returns negated errno. */ int scsi_pt_open_flags(const char * device_name, int flags_arg, int verbose) { int oflags = O_NONBLOCK | O_RDWR; int fd; flags_arg = flags_arg; /* ignore flags argument, suppress warning */ if (verbose > 1) { fprintf(stderr, "open %s with flags=0x%x\n", device_name, oflags); } fd = open(device_name, oflags); if (fd < 0) fd = -errno; return fd; } /* Returns 0 if successful. If error in Unix returns negated errno. */ int scsi_pt_close_device(int device_fd) { int res; res = close(device_fd); if (res < 0) res = -errno; return res; } struct sg_pt_base * construct_scsi_pt_obj() { struct sg_pt_solaris_scsi * ptp; ptp = (struct sg_pt_solaris_scsi *) calloc(1, sizeof(struct sg_pt_solaris_scsi)); if (ptp) { ptp->uscsi.uscsi_timeout = DEF_TIMEOUT; ptp->uscsi.uscsi_flags = USCSI_READ | USCSI_ISOLATE | USCSI_RQENABLE; ptp->uscsi.uscsi_timeout = DEF_TIMEOUT; } return (struct sg_pt_base *)ptp; } void destruct_scsi_pt_obj(struct sg_pt_base * vp) { struct sg_pt_solaris_scsi * ptp = &vp->impl; if (ptp) free(ptp); } void clear_scsi_pt_obj(struct sg_pt_base * vp) { struct sg_pt_solaris_scsi * ptp = &vp->impl; if (ptp) { memset(ptp, 0, sizeof(struct sg_pt_solaris_scsi)); ptp->uscsi.uscsi_timeout = DEF_TIMEOUT; ptp->uscsi.uscsi_flags = USCSI_READ | USCSI_ISOLATE | USCSI_RQENABLE; ptp->uscsi.uscsi_timeout = DEF_TIMEOUT; } } void set_scsi_pt_cdb(struct sg_pt_base * vp, const unsigned char * cdb, int cdb_len) { struct sg_pt_solaris_scsi * ptp = &vp->impl; if (ptp->uscsi.uscsi_cdb) ++ptp->in_err; ptp->uscsi.uscsi_cdb = (char *)cdb; ptp->uscsi.uscsi_cdblen = cdb_len; } void set_scsi_pt_sense(struct sg_pt_base * vp, unsigned char * sense, int max_sense_len) { struct sg_pt_solaris_scsi * ptp = &vp->impl; if (ptp->uscsi.uscsi_rqbuf) ++ptp->in_err; memset(sense, 0, max_sense_len); ptp->uscsi.uscsi_rqbuf = (char *)sense; ptp->uscsi.uscsi_rqlen = max_sense_len; ptp->max_sense_len = max_sense_len; } /* from device */ void set_scsi_pt_data_in(struct sg_pt_base * vp, unsigned char * dxferp, int dxfer_len) { struct sg_pt_solaris_scsi * ptp = &vp->impl; if (ptp->uscsi.uscsi_bufaddr) ++ptp->in_err; if (dxfer_len > 0) { ptp->uscsi.uscsi_bufaddr = (char *)dxferp; ptp->uscsi.uscsi_buflen = dxfer_len; ptp->uscsi.uscsi_flags = USCSI_READ | USCSI_ISOLATE | USCSI_RQENABLE; } } /* to device */ void set_scsi_pt_data_out(struct sg_pt_base * vp, const unsigned char * dxferp, int dxfer_len) { struct sg_pt_solaris_scsi * ptp = &vp->impl; if (ptp->uscsi.uscsi_bufaddr) ++ptp->in_err; if (dxfer_len > 0) { ptp->uscsi.uscsi_bufaddr = (char *)dxferp; ptp->uscsi.uscsi_buflen = dxfer_len; ptp->uscsi.uscsi_flags = USCSI_WRITE | USCSI_ISOLATE | USCSI_RQENABLE; } } void set_scsi_pt_packet_id(struct sg_pt_base * vp, int pack_id) { // struct sg_pt_solaris_scsi * ptp = &vp->impl; vp = vp; /* ignore and suppress warning */ pack_id = pack_id; /* ignore and suppress warning */ } void set_scsi_pt_tag(struct sg_pt_base * vp, uint64_t tag) { // struct sg_pt_solaris_scsi * ptp = &vp->impl; vp = vp; /* ignore and suppress warning */ tag = tag; /* ignore and suppress warning */ } /* Note that task management function codes are transport specific */ void set_scsi_pt_task_management(struct sg_pt_base * vp, int tmf_code) { struct sg_pt_solaris_scsi * ptp = &vp->impl; ++ptp->in_err; tmf_code = tmf_code; /* dummy to silence compiler */ } void set_scsi_pt_task_attr(struct sg_pt_base * vp, int attribute, int priority) { struct sg_pt_solaris_scsi * ptp = &vp->impl; ++ptp->in_err; attribute = attribute; /* dummy to silence compiler */ priority = priority; /* dummy to silence compiler */ } void set_scsi_pt_flags(struct sg_pt_base * objp, int flags) { /* do nothing, suppress warnings */ objp = objp; flags = flags; } /* Executes SCSI command (or at least forwards it to lower layers). * Clears os_err field prior to active call (whose result may set it * again). */ int do_scsi_pt(struct sg_pt_base * vp, int fd, int time_secs, int verbose) { struct sg_pt_solaris_scsi * ptp = &vp->impl; ptp->os_err = 0; if (ptp->in_err) { if (verbose) fprintf(stderr, "Replicated or unused set_scsi_pt... " "functions\n"); return SCSI_PT_DO_BAD_PARAMS; } if (NULL == ptp->uscsi.uscsi_cdb) { if (verbose) fprintf(stderr, "No SCSI command (cdb) given\n"); return SCSI_PT_DO_BAD_PARAMS; } if (time_secs > 0) ptp->uscsi.uscsi_timeout = time_secs; if (ioctl(fd, USCSICMD, &ptp->uscsi)) { ptp->os_err = errno; if ((EIO == ptp->os_err) && ptp->uscsi.uscsi_status) { ptp->os_err = 0; return 0; } if (verbose) fprintf(stderr, "ioctl(USCSICMD) failed with os_err " "(errno) = %d\n", ptp->os_err); return -ptp->os_err; } return 0; } int get_scsi_pt_result_category(const struct sg_pt_base * vp) { const struct sg_pt_solaris_scsi * ptp = &vp->impl; int scsi_st = ptp->uscsi.uscsi_status; if (ptp->os_err) return SCSI_PT_RESULT_OS_ERR; else if ((SAM_STAT_CHECK_CONDITION == scsi_st) || (SAM_STAT_COMMAND_TERMINATED == scsi_st)) return SCSI_PT_RESULT_SENSE; else if (scsi_st) return SCSI_PT_RESULT_STATUS; else return SCSI_PT_RESULT_GOOD; } int get_scsi_pt_resid(const struct sg_pt_base * vp) { const struct sg_pt_solaris_scsi * ptp = &vp->impl; return ptp->uscsi.uscsi_resid; } int get_scsi_pt_status_response(const struct sg_pt_base * vp) { const struct sg_pt_solaris_scsi * ptp = &vp->impl; return ptp->uscsi.uscsi_status; } int get_scsi_pt_sense_len(const struct sg_pt_base * vp) { const struct sg_pt_solaris_scsi * ptp = &vp->impl; int res; if (ptp->max_sense_len > 0) { res = ptp->max_sense_len - ptp->uscsi.uscsi_rqresid; return (res > 0) ? res : 0; } return 0; } int get_scsi_pt_duration_ms(const struct sg_pt_base * vp) { // const struct sg_pt_solaris_scsi * ptp = &vp->impl; vp = vp; /* ignore and suppress warning */ return -1; /* not available */ } int get_scsi_pt_transport_err(const struct sg_pt_base * vp) { // const struct sg_pt_solaris_scsi * ptp = &vp->impl; vp = vp; /* ignore and suppress warning */ return 0; } int get_scsi_pt_os_err(const struct sg_pt_base * vp) { const struct sg_pt_solaris_scsi * ptp = &vp->impl; return ptp->os_err; } char * get_scsi_pt_transport_err_str(const struct sg_pt_base * vp, int max_b_len, char * b) { // const struct sg_pt_solaris_scsi * ptp = &vp->impl; vp = vp; /* ignore and suppress warning */ if (max_b_len > 0) b[0] = '\0'; return b; } char * get_scsi_pt_os_err_str(const struct sg_pt_base * vp, int max_b_len, char * b) { const struct sg_pt_solaris_scsi * ptp = &vp->impl; const char * cp; cp = safe_strerror(ptp->os_err); strncpy(b, cp, max_b_len); if ((int)strlen(cp) >= max_b_len) b[max_b_len - 1] = '\0'; return b; } ddpt-0.92/lib/sg_cmds_basic.c0000644000175000017500000015326111524334352015077 0ustar douggdougg/* * Copyright (c) 1999-2011 Douglas Gilbert. * All rights reserved. * Use of this source code is governed by a BSD-style * license that can be found in the BSD_LICENSE file. */ /* * CONTENTS * Some SCSI commands are executed in many contexts and hence began * to appear in several sg3_utils utilities. This files centralizes * some of the low level command execution code. In most cases the * interpretation of the command response is left to the each * utility. */ #include #include #include #include #include "sg_lib.h" #include "sg_cmds_basic.h" #include "sg_pt.h" #ifdef HAVE_CONFIG_H #include "config.h" #endif static char * version_str = "1.51 20110207"; #define SENSE_BUFF_LEN 32 /* Arbitrary, could be larger */ #define EBUFF_SZ 256 #define DEF_PT_TIMEOUT 60 /* 60 seconds */ #define START_PT_TIMEOUT 120 /* 120 seconds == 2 minutes */ #define LONG_PT_TIMEOUT 7200 /* 7,200 seconds == 120 minutes */ #define INQUIRY_CMD 0x12 #define INQUIRY_CMDLEN 6 #define SYNCHRONIZE_CACHE_CMD 0x35 #define SYNCHRONIZE_CACHE_CMDLEN 10 #define SERVICE_ACTION_IN_16_CMD 0x9e #define SERVICE_ACTION_IN_16_CMDLEN 16 #define READ_CAPACITY_16_SA 0x10 #define READ_CAPACITY_10_CMD 0x25 #define READ_CAPACITY_10_CMDLEN 10 #define MODE_SENSE6_CMD 0x1a #define MODE_SENSE6_CMDLEN 6 #define MODE_SENSE10_CMD 0x5a #define MODE_SENSE10_CMDLEN 10 #define MODE_SELECT6_CMD 0x15 #define MODE_SELECT6_CMDLEN 6 #define MODE_SELECT10_CMD 0x55 #define MODE_SELECT10_CMDLEN 10 #define REQUEST_SENSE_CMD 0x3 #define REQUEST_SENSE_CMDLEN 6 #define REPORT_LUNS_CMD 0xa0 #define REPORT_LUNS_CMDLEN 12 #define LOG_SENSE_CMD 0x4d #define LOG_SENSE_CMDLEN 10 #define LOG_SELECT_CMD 0x4c #define LOG_SELECT_CMDLEN 10 #define TUR_CMD 0x0 #define TUR_CMDLEN 6 #define START_STOP_CMD 0x1b #define START_STOP_CMDLEN 6 #define PREVENT_ALLOW_CMD 0x1e #define PREVENT_ALLOW_CMDLEN 6 #define MODE6_RESP_HDR_LEN 4 #define MODE10_RESP_HDR_LEN 8 #define MODE_RESP_ARB_LEN 1024 #define INQUIRY_RESP_INITIAL_LEN 36 const char * sg_cmds_version() { return version_str; } /* Returns file descriptor >= 0 if successful. If error in Unix returns negated errno. */ int sg_cmds_open_device(const char * device_name, int read_only, int verbose) { return scsi_pt_open_device(device_name, read_only, verbose); } /* Returns file descriptor >= 0 if successful. If error in Unix returns negated errno. */ int sg_cmds_open_flags(const char * device_name, int flags, int verbose) { return scsi_pt_open_flags(device_name, flags, verbose); } /* Returns 0 if successful. If error in Unix returns negated errno. */ int sg_cmds_close_device(int device_fd) { return scsi_pt_close_device(device_fd); } /* This is a helper function used by all sg_cmds_* implementations. * If valid sense data is found it is decoded and output to sg_warnings_strm * (def: stderr); depending on the 'noisy' and 'verbose' settings. * Returns -2 for sense data (may not be fatal), -1 for failed, or the * number of data in bytes received. For data out (to device) or no data, * set 'mx_di_len' to 0 or less. If -2 returned then sense category * output via 'o_sense_cat' pointer (if not NULL). Note that several sense * categories also have data in bytes received; -2 is still returned. */ int sg_cmds_process_resp(struct sg_pt_base * ptvp, const char * leadin, int res, int mx_di_len, const unsigned char * sense_b, int noisy, int verbose, int * o_sense_cat) { int got, cat, duration, slen, scat, n, resid; int check_data_in = 0; char b[1024]; if (NULL == leadin) leadin = ""; if (res < 0) { if (noisy || verbose) fprintf(sg_warnings_strm, "%s: pass through os error: %s\n", leadin, safe_strerror(-res)); return -1; } else if (SCSI_PT_DO_BAD_PARAMS == res) { fprintf(sg_warnings_strm, "%s: bad pass through setup\n", leadin); return -1; } else if (SCSI_PT_DO_TIMEOUT == res) { fprintf(sg_warnings_strm, "%s: pass through timeout\n", leadin); return -1; } if ((verbose > 2) && ((duration = get_scsi_pt_duration_ms(ptvp)) >= 0)) fprintf(sg_warnings_strm, " duration=%d ms\n", duration); resid = (mx_di_len > 0) ? get_scsi_pt_resid(ptvp) : 0; switch ((cat = get_scsi_pt_result_category(ptvp))) { case SCSI_PT_RESULT_GOOD: if (mx_di_len > 0) { got = mx_di_len - resid; if (verbose && (resid > 0)) fprintf(sg_warnings_strm, " %s: requested %d bytes but " "got %d bytes\n", leadin, mx_di_len, got); return got; } else return 0; case SCSI_PT_RESULT_STATUS: /* other than GOOD and CHECK CONDITION */ if (verbose || noisy) { sg_get_scsi_status_str(get_scsi_pt_status_response(ptvp), sizeof(b), b); fprintf(sg_warnings_strm, "%s: scsi status: %s\n", leadin, b); } return -1; case SCSI_PT_RESULT_SENSE: slen = get_scsi_pt_sense_len(ptvp); scat = sg_err_category_sense(sense_b, slen); switch (scat) { case SG_LIB_CAT_NOT_READY: case SG_LIB_CAT_UNIT_ATTENTION: case SG_LIB_CAT_INVALID_OP: case SG_LIB_CAT_ILLEGAL_REQ: case SG_LIB_CAT_ABORTED_COMMAND: case SG_LIB_CAT_NO_SENSE: n = 0; break; case SG_LIB_CAT_RECOVERED: case SG_LIB_CAT_MEDIUM_HARD: ++check_data_in; default: n = noisy; break; } if (verbose || n) { sg_get_sense_str(leadin, sense_b, slen, (verbose > 1), sizeof(b), b); fprintf(sg_warnings_strm, "%s", b); if ((mx_di_len > 0) && (resid > 0)) { got = mx_di_len - resid; if ((verbose > 2) || check_data_in || (got > 0)) fprintf(sg_warnings_strm, " requested %d bytes but " "got %d bytes\n", mx_di_len, got); } } if (o_sense_cat) *o_sense_cat = scat; return -2; case SCSI_PT_RESULT_TRANSPORT_ERR: if (verbose || noisy) { get_scsi_pt_transport_err_str(ptvp, sizeof(b), b); fprintf(sg_warnings_strm, "%s: transport: %s\n", leadin, b); } return -1; case SCSI_PT_RESULT_OS_ERR: if (verbose || noisy) { get_scsi_pt_os_err_str(ptvp, sizeof(b), b); fprintf(sg_warnings_strm, "%s: os: %s\n", leadin, b); } return -1; default: fprintf(sg_warnings_strm, "%s: unknown pass through result " "category (%d)\n", leadin, cat); return -1; } } /* Invokes a SCSI INQUIRY command and yields the response * Returns 0 when successful, SG_LIB_CAT_INVALID_OP -> not supported, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_ABORTED_COMMAND, * SG_LIB_CAT_MALFORMED -> bad response, -1 -> other errors */ int sg_ll_inquiry(int sg_fd, int cmddt, int evpd, int pg_op, void * resp, int mx_resp_len, int noisy, int verbose) { int res, ret, k, sense_cat; unsigned char inqCmdBlk[INQUIRY_CMDLEN] = {INQUIRY_CMD, 0, 0, 0, 0, 0}; unsigned char sense_b[SENSE_BUFF_LEN]; unsigned char * up; struct sg_pt_base * ptvp; if (cmddt) inqCmdBlk[1] |= 2; if (evpd) inqCmdBlk[1] |= 1; inqCmdBlk[2] = (unsigned char)pg_op; /* 16 bit allocation length (was 8) is a recent SPC-3 addition */ inqCmdBlk[3] = (unsigned char)((mx_resp_len >> 8) & 0xff); inqCmdBlk[4] = (unsigned char)(mx_resp_len & 0xff); if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; if (verbose) { fprintf(sg_warnings_strm, " inquiry cdb: "); for (k = 0; k < INQUIRY_CMDLEN; ++k) fprintf(sg_warnings_strm, "%02x ", inqCmdBlk[k]); fprintf(sg_warnings_strm, "\n"); } if (resp && (mx_resp_len > 0)) { up = (unsigned char *)resp; up[0] = 0x7f; /* defensive prefill */ if (mx_resp_len > 4) up[4] = 0; } ptvp = construct_scsi_pt_obj(); if (NULL == ptvp) { fprintf(sg_warnings_strm, "inquiry: out of memory\n"); return -1; } set_scsi_pt_cdb(ptvp, inqCmdBlk, sizeof(inqCmdBlk)); set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); set_scsi_pt_data_in(ptvp, (unsigned char *)resp, mx_resp_len); res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, "inquiry", res, mx_resp_len, sense_b, noisy, verbose, &sense_cat); destruct_scsi_pt_obj(ptvp); if (-1 == ret) ; else if (-2 == ret) { switch (sense_cat) { case SG_LIB_CAT_INVALID_OP: case SG_LIB_CAT_ILLEGAL_REQ: case SG_LIB_CAT_ABORTED_COMMAND: ret = sense_cat; break; case SG_LIB_CAT_RECOVERED: case SG_LIB_CAT_NO_SENSE: ret = 0; break; default: ret = -1; break; } } else if (ret < 4) { if (verbose) fprintf(sg_warnings_strm, "inquiry: got too few " "bytes (%d)\n", ret); ret = SG_LIB_CAT_MALFORMED; } else ret = 0; return ret; } /* Yields most of first 36 bytes of a standard INQUIRY (evpd==0) response. * Returns 0 when successful, SG_LIB_CAT_INVALID_OP -> not supported, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_ABORTED_COMMAND, * SG_LIB_CAT_MALFORMED -> bad response, -1 -> other errors */ int sg_simple_inquiry(int sg_fd, struct sg_simple_inquiry_resp * inq_data, int noisy, int verbose) { int res, ret, k, sense_cat; unsigned char inqCmdBlk[INQUIRY_CMDLEN] = {INQUIRY_CMD, 0, 0, 0, 0, 0}; unsigned char sense_b[SENSE_BUFF_LEN]; unsigned char inq_resp[INQUIRY_RESP_INITIAL_LEN]; struct sg_pt_base * ptvp; if (inq_data) { memset(inq_data, 0, sizeof(* inq_data)); inq_data->peripheral_qualifier = 0x3; inq_data->peripheral_type = 0x1f; } inqCmdBlk[4] = (unsigned char)sizeof(inq_resp); if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; if (verbose) { fprintf(sg_warnings_strm, " inquiry cdb: "); for (k = 0; k < INQUIRY_CMDLEN; ++k) fprintf(sg_warnings_strm, "%02x ", inqCmdBlk[k]); fprintf(sg_warnings_strm, "\n"); } memset(inq_resp, 0, sizeof(inq_resp)); inq_resp[0] = 0x7f; /* defensive prefill */ ptvp = construct_scsi_pt_obj(); if (NULL == ptvp) { fprintf(sg_warnings_strm, "inquiry: out of memory\n"); return -1; } set_scsi_pt_cdb(ptvp, inqCmdBlk, sizeof(inqCmdBlk)); set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); set_scsi_pt_data_in(ptvp, inq_resp, sizeof(inq_resp)); res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, "inquiry", res, sizeof(inq_resp), sense_b, noisy, verbose, &sense_cat); if (-1 == ret) ; else if (-2 == ret) { switch (sense_cat) { case SG_LIB_CAT_INVALID_OP: case SG_LIB_CAT_ILLEGAL_REQ: case SG_LIB_CAT_ABORTED_COMMAND: ret = sense_cat; break; case SG_LIB_CAT_RECOVERED: case SG_LIB_CAT_NO_SENSE: ret = 0; break; default: ret = -1; break; } } else if (ret < 4) { if (verbose) fprintf(sg_warnings_strm, "inquiry: got too few " "bytes (%d)\n", ret); ret = SG_LIB_CAT_MALFORMED; } else ret = 0; if (0 == ret) { inq_data->peripheral_qualifier = (inq_resp[0] >> 5) & 0x7; inq_data->peripheral_type = inq_resp[0] & 0x1f; inq_data->rmb = (inq_resp[1] & 0x80) ? 1 : 0; inq_data->version = inq_resp[2]; inq_data->byte_3 = inq_resp[3]; inq_data->byte_5 = inq_resp[5]; inq_data->byte_6 = inq_resp[6]; inq_data->byte_7 = inq_resp[7]; memcpy(inq_data->vendor, inq_resp + 8, 8); memcpy(inq_data->product, inq_resp + 16, 16); memcpy(inq_data->revision, inq_resp + 32, 4); } destruct_scsi_pt_obj(ptvp); return ret; } /* Invokes a SCSI TEST UNIT READY command. * 'pack_id' is just for diagnostics, safe to set to 0. * Looks for progress indicator if 'progress' non-NULL; * if found writes value [0..65535] else write -1. * Return of 0 -> success, SG_LIB_CAT_UNIT_ATTENTION, * SG_LIB_CAT_ABORTED_COMMAND, SG_LIB_CAT_NOT_READY -> * device not ready, -1 -> other failure */ int sg_ll_test_unit_ready_progress(int sg_fd, int pack_id, int * progress, int noisy, int verbose) { int res, ret, k, sense_cat; unsigned char turCmdBlk[TUR_CMDLEN] = {TUR_CMD, 0, 0, 0, 0, 0}; unsigned char sense_b[SENSE_BUFF_LEN]; struct sg_pt_base * ptvp; if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; if (verbose) { fprintf(sg_warnings_strm, " test unit ready cdb: "); for (k = 0; k < TUR_CMDLEN; ++k) fprintf(sg_warnings_strm, "%02x ", turCmdBlk[k]); fprintf(sg_warnings_strm, "\n"); } ptvp = construct_scsi_pt_obj(); if (NULL == ptvp) { fprintf(sg_warnings_strm, "test unit ready: out of memory\n"); return -1; } set_scsi_pt_cdb(ptvp, turCmdBlk, sizeof(turCmdBlk)); set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); set_scsi_pt_packet_id(ptvp, pack_id); res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, "test unit ready", res, 0, sense_b, noisy, verbose, &sense_cat); if (-1 == ret) ; else if (-2 == ret) { if (progress) { int slen = get_scsi_pt_sense_len(ptvp); if (! sg_get_sense_progress_fld(sense_b, slen, progress)) *progress = -1; } switch (sense_cat) { case SG_LIB_CAT_UNIT_ATTENTION: case SG_LIB_CAT_NOT_READY: case SG_LIB_CAT_ABORTED_COMMAND: ret = sense_cat; break; case SG_LIB_CAT_RECOVERED: case SG_LIB_CAT_NO_SENSE: ret = 0; break; case SG_LIB_CAT_INVALID_OP: case SG_LIB_CAT_ILLEGAL_REQ: default: ret = -1; break; } } else ret = 0; destruct_scsi_pt_obj(ptvp); return ret; } /* Invokes a SCSI TEST UNIT READY command. * 'pack_id' is just for diagnostics, safe to set to 0. * Return of 0 -> success, SG_LIB_CAT_UNIT_ATTENTION, * SG_LIB_CAT_ABORTED_COMMAND, SG_LIB_CAT_NOT_READY -> * device not ready, -1 -> other failure */ int sg_ll_test_unit_ready(int sg_fd, int pack_id, int noisy, int verbose) { return sg_ll_test_unit_ready_progress(sg_fd, pack_id, NULL, noisy, verbose); } /* Invokes a SCSI SYNCHRONIZE CACHE (10) command. Return of 0 -> success, * SG_LIB_CAT_UNIT_ATTENTION -> repeat, * SG_LIB_CAT_INVALID_OP -> cdb not supported, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_ABORTED_COMMAND, * SG_LIB_CAT_NOT_READY -> device not ready, -1 -> other failure */ int sg_ll_sync_cache_10(int sg_fd, int sync_nv, int immed, int group, unsigned int lba, unsigned int count, int noisy, int verbose) { int res, ret, k, sense_cat; unsigned char scCmdBlk[SYNCHRONIZE_CACHE_CMDLEN] = {SYNCHRONIZE_CACHE_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0}; unsigned char sense_b[SENSE_BUFF_LEN]; struct sg_pt_base * ptvp; if (sync_nv) scCmdBlk[1] |= 4; if (immed) scCmdBlk[1] |= 2; scCmdBlk[2] = (lba >> 24) & 0xff; scCmdBlk[3] = (lba >> 16) & 0xff; scCmdBlk[4] = (lba >> 8) & 0xff; scCmdBlk[5] = lba & 0xff; scCmdBlk[6] = group & 0x1f; if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; if (count > 0xffff) { fprintf(sg_warnings_strm, "count too big\n"); return -1; } scCmdBlk[7] = (count >> 8) & 0xff; scCmdBlk[8] = count & 0xff; if (verbose) { fprintf(sg_warnings_strm, " synchronize cache(10) cdb: "); for (k = 0; k < SYNCHRONIZE_CACHE_CMDLEN; ++k) fprintf(sg_warnings_strm, "%02x ", scCmdBlk[k]); fprintf(sg_warnings_strm, "\n"); } ptvp = construct_scsi_pt_obj(); if (NULL == ptvp) { fprintf(sg_warnings_strm, "synchronize cache(10): out of memory\n"); return -1; } set_scsi_pt_cdb(ptvp, scCmdBlk, sizeof(scCmdBlk)); set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, "synchronize cache(10)", res, 0, sense_b, noisy, verbose, &sense_cat); if (-1 == ret) ; else if (-2 == ret) { switch (sense_cat) { case SG_LIB_CAT_NOT_READY: case SG_LIB_CAT_UNIT_ATTENTION: case SG_LIB_CAT_INVALID_OP: case SG_LIB_CAT_ILLEGAL_REQ: case SG_LIB_CAT_ABORTED_COMMAND: ret = sense_cat; break; case SG_LIB_CAT_RECOVERED: case SG_LIB_CAT_NO_SENSE: ret = 0; break; default: ret = -1; break; } } else ret = 0; destruct_scsi_pt_obj(ptvp); return ret; } /* Invokes a SCSI READ CAPACITY (16) command. Returns 0 -> success, * SG_LIB_CAT_UNIT_ATTENTION -> media changed??, SG_LIB_CAT_INVALID_OP * -> cdb not supported, SG_LIB_CAT_IlLEGAL_REQ -> bad field in cdb, * SG_LIB_CAT_ABORTED_COMMAND, SG_LIB_CAT_NOT_READY -> device not ready, * -1 -> other failure */ int sg_ll_readcap_16(int sg_fd, int pmi, uint64_t llba, void * resp, int mx_resp_len, int noisy, int verbose) { int k, ret, res, sense_cat; unsigned char rcCmdBlk[SERVICE_ACTION_IN_16_CMDLEN] = {SERVICE_ACTION_IN_16_CMD, READ_CAPACITY_16_SA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; unsigned char sense_b[SENSE_BUFF_LEN]; struct sg_pt_base * ptvp; if (pmi) { /* lbs only valid when pmi set */ rcCmdBlk[14] |= 1; rcCmdBlk[2] = (llba >> 56) & 0xff; rcCmdBlk[3] = (llba >> 48) & 0xff; rcCmdBlk[4] = (llba >> 40) & 0xff; rcCmdBlk[5] = (llba >> 32) & 0xff; rcCmdBlk[6] = (llba >> 24) & 0xff; rcCmdBlk[7] = (llba >> 16) & 0xff; rcCmdBlk[8] = (llba >> 8) & 0xff; rcCmdBlk[9] = llba & 0xff; } /* Allocation length, no guidance in SBC-2 rev 15b */ rcCmdBlk[10] = (mx_resp_len >> 24) & 0xff; rcCmdBlk[11] = (mx_resp_len >> 16) & 0xff; rcCmdBlk[12] = (mx_resp_len >> 8) & 0xff; rcCmdBlk[13] = mx_resp_len & 0xff; if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; if (verbose) { fprintf(sg_warnings_strm, " read capacity (16) cdb: "); for (k = 0; k < SERVICE_ACTION_IN_16_CMDLEN; ++k) fprintf(sg_warnings_strm, "%02x ", rcCmdBlk[k]); fprintf(sg_warnings_strm, "\n"); } ptvp = construct_scsi_pt_obj(); if (NULL == ptvp) { fprintf(sg_warnings_strm, "read capacity (16): out of memory\n"); return -1; } set_scsi_pt_cdb(ptvp, rcCmdBlk, sizeof(rcCmdBlk)); set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); set_scsi_pt_data_in(ptvp, (unsigned char *)resp, mx_resp_len); res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, "read capacity (16)", res, mx_resp_len, sense_b, noisy, verbose, &sense_cat); if (-1 == ret) ; else if (-2 == ret) { switch (sense_cat) { case SG_LIB_CAT_NOT_READY: case SG_LIB_CAT_UNIT_ATTENTION: case SG_LIB_CAT_INVALID_OP: case SG_LIB_CAT_ILLEGAL_REQ: case SG_LIB_CAT_ABORTED_COMMAND: ret = sense_cat; break; case SG_LIB_CAT_RECOVERED: case SG_LIB_CAT_NO_SENSE: ret = 0; break; default: ret = -1; break; } } else ret = 0; destruct_scsi_pt_obj(ptvp); return ret; } /* Invokes a SCSI READ CAPACITY (10) command. Returns 0 -> success, * SG_LIB_CAT_UNIT_ATTENTION -> media changed??, SG_LIB_CAT_INVALID_OP * -> cdb not supported, SG_LIB_CAT_IlLEGAL_REQ -> bad field in cdb, * SG_LIB_CAT_ABORTED_COMMAND, SG_LIB_CAT_NOT_READY -> device not ready, * -1 -> other failure */ int sg_ll_readcap_10(int sg_fd, int pmi, unsigned int lba, void * resp, int mx_resp_len, int noisy, int verbose) { int k, ret, res, sense_cat; unsigned char rcCmdBlk[READ_CAPACITY_10_CMDLEN] = {READ_CAPACITY_10_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0}; unsigned char sense_b[SENSE_BUFF_LEN]; struct sg_pt_base * ptvp; if (pmi) { /* lbs only valid when pmi set */ rcCmdBlk[8] |= 1; rcCmdBlk[2] = (lba >> 24) & 0xff; rcCmdBlk[3] = (lba >> 16) & 0xff; rcCmdBlk[4] = (lba >> 8) & 0xff; rcCmdBlk[5] = lba & 0xff; } if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; if (verbose) { fprintf(sg_warnings_strm, " read capacity (10) cdb: "); for (k = 0; k < READ_CAPACITY_10_CMDLEN; ++k) fprintf(sg_warnings_strm, "%02x ", rcCmdBlk[k]); fprintf(sg_warnings_strm, "\n"); } ptvp = construct_scsi_pt_obj(); if (NULL == ptvp) { fprintf(sg_warnings_strm, "read capacity (10): out of memory\n"); return -1; } set_scsi_pt_cdb(ptvp, rcCmdBlk, sizeof(rcCmdBlk)); set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); set_scsi_pt_data_in(ptvp, (unsigned char *)resp, mx_resp_len); res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, "read capacity (10)", res, mx_resp_len, sense_b, noisy, verbose, &sense_cat); if (-1 == ret) ; else if (-2 == ret) { switch (sense_cat) { case SG_LIB_CAT_NOT_READY: case SG_LIB_CAT_UNIT_ATTENTION: case SG_LIB_CAT_INVALID_OP: case SG_LIB_CAT_ILLEGAL_REQ: case SG_LIB_CAT_ABORTED_COMMAND: ret = sense_cat; break; case SG_LIB_CAT_RECOVERED: case SG_LIB_CAT_NO_SENSE: ret = 0; break; default: ret = -1; break; } } else ret = 0; destruct_scsi_pt_obj(ptvp); return ret; } /* Invokes a SCSI MODE SENSE (6) command. Return of 0 -> success, * SG_LIB_CAT_INVALID_OP -> invalid opcode, SG_LIB_CAT_ILLEGAL_REQ -> * bad field in cdb, * SG_LIB_CAT_NOT_READY -> device not ready, * SG_LIB_CAT_ABORTED_COMMAND, SG_LIB_CAT_UNIT_ATTENTION, * -1 -> other failure */ int sg_ll_mode_sense6(int sg_fd, int dbd, int pc, int pg_code, int sub_pg_code, void * resp, int mx_resp_len, int noisy, int verbose) { int res, ret, k, sense_cat; unsigned char modesCmdBlk[MODE_SENSE6_CMDLEN] = {MODE_SENSE6_CMD, 0, 0, 0, 0, 0}; unsigned char sense_b[SENSE_BUFF_LEN]; struct sg_pt_base * ptvp; modesCmdBlk[1] = (unsigned char)(dbd ? 0x8 : 0); modesCmdBlk[2] = (unsigned char)(((pc << 6) & 0xc0) | (pg_code & 0x3f)); modesCmdBlk[3] = (unsigned char)(sub_pg_code & 0xff); modesCmdBlk[4] = (unsigned char)(mx_resp_len & 0xff); if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; if (mx_resp_len > 0xff) { fprintf(sg_warnings_strm, "mx_resp_len too big\n"); return -1; } if (verbose) { fprintf(sg_warnings_strm, " mode sense (6) cdb: "); for (k = 0; k < MODE_SENSE6_CMDLEN; ++k) fprintf(sg_warnings_strm, "%02x ", modesCmdBlk[k]); fprintf(sg_warnings_strm, "\n"); } ptvp = construct_scsi_pt_obj(); if (NULL == ptvp) { fprintf(sg_warnings_strm, "mode sense (6): out of memory\n"); return -1; } set_scsi_pt_cdb(ptvp, modesCmdBlk, sizeof(modesCmdBlk)); set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); set_scsi_pt_data_in(ptvp, (unsigned char *)resp, mx_resp_len); res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, "mode sense (6)", res, mx_resp_len, sense_b, noisy, verbose, &sense_cat); if (-1 == ret) ; else if (-2 == ret) { switch (sense_cat) { case SG_LIB_CAT_NOT_READY: case SG_LIB_CAT_INVALID_OP: case SG_LIB_CAT_ILLEGAL_REQ: case SG_LIB_CAT_UNIT_ATTENTION: case SG_LIB_CAT_ABORTED_COMMAND: ret = sense_cat; break; case SG_LIB_CAT_RECOVERED: case SG_LIB_CAT_NO_SENSE: ret = 0; break; default: ret = -1; break; } } else { if ((verbose > 2) && (ret > 0)) { fprintf(sg_warnings_strm, " mode sense (6): response%s\n", (ret > 256 ? ", first 256 bytes" : "")); dStrHex((const char *)resp, (ret > 256 ? 256 : ret), -1); } ret = 0; } destruct_scsi_pt_obj(ptvp); return ret; } /* Invokes a SCSI MODE SENSE (10) command. Return of 0 -> success, * SG_LIB_CAT_INVALID_OP -> invalid opcode, SG_LIB_CAT_ILLEGAL_REQ -> * bad field in cdb, * SG_LIB_CAT_NOT_READY -> device not ready, * SG_LIB_CAT_ABORTED_COMMAND, SG_LIB_CAT_UNIT_ATTENTION, * -1 -> other failure */ int sg_ll_mode_sense10(int sg_fd, int llbaa, int dbd, int pc, int pg_code, int sub_pg_code, void * resp, int mx_resp_len, int noisy, int verbose) { int res, ret, k, sense_cat; unsigned char modesCmdBlk[MODE_SENSE10_CMDLEN] = {MODE_SENSE10_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0}; unsigned char sense_b[SENSE_BUFF_LEN]; struct sg_pt_base * ptvp; modesCmdBlk[1] = (unsigned char)((dbd ? 0x8 : 0) | (llbaa ? 0x10 : 0)); modesCmdBlk[2] = (unsigned char)(((pc << 6) & 0xc0) | (pg_code & 0x3f)); modesCmdBlk[3] = (unsigned char)(sub_pg_code & 0xff); modesCmdBlk[7] = (unsigned char)((mx_resp_len >> 8) & 0xff); modesCmdBlk[8] = (unsigned char)(mx_resp_len & 0xff); if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; if (mx_resp_len > 0xffff) { fprintf(sg_warnings_strm, "mx_resp_len too big\n"); return -1; } if (verbose) { fprintf(sg_warnings_strm, " mode sense (10) cdb: "); for (k = 0; k < MODE_SENSE10_CMDLEN; ++k) fprintf(sg_warnings_strm, "%02x ", modesCmdBlk[k]); fprintf(sg_warnings_strm, "\n"); } ptvp = construct_scsi_pt_obj(); if (NULL == ptvp) { fprintf(sg_warnings_strm, "mode sense (10): out of memory\n"); return -1; } set_scsi_pt_cdb(ptvp, modesCmdBlk, sizeof(modesCmdBlk)); set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); set_scsi_pt_data_in(ptvp, (unsigned char *)resp, mx_resp_len); res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, "mode sense (10)", res, mx_resp_len, sense_b, noisy, verbose, &sense_cat); if (-1 == ret) ; else if (-2 == ret) { switch (sense_cat) { case SG_LIB_CAT_NOT_READY: case SG_LIB_CAT_INVALID_OP: case SG_LIB_CAT_ILLEGAL_REQ: case SG_LIB_CAT_UNIT_ATTENTION: case SG_LIB_CAT_ABORTED_COMMAND: ret = sense_cat; break; case SG_LIB_CAT_RECOVERED: case SG_LIB_CAT_NO_SENSE: ret = 0; break; default: ret = -1; break; } } else { if ((verbose > 2) && (ret > 0)) { fprintf(sg_warnings_strm, " mode sense (10): response%s\n", (ret > 256 ? ", first 256 bytes" : "")); dStrHex((const char *)resp, (ret > 256 ? 256 : ret), -1); } ret = 0; } destruct_scsi_pt_obj(ptvp); return ret; } /* Invokes a SCSI MODE SELECT (6) command. Return of 0 -> success, * SG_LIB_CAT_INVALID_OP -> invalid opcode, SG_LIB_CAT_ILLEGAL_REQ -> * bad field in cdb, * SG_LIB_CAT_NOT_READY -> device not ready, * SG_LIB_CAT_ABORTED_COMMAND, SG_LIB_CAT_UNIT_ATTENTION, * -1 -> other failure */ int sg_ll_mode_select6(int sg_fd, int pf, int sp, void * paramp, int param_len, int noisy, int verbose) { int res, ret, k, sense_cat; unsigned char modesCmdBlk[MODE_SELECT6_CMDLEN] = {MODE_SELECT6_CMD, 0, 0, 0, 0, 0}; unsigned char sense_b[SENSE_BUFF_LEN]; struct sg_pt_base * ptvp; modesCmdBlk[1] = (unsigned char)(((pf << 4) & 0x10) | (sp & 0x1)); modesCmdBlk[4] = (unsigned char)(param_len & 0xff); if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; if (param_len > 0xff) { fprintf(sg_warnings_strm, "mode select (6): param_len too big\n"); return -1; } if (verbose) { fprintf(sg_warnings_strm, " mode select (6) cdb: "); for (k = 0; k < MODE_SELECT6_CMDLEN; ++k) fprintf(sg_warnings_strm, "%02x ", modesCmdBlk[k]); fprintf(sg_warnings_strm, "\n"); } if (verbose > 1) { fprintf(sg_warnings_strm, " mode select (6) parameter list\n"); dStrHex((const char *)paramp, param_len, -1); } ptvp = construct_scsi_pt_obj(); if (NULL == ptvp) { fprintf(sg_warnings_strm, "mode select (6): out of memory\n"); return -1; } set_scsi_pt_cdb(ptvp, modesCmdBlk, sizeof(modesCmdBlk)); set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); set_scsi_pt_data_out(ptvp, (unsigned char *)paramp, param_len); res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, "mode select (6)", res, 0, sense_b, noisy, verbose, &sense_cat); if (-1 == ret) ; else if (-2 == ret) { switch (sense_cat) { case SG_LIB_CAT_NOT_READY: case SG_LIB_CAT_INVALID_OP: case SG_LIB_CAT_ILLEGAL_REQ: case SG_LIB_CAT_UNIT_ATTENTION: case SG_LIB_CAT_ABORTED_COMMAND: ret = sense_cat; break; case SG_LIB_CAT_RECOVERED: case SG_LIB_CAT_NO_SENSE: ret = 0; break; default: ret = -1; break; } } else ret = 0; destruct_scsi_pt_obj(ptvp); return ret; } /* Invokes a SCSI MODE SELECT (10) command. Return of 0 -> success, * SG_LIB_CAT_INVALID_OP -> invalid opcode, SG_LIB_CAT_ILLEGAL_REQ -> * bad field in cdb, * SG_LIB_CAT_NOT_READY -> device not ready, * SG_LIB_CAT_ABORTED_COMMAND, SG_LIB_CAT_UNIT_ATTENTION, * -1 -> other failure */ int sg_ll_mode_select10(int sg_fd, int pf, int sp, void * paramp, int param_len, int noisy, int verbose) { int res, ret, k, sense_cat; unsigned char modesCmdBlk[MODE_SELECT10_CMDLEN] = {MODE_SELECT10_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0}; unsigned char sense_b[SENSE_BUFF_LEN]; struct sg_pt_base * ptvp; modesCmdBlk[1] = (unsigned char)(((pf << 4) & 0x10) | (sp & 0x1)); modesCmdBlk[7] = (unsigned char)((param_len >> 8) & 0xff); modesCmdBlk[8] = (unsigned char)(param_len & 0xff); if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; if (param_len > 0xffff) { fprintf(sg_warnings_strm, "mode select (10): param_len too big\n"); return -1; } if (verbose) { fprintf(sg_warnings_strm, " mode select (10) cdb: "); for (k = 0; k < MODE_SELECT10_CMDLEN; ++k) fprintf(sg_warnings_strm, "%02x ", modesCmdBlk[k]); fprintf(sg_warnings_strm, "\n"); } if (verbose > 1) { fprintf(sg_warnings_strm, " mode select (10) parameter list\n"); dStrHex((const char *)paramp, param_len, -1); } ptvp = construct_scsi_pt_obj(); if (NULL == ptvp) { fprintf(sg_warnings_strm, "mode select (10): out of memory\n"); return -1; } set_scsi_pt_cdb(ptvp, modesCmdBlk, sizeof(modesCmdBlk)); set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); set_scsi_pt_data_out(ptvp, (unsigned char *)paramp, param_len); res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, "mode select (10)", res, 0, sense_b, noisy, verbose, &sense_cat); if (-1 == ret) ; else if (-2 == ret) { switch (sense_cat) { case SG_LIB_CAT_NOT_READY: case SG_LIB_CAT_INVALID_OP: case SG_LIB_CAT_ILLEGAL_REQ: case SG_LIB_CAT_UNIT_ATTENTION: case SG_LIB_CAT_ABORTED_COMMAND: ret = sense_cat; break; case SG_LIB_CAT_RECOVERED: case SG_LIB_CAT_NO_SENSE: ret = 0; break; default: ret = -1; break; } } else ret = 0; destruct_scsi_pt_obj(ptvp); return ret; } /* MODE SENSE commands yield a response that has block descriptors followed * by mode pages. In most cases users are interested in the first mode page. * This function returns the (byte) offset of the start of the first mode * page. Set mode_sense_6 to 1 for MODE SENSE (6) and 0 for MODE SENSE (10). * Returns >= 0 is successful or -1 if failure. If there is a failure * a message is written to err_buff. */ int sg_mode_page_offset(const unsigned char * resp, int resp_len, int mode_sense_6, char * err_buff, int err_buff_len) { int bd_len; int calc_len; int offset; if ((NULL == resp) || (resp_len < 4) || ((! mode_sense_6) && (resp_len < 8))) { snprintf(err_buff, err_buff_len, "given response length too short: " "%d\n", resp_len); return -1; } if (mode_sense_6) { calc_len = resp[0] + 1; bd_len = resp[3]; offset = bd_len + MODE6_RESP_HDR_LEN; } else { calc_len = (resp[0] << 8) + resp[1] + 2; bd_len = (resp[6] << 8) + resp[7]; /* LongLBA doesn't change this calculation */ offset = bd_len + MODE10_RESP_HDR_LEN; } if ((offset + 2) > resp_len) { snprintf(err_buff, err_buff_len, "given response length " "too small, offset=%d given_len=%d bd_len=%d\n", offset, resp_len, bd_len); offset = -1; } else if ((offset + 2) > calc_len) { snprintf(err_buff, err_buff_len, "calculated response " "length too small, offset=%d calc_len=%d bd_len=%d\n", offset, calc_len, bd_len); offset = -1; } return offset; } /* Fetches current, changeable, default and/or saveable modes pages as * indicated by pcontrol_arr for given pg_code and sub_pg_code. If * mode6==0 then use MODE SENSE (10) else use MODE SENSE (6). If * flexible set and mode data length seems wrong then try and * fix (compensating hack for bad device or driver). pcontrol_arr * should have 4 elements for output of current, changeable, default * and saved values respectively. Each element should be NULL or * at least mx_mpage_len bytes long. * Return of 0 -> overall success, SG_LIB_CAT_INVALID_OP -> invalid opcode, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_UNIT_ATTENTION, * SG_LIB_CAT_NOT_READY -> device not ready, * SG_LIB_CAT_MALFORMED -> bad response, -1 -> other failure. * If success_mask pointer is not NULL then first zeros it. Then set bits * 0, 1, 2 and/or 3 if the current, changeable, default and saved values * respectively have been fetched. If error on current page * then stops and returns that error; otherwise continues if an error is * detected but returns the first error encountered. */ int sg_get_mode_page_controls(int sg_fd, int mode6, int pg_code, int sub_pg_code, int dbd, int flexible, int mx_mpage_len, int * success_mask, void * pcontrol_arr[], int * reported_len, int verbose) { int k, n, res, offset, calc_len, xfer_len, resp_mode6; unsigned char buff[MODE_RESP_ARB_LEN]; char ebuff[EBUFF_SZ]; int first_err = 0; if (success_mask) *success_mask = 0; if (reported_len) *reported_len = 0; if (mx_mpage_len < 4) return 0; if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; memset(ebuff, 0, sizeof(ebuff)); /* first try to find length of current page response */ memset(buff, 0, MODE10_RESP_HDR_LEN); if (mode6) /* want first 8 bytes just in case */ res = sg_ll_mode_sense6(sg_fd, dbd, 0 /* pc */, pg_code, sub_pg_code, buff, MODE10_RESP_HDR_LEN, 0, verbose); else res = sg_ll_mode_sense10(sg_fd, 0 /* llbaa */, dbd, 0 /* pc */, pg_code, sub_pg_code, buff, MODE10_RESP_HDR_LEN, 0, verbose); if (0 != res) return res; n = buff[0]; if (reported_len) *reported_len = mode6 ? (n + 1) : ((n << 8) + buff[1] + 2); resp_mode6 = mode6; if (flexible) { if (mode6 && (n < 3)) { resp_mode6 = 0; if (verbose) fprintf(sg_warnings_strm, ">>> msense(6) but resp[0]=%d so " "try msense(10) response processing\n", n); } if ((0 == mode6) && (n > 5)) { if ((n > 11) && (0 == (n % 2)) && (0 == buff[4]) && (0 == buff[5]) && (0 == buff[6])) { buff[1] = n; buff[0] = 0; if (verbose) fprintf(sg_warnings_strm, ">>> msense(10) but resp[0]=%d " "and not msense(6) response so fix length\n", n); } else resp_mode6 = 1; } } if (verbose && (resp_mode6 != mode6)) fprintf(sg_warnings_strm, ">>> msense(%d) but resp[0]=%d " "so switch response processing\n", (mode6 ? 6 : 10), buff[0]); calc_len = resp_mode6 ? (buff[0] + 1) : ((buff[0] << 8) + buff[1] + 2); if (calc_len > MODE_RESP_ARB_LEN) calc_len = MODE_RESP_ARB_LEN; offset = sg_mode_page_offset(buff, calc_len, resp_mode6, ebuff, EBUFF_SZ); if (offset < 0) { if (('\0' != ebuff[0]) && (verbose > 0)) fprintf(sg_warnings_strm, "sg_get_mode_page_controls: %s\n", ebuff); return SG_LIB_CAT_MALFORMED; } xfer_len = calc_len - offset; if (xfer_len > mx_mpage_len) xfer_len = mx_mpage_len; for (k = 0; k < 4; ++k) { if (NULL == pcontrol_arr[k]) continue; memset(pcontrol_arr[k], 0, mx_mpage_len); if (mode6) res = sg_ll_mode_sense6(sg_fd, dbd, k /* pc */, pg_code, sub_pg_code, buff, calc_len, 0, verbose); else res = sg_ll_mode_sense10(sg_fd, 0 /* llbaa */, dbd, k /* pc */, pg_code, sub_pg_code, buff, calc_len, 0, verbose); if (0 != res) { if (0 == first_err) first_err = res; if (0 == k) break; /* if problem on current page, it won't improve */ else continue; } if (xfer_len > 0) memcpy(pcontrol_arr[k], buff + offset, xfer_len); if (success_mask) *success_mask |= (1 << k); } return first_err; } /* Invokes a SCSI REQUEST SENSE command. Return of 0 -> success, * SG_LIB_CAT_INVALID_OP -> Request Sense not supported??, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, * SG_LIB_CAT_ABORTED_COMMAND, -1 -> other failure */ int sg_ll_request_sense(int sg_fd, int desc, void * resp, int mx_resp_len, int noisy, int verbose) { int k, ret, res, sense_cat; unsigned char rsCmdBlk[REQUEST_SENSE_CMDLEN] = {REQUEST_SENSE_CMD, 0, 0, 0, 0, 0}; unsigned char sense_b[SENSE_BUFF_LEN]; struct sg_pt_base * ptvp; if (desc) rsCmdBlk[1] |= 0x1; if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; if (mx_resp_len > 0xff) { fprintf(sg_warnings_strm, "mx_resp_len cannot exceed 255\n"); return -1; } rsCmdBlk[4] = mx_resp_len & 0xff; if (verbose) { fprintf(sg_warnings_strm, " Request Sense cmd: "); for (k = 0; k < REQUEST_SENSE_CMDLEN; ++k) fprintf(sg_warnings_strm, "%02x ", rsCmdBlk[k]); fprintf(sg_warnings_strm, "\n"); } ptvp = construct_scsi_pt_obj(); if (NULL == ptvp) { fprintf(sg_warnings_strm, "request sense: out of memory\n"); return -1; } set_scsi_pt_cdb(ptvp, rsCmdBlk, sizeof(rsCmdBlk)); set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); set_scsi_pt_data_in(ptvp, (unsigned char *)resp, mx_resp_len); res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, "request sense", res, mx_resp_len, sense_b, noisy, verbose, &sense_cat); if (-1 == ret) ; else if (-2 == ret) { switch (sense_cat) { case SG_LIB_CAT_INVALID_OP: case SG_LIB_CAT_ILLEGAL_REQ: case SG_LIB_CAT_ABORTED_COMMAND: ret = sense_cat; break; case SG_LIB_CAT_RECOVERED: case SG_LIB_CAT_NO_SENSE: ret = 0; break; case SG_LIB_CAT_NOT_READY: /* shouldn't happen ?? */ default: ret = -1; break; } } else { if ((mx_resp_len >= 8) && (ret < 8)) { if (verbose) fprintf(sg_warnings_strm, " request sense: got %d " "bytes in response, too short\n", ret); ret = -1; } else ret = 0; } destruct_scsi_pt_obj(ptvp); return ret; } /* Invokes a SCSI REPORT LUNS command. Return of 0 -> success, * SG_LIB_CAT_INVALID_OP -> Report Luns not supported, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, * SG_LIB_CAT_ABORTED_COMMAND, * SG_LIB_NOT_READY (shouldn't happen), -1 -> other failure */ int sg_ll_report_luns(int sg_fd, int select_report, void * resp, int mx_resp_len, int noisy, int verbose) { int k, ret, res, sense_cat; unsigned char rlCmdBlk[REPORT_LUNS_CMDLEN] = {REPORT_LUNS_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; unsigned char sense_b[SENSE_BUFF_LEN]; struct sg_pt_base * ptvp; rlCmdBlk[2] = select_report & 0xff; rlCmdBlk[6] = (mx_resp_len >> 24) & 0xff; rlCmdBlk[7] = (mx_resp_len >> 16) & 0xff; rlCmdBlk[8] = (mx_resp_len >> 8) & 0xff; rlCmdBlk[9] = mx_resp_len & 0xff; if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; if (verbose) { fprintf(sg_warnings_strm, " report luns cdb: "); for (k = 0; k < REPORT_LUNS_CMDLEN; ++k) fprintf(sg_warnings_strm, "%02x ", rlCmdBlk[k]); fprintf(sg_warnings_strm, "\n"); } ptvp = construct_scsi_pt_obj(); if (NULL == ptvp) { fprintf(sg_warnings_strm, "report luns: out of memory\n"); return -1; } set_scsi_pt_cdb(ptvp, rlCmdBlk, sizeof(rlCmdBlk)); set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); set_scsi_pt_data_in(ptvp, (unsigned char *)resp, mx_resp_len); res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, "report luns", res, mx_resp_len, sense_b, noisy, verbose, &sense_cat); if (-1 == ret) ; else if (-2 == ret) { switch (sense_cat) { case SG_LIB_CAT_INVALID_OP: case SG_LIB_CAT_ILLEGAL_REQ: case SG_LIB_CAT_ABORTED_COMMAND: case SG_LIB_CAT_NOT_READY: /* shouldn't happen ?? */ ret = sense_cat; break; case SG_LIB_CAT_RECOVERED: case SG_LIB_CAT_NO_SENSE: ret = 0; break; default: ret = -1; break; } } else ret = 0; destruct_scsi_pt_obj(ptvp); return ret; } /* Invokes a SCSI LOG SENSE command. Return of 0 -> success, * SG_LIB_CAT_INVALID_OP -> Log Sense not supported, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_UNIT_ATTENTION, * SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND, * -1 -> other failure */ int sg_ll_log_sense(int sg_fd, int ppc, int sp, int pc, int pg_code, int subpg_code, int paramp, unsigned char * resp, int mx_resp_len, int noisy, int verbose) { int res, ret, k, sense_cat; unsigned char logsCmdBlk[LOG_SENSE_CMDLEN] = {LOG_SENSE_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0}; unsigned char sense_b[SENSE_BUFF_LEN]; struct sg_pt_base * ptvp; if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; if (mx_resp_len > 0xffff) { fprintf(sg_warnings_strm, "mx_resp_len too big\n"); return -1; } logsCmdBlk[1] = (unsigned char)((ppc ? 2 : 0) | (sp ? 1 : 0)); logsCmdBlk[2] = (unsigned char)(((pc << 6) & 0xc0) | (pg_code & 0x3f)); logsCmdBlk[3] = (unsigned char)(subpg_code & 0xff); logsCmdBlk[5] = (unsigned char)((paramp >> 8) & 0xff); logsCmdBlk[6] = (unsigned char)(paramp & 0xff); logsCmdBlk[7] = (unsigned char)((mx_resp_len >> 8) & 0xff); logsCmdBlk[8] = (unsigned char)(mx_resp_len & 0xff); if (verbose) { fprintf(sg_warnings_strm, " log sense cdb: "); for (k = 0; k < LOG_SENSE_CMDLEN; ++k) fprintf(sg_warnings_strm, "%02x ", logsCmdBlk[k]); fprintf(sg_warnings_strm, "\n"); } ptvp = construct_scsi_pt_obj(); if (NULL == ptvp) { fprintf(sg_warnings_strm, "log sense: out of memory\n"); return -1; } set_scsi_pt_cdb(ptvp, logsCmdBlk, sizeof(logsCmdBlk)); set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); set_scsi_pt_data_in(ptvp, resp, mx_resp_len); res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, "log sense", res, mx_resp_len, sense_b, noisy, verbose, &sense_cat); if (-1 == ret) ; else if (-2 == ret) { switch (sense_cat) { case SG_LIB_CAT_NOT_READY: case SG_LIB_CAT_INVALID_OP: case SG_LIB_CAT_ILLEGAL_REQ: case SG_LIB_CAT_UNIT_ATTENTION: case SG_LIB_CAT_ABORTED_COMMAND: ret = sense_cat; break; case SG_LIB_CAT_RECOVERED: case SG_LIB_CAT_NO_SENSE: ret = 0; break; default: ret = -1; break; } } else ret = 0; destruct_scsi_pt_obj(ptvp); return ret; } /* Invokes a SCSI LOG SELECT command. Return of 0 -> success, * SG_LIB_CAT_INVALID_OP -> Log Select not supported, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_UNIT_ATTENTION, * SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND, * -1 -> other failure */ int sg_ll_log_select(int sg_fd, int pcr, int sp, int pc, int pg_code, int subpg_code, unsigned char * paramp, int param_len, int noisy, int verbose) { int res, ret, k, sense_cat; unsigned char logsCmdBlk[LOG_SELECT_CMDLEN] = {LOG_SELECT_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0}; unsigned char sense_b[SENSE_BUFF_LEN]; struct sg_pt_base * ptvp; if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; if (param_len > 0xffff) { fprintf(sg_warnings_strm, "log select: param_len too big\n"); return -1; } logsCmdBlk[1] = (unsigned char)((pcr ? 2 : 0) | (sp ? 1 : 0)); logsCmdBlk[2] = (unsigned char)(((pc << 6) & 0xc0) | (pg_code & 0x3f)); logsCmdBlk[3] = (unsigned char)(subpg_code & 0xff); logsCmdBlk[7] = (unsigned char)((param_len >> 8) & 0xff); logsCmdBlk[8] = (unsigned char)(param_len & 0xff); if (verbose) { fprintf(sg_warnings_strm, " log select cdb: "); for (k = 0; k < LOG_SELECT_CMDLEN; ++k) fprintf(sg_warnings_strm, "%02x ", logsCmdBlk[k]); fprintf(sg_warnings_strm, "\n"); } if ((verbose > 1) && (param_len > 0)) { fprintf(sg_warnings_strm, " log select parameter list\n"); dStrHex((const char *)paramp, param_len, -1); } ptvp = construct_scsi_pt_obj(); if (NULL == ptvp) { fprintf(sg_warnings_strm, "log select: out of memory\n"); return -1; } set_scsi_pt_cdb(ptvp, logsCmdBlk, sizeof(logsCmdBlk)); set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); set_scsi_pt_data_out(ptvp, paramp, param_len); res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, "log select", res, 0, sense_b, noisy, verbose, &sense_cat); if (-1 == ret) ; else if (-2 == ret) { switch (sense_cat) { case SG_LIB_CAT_NOT_READY: case SG_LIB_CAT_INVALID_OP: case SG_LIB_CAT_ILLEGAL_REQ: case SG_LIB_CAT_UNIT_ATTENTION: case SG_LIB_CAT_ABORTED_COMMAND: ret = sense_cat; break; case SG_LIB_CAT_RECOVERED: case SG_LIB_CAT_NO_SENSE: ret = 0; break; default: ret = -1; break; } } else ret = 0; destruct_scsi_pt_obj(ptvp); return ret; } /* Invokes a SCSI START STOP UNIT command (SBC + MMC). * Return of 0 -> success, * SG_LIB_CAT_INVALID_OP -> Start stop unit not supported, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_UNIT_ATTENTION, * SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND, * -1 -> other failure * SBC-3 and MMC partially overlap on the power_condition_modifier(sbc) and * format_layer_number(mmc) fields. They also overlap on the noflush(sbc) * and fl(mmc) one bit field. This is the cause of the awkardly named * pc_mod__fl_num and noflush__fl arguments to this function. * */ int sg_ll_start_stop_unit(int sg_fd, int immed, int pc_mod__fl_num, int power_cond, int noflush__fl, int loej, int start, int noisy, int verbose) { unsigned char ssuBlk[START_STOP_CMDLEN] = {START_STOP_CMD, 0, 0, 0, 0, 0}; unsigned char sense_b[SENSE_BUFF_LEN]; int k, res, ret, sense_cat; struct sg_pt_base * ptvp; ssuBlk[1] = immed & 1; ssuBlk[3] = pc_mod__fl_num & 0xf; /* bits 2 and 3 are reserved in MMC */ ssuBlk[4] = ((power_cond & 0xf) << 4) | (noflush__fl ? 0x4 : 0) | (loej ? 0x2 : 0) | (start ? 0x1 : 0); if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; if (verbose) { fprintf(sg_warnings_strm, " Start stop unit command:"); for (k = 0; k < (int)sizeof(ssuBlk); ++k) fprintf (sg_warnings_strm, " %02x", ssuBlk[k]); fprintf(sg_warnings_strm, "\n"); } ptvp = construct_scsi_pt_obj(); if (NULL == ptvp) { fprintf(sg_warnings_strm, "start stop unit: out of memory\n"); return -1; } set_scsi_pt_cdb(ptvp, ssuBlk, sizeof(ssuBlk)); set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); res = do_scsi_pt(ptvp, sg_fd, START_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, "start stop unit", res, 0, sense_b, noisy, verbose, &sense_cat); if (-1 == ret) ; else if (-2 == ret) { switch (sense_cat) { case SG_LIB_CAT_NOT_READY: case SG_LIB_CAT_INVALID_OP: case SG_LIB_CAT_ILLEGAL_REQ: case SG_LIB_CAT_UNIT_ATTENTION: case SG_LIB_CAT_ABORTED_COMMAND: ret = sense_cat; break; case SG_LIB_CAT_RECOVERED: case SG_LIB_CAT_NO_SENSE: ret = 0; break; default: ret = -1; break; } } else ret = 0; destruct_scsi_pt_obj(ptvp); return ret; } /* Invokes a SCSI PREVENT ALLOW MEDIUM REMOVAL command * [was in SPC-3 but displaced from SPC-4 into SBC-3, MMC-5, SSC-3] * prevent==0 allows removal, prevent==1 prevents removal ... * Return of 0 -> success, * SG_LIB_CAT_INVALID_OP -> command not supported * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_UNIT_ATTENTION, * SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND, * -1 -> other failure */ int sg_ll_prevent_allow(int sg_fd, int prevent, int noisy, int verbose) { int k, res, ret, sense_cat; unsigned char pCmdBlk[PREVENT_ALLOW_CMDLEN] = {PREVENT_ALLOW_CMD, 0, 0, 0, 0, 0}; unsigned char sense_b[SENSE_BUFF_LEN]; struct sg_pt_base * ptvp; if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; if ((prevent < 0) || (prevent > 3)) { fprintf(sg_warnings_strm, "prevent argument should be 0, 1, 2 or 3\n"); return -1; } pCmdBlk[4] |= (prevent & 0x3); if (verbose) { fprintf(sg_warnings_strm, " Prevent allow medium removal cdb: "); for (k = 0; k < PREVENT_ALLOW_CMDLEN; ++k) fprintf(sg_warnings_strm, "%02x ", pCmdBlk[k]); fprintf(sg_warnings_strm, "\n"); } ptvp = construct_scsi_pt_obj(); if (NULL == ptvp) { fprintf(sg_warnings_strm, "prevent allow medium removal: out of " "memory\n"); return -1; } set_scsi_pt_cdb(ptvp, pCmdBlk, sizeof(pCmdBlk)); set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, "prevent allow medium removal", res, 0, sense_b, noisy, verbose, &sense_cat); if (-1 == ret) ; else if (-2 == ret) { switch (sense_cat) { case SG_LIB_CAT_NOT_READY: case SG_LIB_CAT_INVALID_OP: case SG_LIB_CAT_ILLEGAL_REQ: case SG_LIB_CAT_UNIT_ATTENTION: case SG_LIB_CAT_ABORTED_COMMAND: ret = sense_cat; break; case SG_LIB_CAT_RECOVERED: case SG_LIB_CAT_NO_SENSE: ret = 0; break; default: ret = -1; break; } } else ret = 0; destruct_scsi_pt_obj(ptvp); return ret; } ddpt-0.92/lib/Makefile.in0000644000175000017500000006021411446023005014204 0ustar douggdougg# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, # Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = lib DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__installdirs = "$(DESTDIR)$(libdir)" LTLIBRARIES = $(lib_LTLIBRARIES) am__libsgutils2_la_SOURCES_DIST = sg_lib.c sg_lib_data.c \ sg_cmds_basic.c sg_cmds_extra.c sg_cmds_mmc.c sg_pt_common.c \ sg_pt_freebsd.c sg_pt_linux.c sg_io_linux.c sg_pt_osf1.c \ sg_pt_solaris.c sg_pt_win32.c @OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_FALSE@@OS_WIN32_MINGW_TRUE@am_libsgutils2_la_OBJECTS = sg_lib.lo \ @OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_FALSE@@OS_WIN32_MINGW_TRUE@ sg_lib_data.lo \ @OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_FALSE@@OS_WIN32_MINGW_TRUE@ sg_cmds_basic.lo \ @OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_FALSE@@OS_WIN32_MINGW_TRUE@ sg_cmds_extra.lo \ @OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_FALSE@@OS_WIN32_MINGW_TRUE@ sg_cmds_mmc.lo \ @OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_FALSE@@OS_WIN32_MINGW_TRUE@ sg_pt_common.lo \ @OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_FALSE@@OS_WIN32_MINGW_TRUE@ sg_pt_win32.lo @OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_TRUE@am_libsgutils2_la_OBJECTS = sg_lib.lo \ @OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_TRUE@ sg_lib_data.lo \ @OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_TRUE@ sg_cmds_basic.lo \ @OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_TRUE@ sg_cmds_extra.lo \ @OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_TRUE@ sg_cmds_mmc.lo \ @OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_TRUE@ sg_pt_common.lo \ @OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_TRUE@ sg_pt_win32.lo @OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_TRUE@am_libsgutils2_la_OBJECTS = sg_lib.lo \ @OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_TRUE@ sg_lib_data.lo \ @OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_TRUE@ sg_cmds_basic.lo \ @OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_TRUE@ sg_cmds_extra.lo \ @OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_TRUE@ sg_cmds_mmc.lo \ @OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_TRUE@ sg_pt_common.lo \ @OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_TRUE@ sg_pt_solaris.lo @OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_TRUE@am_libsgutils2_la_OBJECTS = \ @OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_TRUE@ sg_lib.lo \ @OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_TRUE@ sg_lib_data.lo \ @OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_TRUE@ sg_cmds_basic.lo \ @OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_TRUE@ sg_cmds_extra.lo \ @OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_TRUE@ sg_cmds_mmc.lo \ @OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_TRUE@ sg_pt_common.lo \ @OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_TRUE@ sg_pt_osf1.lo @OS_FREEBSD_FALSE@@OS_LINUX_TRUE@am_libsgutils2_la_OBJECTS = \ @OS_FREEBSD_FALSE@@OS_LINUX_TRUE@ sg_lib.lo sg_lib_data.lo \ @OS_FREEBSD_FALSE@@OS_LINUX_TRUE@ sg_cmds_basic.lo \ @OS_FREEBSD_FALSE@@OS_LINUX_TRUE@ sg_cmds_extra.lo \ @OS_FREEBSD_FALSE@@OS_LINUX_TRUE@ sg_cmds_mmc.lo \ @OS_FREEBSD_FALSE@@OS_LINUX_TRUE@ sg_pt_common.lo \ @OS_FREEBSD_FALSE@@OS_LINUX_TRUE@ sg_pt_linux.lo sg_io_linux.lo @OS_FREEBSD_TRUE@am_libsgutils2_la_OBJECTS = sg_lib.lo sg_lib_data.lo \ @OS_FREEBSD_TRUE@ sg_cmds_basic.lo sg_cmds_extra.lo \ @OS_FREEBSD_TRUE@ sg_cmds_mmc.lo sg_pt_common.lo \ @OS_FREEBSD_TRUE@ sg_pt_freebsd.lo am__EXTRA_libsgutils2_la_SOURCES_DIST = sg_pt_linux.c sg_io_linux.c \ sg_linux_inc.h sg_pt_osf1.c sg_pt_solaris.c sg_pt_win32.c \ getopt_long.c sg_pt_freebsd.c libsgutils2_la_OBJECTS = $(am_libsgutils2_la_OBJECTS) libsgutils2_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(libsgutils2_la_LDFLAGS) $(LDFLAGS) -o $@ DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libsgutils2_la_SOURCES) $(EXTRA_libsgutils2_la_SOURCES) DIST_SOURCES = $(am__libsgutils2_la_SOURCES_DIST) \ $(am__EXTRA_libsgutils2_la_SOURCES_DIST) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GETOPT_O_FILES = @GETOPT_O_FILES@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ os_libs = @os_libs@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ @OS_FREEBSD_TRUE@libsgutils2_la_SOURCES = \ @OS_FREEBSD_TRUE@ sg_lib.c \ @OS_FREEBSD_TRUE@ sg_lib_data.c \ @OS_FREEBSD_TRUE@ sg_cmds_basic.c \ @OS_FREEBSD_TRUE@ sg_cmds_extra.c \ @OS_FREEBSD_TRUE@ sg_cmds_mmc.c \ @OS_FREEBSD_TRUE@ sg_pt_common.c \ @OS_FREEBSD_TRUE@ sg_pt_freebsd.c @OS_LINUX_TRUE@libsgutils2_la_SOURCES = \ @OS_LINUX_TRUE@ sg_lib.c \ @OS_LINUX_TRUE@ sg_lib_data.c \ @OS_LINUX_TRUE@ sg_cmds_basic.c \ @OS_LINUX_TRUE@ sg_cmds_extra.c \ @OS_LINUX_TRUE@ sg_cmds_mmc.c \ @OS_LINUX_TRUE@ sg_pt_common.c \ @OS_LINUX_TRUE@ sg_pt_linux.c \ @OS_LINUX_TRUE@ sg_io_linux.c @OS_OSF_TRUE@libsgutils2_la_SOURCES = \ @OS_OSF_TRUE@ sg_lib.c \ @OS_OSF_TRUE@ sg_lib_data.c \ @OS_OSF_TRUE@ sg_cmds_basic.c \ @OS_OSF_TRUE@ sg_cmds_extra.c \ @OS_OSF_TRUE@ sg_cmds_mmc.c \ @OS_OSF_TRUE@ sg_pt_common.c \ @OS_OSF_TRUE@ sg_pt_osf1.c @OS_SOLARIS_TRUE@libsgutils2_la_SOURCES = \ @OS_SOLARIS_TRUE@ sg_lib.c \ @OS_SOLARIS_TRUE@ sg_lib_data.c \ @OS_SOLARIS_TRUE@ sg_cmds_basic.c \ @OS_SOLARIS_TRUE@ sg_cmds_extra.c \ @OS_SOLARIS_TRUE@ sg_cmds_mmc.c \ @OS_SOLARIS_TRUE@ sg_pt_common.c \ @OS_SOLARIS_TRUE@ sg_pt_solaris.c @OS_WIN32_CYGWIN_TRUE@libsgutils2_la_SOURCES = \ @OS_WIN32_CYGWIN_TRUE@ sg_lib.c \ @OS_WIN32_CYGWIN_TRUE@ sg_lib_data.c \ @OS_WIN32_CYGWIN_TRUE@ sg_cmds_basic.c \ @OS_WIN32_CYGWIN_TRUE@ sg_cmds_extra.c \ @OS_WIN32_CYGWIN_TRUE@ sg_cmds_mmc.c \ @OS_WIN32_CYGWIN_TRUE@ sg_pt_common.c \ @OS_WIN32_CYGWIN_TRUE@ sg_pt_win32.c @OS_WIN32_MINGW_TRUE@libsgutils2_la_SOURCES = \ @OS_WIN32_MINGW_TRUE@ sg_lib.c \ @OS_WIN32_MINGW_TRUE@ sg_lib_data.c \ @OS_WIN32_MINGW_TRUE@ sg_cmds_basic.c \ @OS_WIN32_MINGW_TRUE@ sg_cmds_extra.c \ @OS_WIN32_MINGW_TRUE@ sg_cmds_mmc.c \ @OS_WIN32_MINGW_TRUE@ sg_pt_common.c \ @OS_WIN32_MINGW_TRUE@ sg_pt_win32.c @OS_FREEBSD_TRUE@EXTRA_libsgutils2_la_SOURCES = \ @OS_FREEBSD_TRUE@ sg_pt_linux.c \ @OS_FREEBSD_TRUE@ sg_io_linux.c \ @OS_FREEBSD_TRUE@ sg_linux_inc.h \ @OS_FREEBSD_TRUE@ sg_pt_osf1.c \ @OS_FREEBSD_TRUE@ sg_pt_solaris.c \ @OS_FREEBSD_TRUE@ sg_pt_win32.c \ @OS_FREEBSD_TRUE@ getopt_long.c @OS_LINUX_TRUE@EXTRA_libsgutils2_la_SOURCES = \ @OS_LINUX_TRUE@ sg_pt_freebsd.c \ @OS_LINUX_TRUE@ sg_pt_osf1.c \ @OS_LINUX_TRUE@ sg_pt_solaris.c \ @OS_LINUX_TRUE@ sg_pt_win32.c \ @OS_LINUX_TRUE@ getopt_long.c @OS_OSF_TRUE@EXTRA_libsgutils2_la_SOURCES = \ @OS_OSF_TRUE@ sg_pt_linux.c \ @OS_OSF_TRUE@ sg_io_linux.c \ @OS_OSF_TRUE@ sg_pt_freebsd.c \ @OS_OSF_TRUE@ sg_pt_solaris.c \ @OS_OSF_TRUE@ sg_pt_win32.c \ @OS_OSF_TRUE@ getopt_long.c @OS_SOLARIS_TRUE@EXTRA_libsgutils2_la_SOURCES = \ @OS_SOLARIS_TRUE@ sg_pt_linux.c \ @OS_SOLARIS_TRUE@ sg_io_linux.c \ @OS_SOLARIS_TRUE@ sg_linux_inc.h \ @OS_SOLARIS_TRUE@ sg_pt_freebsd.c \ @OS_SOLARIS_TRUE@ sg_pt_osf1.c \ @OS_SOLARIS_TRUE@ sg_pt_win32.c \ @OS_SOLARIS_TRUE@ getopt_long.c @OS_WIN32_CYGWIN_TRUE@EXTRA_libsgutils2_la_SOURCES = \ @OS_WIN32_CYGWIN_TRUE@ sg_pt_linux.c \ @OS_WIN32_CYGWIN_TRUE@ sg_io_linux.c \ @OS_WIN32_CYGWIN_TRUE@ sg_pt_freebsd.c \ @OS_WIN32_CYGWIN_TRUE@ sg_pt_osf1.c \ @OS_WIN32_CYGWIN_TRUE@ sg_pt_solaris.c \ @OS_WIN32_CYGWIN_TRUE@ getopt_long.c @OS_WIN32_MINGW_TRUE@EXTRA_libsgutils2_la_SOURCES = \ @OS_WIN32_MINGW_TRUE@ sg_pt_linux.c \ @OS_WIN32_MINGW_TRUE@ sg_io_linux.c \ @OS_WIN32_MINGW_TRUE@ sg_pt_freebsd.c \ @OS_WIN32_MINGW_TRUE@ sg_pt_osf1.c \ @OS_WIN32_MINGW_TRUE@ sg_pt_solaris.c \ @OS_WIN32_MINGW_TRUE@ getopt_long.c AM_CFLAGS = -I ../include -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -Wall -W # AM_CFLAGS = -I ../include -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -Wall -W -pedantic -std=c99 lib_LTLIBRARIES = libsgutils2.la libsgutils2_la_LDFLAGS = -version-info 2:0:0 libsgutils2_la_LIBADD = @GETOPT_O_FILES@ @os_libs@ libsgutils2_la_DEPENDENCIES = @GETOPT_O_FILES@ all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu lib/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ } uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ done clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ test "$$dir" != "$$p" || dir=.; \ echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done libsgutils2.la: $(libsgutils2_la_OBJECTS) $(libsgutils2_la_DEPENDENCIES) $(libsgutils2_la_LINK) -rpath $(libdir) $(libsgutils2_la_OBJECTS) $(libsgutils2_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt_long.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_cmds_basic.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_cmds_extra.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_cmds_mmc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_io_linux.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_lib.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_lib_data.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_pt_common.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_pt_freebsd.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_pt_linux.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_pt_osf1.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_pt_solaris.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_pt_win32.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(libdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-libLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-libLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libLTLIBRARIES clean-libtool ctags distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am \ install-libLTLIBRARIES install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am uninstall-libLTLIBRARIES # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: ddpt-0.92/lib/sg_pt_freebsd.c0000644000175000017500000003217211351460102015111 0ustar douggdougg/* * Copyright (c) 2005-2010 Douglas Gilbert. * All rights reserved. * Use of this source code is governed by a BSD-style * license that can be found in the BSD_LICENSE file. */ /* sg_pt_freebsd version 1.10 20100321 */ #include #include #include #include #include #include #include #include #include #include // #include #include #include #include #include #include #include #include "sg_pt.h" #include "sg_lib.h" #ifdef HAVE_CONFIG_H #include "config.h" #endif #define FREEBSD_MAXDEV 64 #define FREEBSD_FDOFFSET 16; struct freebsd_dev_channel { char* devname; // the SCSI device name int unitnum; // the SCSI unit number struct cam_device* cam_dev; }; // Private table of open devices: guaranteed zero on startup since // part of static data. static struct freebsd_dev_channel *devicetable[FREEBSD_MAXDEV]; #define DEF_TIMEOUT 60000 /* 60,000 milliseconds (60 seconds) */ struct sg_pt_freebsd_scsi { struct cam_device* cam_dev; // copy held for error processing union ccb *ccb; unsigned char * cdb; int cdb_len; unsigned char * sense; int sense_len; unsigned char * dxferp; int dxfer_len; int dxfer_dir; int scsi_status; int resid; int sense_resid; int in_err; int os_err; int transport_err; }; struct sg_pt_base { struct sg_pt_freebsd_scsi impl; }; /* Returns >= 0 if successful. If error in Unix returns negated errno. */ int scsi_pt_open_device(const char * device_name, int read_only, int verbose) { int oflags = 0 /* O_NONBLOCK*/ ; oflags |= (read_only ? O_RDONLY : O_RDWR); return scsi_pt_open_flags(device_name, oflags, verbose); } /* Similar to scsi_pt_open_device() but takes Unix style open flags OR-ed * together. The 'flags' argument is ignored in FreeBSD. * Returns >= 0 if successful, otherwise returns negated errno. */ int scsi_pt_open_flags(const char * device_name, int flags __attribute__ ((unused)), int verbose) { struct freebsd_dev_channel *fdchan; struct cam_device* cam_dev; int k; if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; // Search table for a free entry for (k = 0; k < FREEBSD_MAXDEV; k++) if (! devicetable[k]) break; // If no free entry found, return error. We have max allowed number // of "file descriptors" already allocated. if (k == FREEBSD_MAXDEV) { if (verbose) fprintf(sg_warnings_strm, "too many open file descriptors " "(%d)\n", FREEBSD_MAXDEV); errno = EMFILE; return -1; } fdchan = (struct freebsd_dev_channel *) calloc(1,sizeof(struct freebsd_dev_channel)); if (fdchan == NULL) { // errno already set by call to calloc() return -1; } if (! (fdchan->devname = (char *)calloc(1, DEV_IDLEN+1))) return -1; if (cam_get_device(device_name, fdchan->devname, DEV_IDLEN, &(fdchan->unitnum)) == -1) { if (verbose) fprintf(sg_warnings_strm, "bad device name structure\n"); errno = EINVAL; return -1; } if (! (cam_dev = cam_open_spec_device(fdchan->devname, fdchan->unitnum, O_RDWR, NULL))) { if (verbose) fprintf(sg_warnings_strm, "cam_open_spec_device: %s\n", cam_errbuf); errno = EPERM; /* permissions or no CAM */ return -1; } fdchan->cam_dev = cam_dev; // return pointer to "file descriptor" table entry, properly offset. devicetable[k] = fdchan; return k + FREEBSD_FDOFFSET; } /* Returns 0 if successful. If error in Unix returns negated errno. */ int scsi_pt_close_device(int device_fd) { struct freebsd_dev_channel *fdchan; int fd = device_fd - FREEBSD_FDOFFSET; if ((fd < 0) || (fd >= FREEBSD_MAXDEV)) { errno = ENODEV; return -1; } fdchan = devicetable[fd]; if (NULL == fdchan) { errno = ENODEV; return -1; } if (fdchan->devname) free(fdchan->devname); if (fdchan->cam_dev) cam_close_device(fdchan->cam_dev); free(fdchan); devicetable[fd] = NULL; return 0; } struct sg_pt_base * construct_scsi_pt_obj() { struct sg_pt_freebsd_scsi * ptp; ptp = (struct sg_pt_freebsd_scsi *) calloc(1, sizeof(struct sg_pt_freebsd_scsi)); if (ptp) { memset(ptp, 0, sizeof(struct sg_pt_freebsd_scsi)); ptp->dxfer_dir = CAM_DIR_NONE; } return (struct sg_pt_base *)ptp; } void destruct_scsi_pt_obj(struct sg_pt_base * vp) { struct sg_pt_freebsd_scsi * ptp = &vp->impl; if (ptp) { if (ptp->ccb) cam_freeccb(ptp->ccb); free(ptp); } } void clear_scsi_pt_obj(struct sg_pt_base * vp) { struct sg_pt_freebsd_scsi * ptp = &vp->impl; if (ptp) { memset(ptp, 0, sizeof(struct sg_pt_freebsd_scsi)); ptp->dxfer_dir = CAM_DIR_NONE; } } void set_scsi_pt_cdb(struct sg_pt_base * vp, const unsigned char * cdb, int cdb_len) { struct sg_pt_freebsd_scsi * ptp = &vp->impl; if (ptp->cdb) ++ptp->in_err; ptp->cdb = (unsigned char *)cdb; ptp->cdb_len = cdb_len; } void set_scsi_pt_sense(struct sg_pt_base * vp, unsigned char * sense, int max_sense_len) { struct sg_pt_freebsd_scsi * ptp = &vp->impl; if (ptp->sense) ++ptp->in_err; memset(sense, 0, max_sense_len); ptp->sense = sense; ptp->sense_len = max_sense_len; } /* Setup for data transfer from device */ void set_scsi_pt_data_in(struct sg_pt_base * vp, unsigned char * dxferp, int dxfer_len) { struct sg_pt_freebsd_scsi * ptp = &vp->impl; if (ptp->dxferp) ++ptp->in_err; if (dxfer_len > 0) { ptp->dxferp = dxferp; ptp->dxfer_len = dxfer_len; ptp->dxfer_dir = CAM_DIR_IN; } } /* Setup for data transfer toward device */ void set_scsi_pt_data_out(struct sg_pt_base * vp, const unsigned char * dxferp, int dxfer_len) { struct sg_pt_freebsd_scsi * ptp = &vp->impl; if (ptp->dxferp) ++ptp->in_err; if (dxfer_len > 0) { ptp->dxferp = (unsigned char *)dxferp; ptp->dxfer_len = dxfer_len; ptp->dxfer_dir = CAM_DIR_OUT; } } void set_scsi_pt_packet_id(struct sg_pt_base * vp __attribute__ ((unused)), int pack_id __attribute__ ((unused))) { } void set_scsi_pt_tag(struct sg_pt_base * vp, uint64_t tag __attribute__ ((unused))) { struct sg_pt_freebsd_scsi * ptp = &vp->impl; ++ptp->in_err; } void set_scsi_pt_task_management(struct sg_pt_base * vp, int tmf_code __attribute__ ((unused))) { struct sg_pt_freebsd_scsi * ptp = &vp->impl; ++ptp->in_err; } void set_scsi_pt_task_attr(struct sg_pt_base * vp, int attrib __attribute__ ((unused)), int priority __attribute__ ((unused))) { struct sg_pt_freebsd_scsi * ptp = &vp->impl; ++ptp->in_err; } void set_scsi_pt_flags(struct sg_pt_base * objp, int flags) { /* do nothing, suppress warnings */ objp = objp; flags = flags; } /* Executes SCSI command (or at least forwards it to lower layers). * Clears os_err field prior to active call (whose result may set it * again). */ int do_scsi_pt(struct sg_pt_base * vp, int device_fd, int time_secs, int verbose) { int fd = device_fd - FREEBSD_FDOFFSET; struct sg_pt_freebsd_scsi * ptp = &vp->impl; struct freebsd_dev_channel *fdchan; union ccb *ccb; int len, timout_ms; if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; ptp->os_err = 0; if (ptp->in_err) { if (verbose) fprintf(sg_warnings_strm, "Replicated or unused set_scsi_pt...\n"); return SCSI_PT_DO_BAD_PARAMS; } if (NULL == ptp->cdb) { if (verbose) fprintf(sg_warnings_strm, "No command (cdb) given\n"); return SCSI_PT_DO_BAD_PARAMS; } if ((fd < 0) || (fd >= FREEBSD_MAXDEV)) { if (verbose) fprintf(sg_warnings_strm, "Bad file descriptor\n"); ptp->os_err = ENODEV; return -ptp->os_err; } fdchan = devicetable[fd]; if (NULL == fdchan) { if (verbose) fprintf(sg_warnings_strm, "File descriptor closed??\n"); ptp->os_err = ENODEV; return -ptp->os_err; } if (NULL == fdchan->cam_dev) { if (verbose) fprintf(sg_warnings_strm, "No open CAM device\n"); return SCSI_PT_DO_BAD_PARAMS; } if (! (ccb = cam_getccb(fdchan->cam_dev))) { if (verbose) fprintf(sg_warnings_strm, "cam_getccb: failed\n"); ptp->os_err = ENOMEM; return -ptp->os_err; } ptp->ccb = ccb; // clear out structure, except for header that was filled in for us bzero(&(&ccb->ccb_h)[1], sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr)); timout_ms = (time_secs > 0) ? (time_secs * 1000) : DEF_TIMEOUT; cam_fill_csio(&ccb->csio, /* retries */ 1, /* cbfcnp */ NULL, /* flags */ ptp->dxfer_dir, /* tagaction */ MSG_SIMPLE_Q_TAG, /* dataptr */ ptp->dxferp, /* datalen */ ptp->dxfer_len, /* senselen */ ptp->sense_len, /* cdblen */ ptp->cdb_len, /* timeout (millisecs) */ timout_ms); memcpy(ccb->csio.cdb_io.cdb_bytes, ptp->cdb, ptp->cdb_len); if (cam_send_ccb(fdchan->cam_dev, ccb) < 0) { if (verbose) { warn("error sending SCSI ccb"); #if __FreeBSD_version > 500000 cam_error_print(fdchan->cam_dev, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); #endif } cam_freeccb(ptp->ccb); ptp->ccb = NULL; ptp->os_err = EIO; return -ptp->os_err; } if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) || ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)) { ptp->scsi_status = ccb->csio.scsi_status; ptp->resid = ccb->csio.resid; ptp->sense_resid = ccb->csio.sense_resid; if ((SAM_STAT_CHECK_CONDITION == ptp->scsi_status) || (SAM_STAT_COMMAND_TERMINATED == ptp->scsi_status)) { len = ptp->sense_len - ptp->sense_resid; if (len) memcpy(ptp->sense, &(ccb->csio.sense_data), len); } } else ptp->transport_err = 1; ptp->cam_dev = fdchan->cam_dev; // for error processing return 0; } int get_scsi_pt_result_category(const struct sg_pt_base * vp) { const struct sg_pt_freebsd_scsi * ptp = &vp->impl; if (ptp->os_err) return SCSI_PT_RESULT_OS_ERR; else if (ptp->transport_err) return SCSI_PT_RESULT_TRANSPORT_ERR; else if ((SAM_STAT_CHECK_CONDITION == ptp->scsi_status) || (SAM_STAT_COMMAND_TERMINATED == ptp->scsi_status)) return SCSI_PT_RESULT_SENSE; else if (ptp->scsi_status) return SCSI_PT_RESULT_STATUS; else return SCSI_PT_RESULT_GOOD; } int get_scsi_pt_resid(const struct sg_pt_base * vp) { const struct sg_pt_freebsd_scsi * ptp = &vp->impl; return ptp->resid; } int get_scsi_pt_status_response(const struct sg_pt_base * vp) { const struct sg_pt_freebsd_scsi * ptp = &vp->impl; return ptp->scsi_status; } int get_scsi_pt_sense_len(const struct sg_pt_base * vp) { const struct sg_pt_freebsd_scsi * ptp = &vp->impl; int len; len = ptp->sense_len - ptp->sense_resid; return (len > 0) ? len : 0; } int get_scsi_pt_duration_ms(const struct sg_pt_base * vp __attribute__ ((unused))) { // const struct sg_pt_freebsd_scsi * ptp = &vp->impl; return -1; } int get_scsi_pt_transport_err(const struct sg_pt_base * vp) { const struct sg_pt_freebsd_scsi * ptp = &vp->impl; return ptp->transport_err; } int get_scsi_pt_os_err(const struct sg_pt_base * vp) { const struct sg_pt_freebsd_scsi * ptp = &vp->impl; return ptp->os_err; } char * get_scsi_pt_transport_err_str(const struct sg_pt_base * vp, int max_b_len, char * b) { const struct sg_pt_freebsd_scsi * ptp = &vp->impl; if (0 == ptp->transport_err) { strncpy(b, "no transport error available", max_b_len); b[max_b_len - 1] = '\0'; return b; } #if __FreeBSD_version > 500000 if (ptp->cam_dev) cam_error_string(ptp->cam_dev, ptp->ccb, b, max_b_len, CAM_ESF_ALL, CAM_EPF_ALL); else { strncpy(b, "no transport error available", max_b_len); b[max_b_len - 1] = '\0'; } #else strncpy(b, "no transport error available", max_b_len); b[max_b_len - 1] = '\0'; #endif return b; } char * get_scsi_pt_os_err_str(const struct sg_pt_base * vp, int max_b_len, char * b) { const struct sg_pt_freebsd_scsi * ptp = &vp->impl; const char * cp; cp = safe_strerror(ptp->os_err); strncpy(b, cp, max_b_len); if ((int)strlen(cp) >= max_b_len) b[max_b_len - 1] = '\0'; return b; } ddpt-0.92/lib/Makefile.am0000644000175000017500000000427011215540460014176 0ustar douggdougg if OS_LINUX libsgutils2_la_SOURCES = \ sg_lib.c \ sg_lib_data.c \ sg_cmds_basic.c \ sg_cmds_extra.c \ sg_cmds_mmc.c \ sg_pt_common.c \ sg_pt_linux.c \ sg_io_linux.c EXTRA_libsgutils2_la_SOURCES = \ sg_pt_freebsd.c \ sg_pt_osf1.c \ sg_pt_solaris.c \ sg_pt_win32.c \ getopt_long.c endif if OS_WIN32_MINGW libsgutils2_la_SOURCES = \ sg_lib.c \ sg_lib_data.c \ sg_cmds_basic.c \ sg_cmds_extra.c \ sg_cmds_mmc.c \ sg_pt_common.c \ sg_pt_win32.c EXTRA_libsgutils2_la_SOURCES = \ sg_pt_linux.c \ sg_io_linux.c \ sg_pt_freebsd.c \ sg_pt_osf1.c \ sg_pt_solaris.c \ getopt_long.c endif if OS_WIN32_CYGWIN libsgutils2_la_SOURCES = \ sg_lib.c \ sg_lib_data.c \ sg_cmds_basic.c \ sg_cmds_extra.c \ sg_cmds_mmc.c \ sg_pt_common.c \ sg_pt_win32.c EXTRA_libsgutils2_la_SOURCES = \ sg_pt_linux.c \ sg_io_linux.c \ sg_pt_freebsd.c \ sg_pt_osf1.c \ sg_pt_solaris.c \ getopt_long.c endif if OS_FREEBSD libsgutils2_la_SOURCES = \ sg_lib.c \ sg_lib_data.c \ sg_cmds_basic.c \ sg_cmds_extra.c \ sg_cmds_mmc.c \ sg_pt_common.c \ sg_pt_freebsd.c EXTRA_libsgutils2_la_SOURCES = \ sg_pt_linux.c \ sg_io_linux.c \ sg_linux_inc.h \ sg_pt_osf1.c \ sg_pt_solaris.c \ sg_pt_win32.c \ getopt_long.c endif if OS_SOLARIS libsgutils2_la_SOURCES = \ sg_lib.c \ sg_lib_data.c \ sg_cmds_basic.c \ sg_cmds_extra.c \ sg_cmds_mmc.c \ sg_pt_common.c \ sg_pt_solaris.c EXTRA_libsgutils2_la_SOURCES = \ sg_pt_linux.c \ sg_io_linux.c \ sg_linux_inc.h \ sg_pt_freebsd.c \ sg_pt_osf1.c \ sg_pt_win32.c \ getopt_long.c endif if OS_OSF libsgutils2_la_SOURCES = \ sg_lib.c \ sg_lib_data.c \ sg_cmds_basic.c \ sg_cmds_extra.c \ sg_cmds_mmc.c \ sg_pt_common.c \ sg_pt_osf1.c EXTRA_libsgutils2_la_SOURCES = \ sg_pt_linux.c \ sg_io_linux.c \ sg_pt_freebsd.c \ sg_pt_solaris.c \ sg_pt_win32.c \ getopt_long.c endif AM_CFLAGS = -I ../include -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -Wall -W # AM_CFLAGS = -I ../include -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -Wall -W -pedantic -std=c99 lib_LTLIBRARIES = libsgutils2.la libsgutils2_la_LDFLAGS = -version-info 2:0:0 libsgutils2_la_LIBADD = @GETOPT_O_FILES@ @os_libs@ libsgutils2_la_DEPENDENCIES = @GETOPT_O_FILES@ ddpt-0.92/lib/sg_cmds_mmc.c0000644000175000017500000003001411346470114014557 0ustar douggdougg/* * Copyright (c) 2008-2010 Douglas Gilbert. * All rights reserved. * Use of this source code is governed by a BSD-style * license that can be found in the BSD_LICENSE file. */ #include #include #include #include #define __STDC_FORMAT_MACROS 1 #include #include "sg_lib.h" #include "sg_cmds_basic.h" #include "sg_cmds_mmc.h" #include "sg_pt.h" #ifdef HAVE_CONFIG_H #include "config.h" #endif #define SENSE_BUFF_LEN 32 /* Arbitrary, could be larger */ #define DEF_PT_TIMEOUT 60 /* 60 seconds */ #define GET_CONFIG_CMD 0x46 #define GET_CONFIG_CMD_LEN 10 #define GET_PERFORMANCE_CMD 0xac #define GET_PERFORMANCE_CMD_LEN 12 #define SET_CD_SPEED_CMD 0xbb #define SET_CD_SPEED_CMDLEN 12 #define SET_STREAMING_CMD 0xb6 #define SET_STREAMING_CMDLEN 12 /* Invokes a SCSI SET CD SPEED command (MMC). * Return of 0 -> success, SG_LIB_CAT_INVALID_OP -> command not supported, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_UNIT_ATTENTION, * SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND, * -1 -> other failure */ int sg_ll_set_cd_speed(int sg_fd, int rot_control, int drv_read_speed, int drv_write_speed, int noisy, int verbose) { int res, ret, k, sense_cat; unsigned char scsCmdBlk[SET_CD_SPEED_CMDLEN] = {SET_CD_SPEED_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ,0}; unsigned char sense_b[SENSE_BUFF_LEN]; struct sg_pt_base * ptvp; if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; scsCmdBlk[1] |= (rot_control & 0x3); scsCmdBlk[2] = (drv_read_speed >> 8) & 0xff; scsCmdBlk[3] = drv_read_speed & 0xff; scsCmdBlk[4] = (drv_write_speed >> 8) & 0xff; scsCmdBlk[5] = drv_write_speed & 0xff; if (verbose) { fprintf(sg_warnings_strm, " set cd speed cdb: "); for (k = 0; k < SET_CD_SPEED_CMDLEN; ++k) fprintf(sg_warnings_strm, "%02x ", scsCmdBlk[k]); fprintf(sg_warnings_strm, "\n"); } ptvp = construct_scsi_pt_obj(); if (NULL == ptvp) { fprintf(sg_warnings_strm, "set cd speed: out of memory\n"); return -1; } set_scsi_pt_cdb(ptvp, scsCmdBlk, sizeof(scsCmdBlk)); set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, "set cd speed", res, 0, sense_b, noisy, verbose, &sense_cat); if (-1 == ret) ; else if (-2 == ret) { switch (sense_cat) { case SG_LIB_CAT_NOT_READY: case SG_LIB_CAT_UNIT_ATTENTION: case SG_LIB_CAT_INVALID_OP: case SG_LIB_CAT_ILLEGAL_REQ: case SG_LIB_CAT_ABORTED_COMMAND: ret = sense_cat; break; case SG_LIB_CAT_RECOVERED: case SG_LIB_CAT_NO_SENSE: ret = 0; break; default: ret = -1; break; } } else ret = 0; destruct_scsi_pt_obj(ptvp); return ret; } /* Invokes a SCSI GET CONFIGURATION command (MMC-3,4,5). * Returns 0 when successful, SG_LIB_CAT_INVALID_OP if command not * supported, SG_LIB_CAT_ILLEGAL_REQ if field in cdb not supported, * SG_LIB_CAT_UNIT_ATTENTION, SG_LIB_CAT_ABORTED_COMMAND, else -1 */ int sg_ll_get_config(int sg_fd, int rt, int starting, void * resp, int mx_resp_len, int noisy, int verbose) { int res, k, ret, sense_cat; unsigned char gcCmdBlk[GET_CONFIG_CMD_LEN] = {GET_CONFIG_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0}; unsigned char sense_b[SENSE_BUFF_LEN]; struct sg_pt_base * ptvp; if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; if ((rt < 0) || (rt > 3)) { fprintf(sg_warnings_strm, "Bad rt value: %d\n", rt); return -1; } gcCmdBlk[1] = (rt & 0x3); if ((starting < 0) || (starting > 0xffff)) { fprintf(sg_warnings_strm, "Bad starting field number: 0x%x\n", starting); return -1; } gcCmdBlk[2] = (unsigned char)((starting >> 8) & 0xff); gcCmdBlk[3] = (unsigned char)(starting & 0xff); if ((mx_resp_len < 0) || (mx_resp_len > 0xffff)) { fprintf(sg_warnings_strm, "Bad mx_resp_len: 0x%x\n", starting); return -1; } gcCmdBlk[7] = (unsigned char)((mx_resp_len >> 8) & 0xff); gcCmdBlk[8] = (unsigned char)(mx_resp_len & 0xff); if (verbose) { fprintf(sg_warnings_strm, " Get Configuration cdb: "); for (k = 0; k < GET_CONFIG_CMD_LEN; ++k) fprintf(sg_warnings_strm, "%02x ", gcCmdBlk[k]); fprintf(sg_warnings_strm, "\n"); } ptvp = construct_scsi_pt_obj(); if (NULL == ptvp) { fprintf(sg_warnings_strm, "get configuration: out of memory\n"); return -1; } set_scsi_pt_cdb(ptvp, gcCmdBlk, sizeof(gcCmdBlk)); set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); set_scsi_pt_data_in(ptvp, (unsigned char *)resp, mx_resp_len); res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, "get configuration", res, mx_resp_len, sense_b, noisy, verbose, &sense_cat); if (-1 == ret) ; else if (-2 == ret) { switch (sense_cat) { case SG_LIB_CAT_INVALID_OP: case SG_LIB_CAT_ILLEGAL_REQ: case SG_LIB_CAT_UNIT_ATTENTION: case SG_LIB_CAT_ABORTED_COMMAND: ret = sense_cat; break; case SG_LIB_CAT_RECOVERED: case SG_LIB_CAT_NO_SENSE: ret = 0; break; default: ret = -1; break; } } else { if ((verbose > 2) && (ret > 3)) { unsigned char * ucp; int len; ucp = (unsigned char *)resp; len = (ucp[0] << 24) + (ucp[1] << 16) + (ucp[2] << 8) + ucp[3] + 4; if (len < 0) len = 0; len = (ret < len) ? ret : len; fprintf(sg_warnings_strm, " get configuration: response%s\n", (len > 256 ? ", first 256 bytes" : "")); dStrHex((const char *)resp, (len > 256 ? 256 : len), -1); } ret = 0; } destruct_scsi_pt_obj(ptvp); return ret; } /* Invokes a SCSI GET PERFORMANCE command (MMC-3...6). * Returns 0 when successful, SG_LIB_CAT_INVALID_OP if command not * supported, SG_LIB_CAT_ILLEGAL_REQ if field in cdb not supported, * SG_LIB_CAT_UNIT_ATTENTION, SG_LIB_CAT_ABORTED_COMMAND, else -1 */ int sg_ll_get_performance(int sg_fd, int data_type, unsigned int starting_lba, int max_num_desc, int ttype, void * resp, int mx_resp_len, int noisy, int verbose) { int res, k, ret, sense_cat; unsigned char gpCmdBlk[GET_PERFORMANCE_CMD_LEN] = {GET_PERFORMANCE_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; unsigned char sense_b[SENSE_BUFF_LEN]; struct sg_pt_base * ptvp; if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; if ((data_type < 0) || (data_type > 0x1f)) { fprintf(sg_warnings_strm, "Bad data_type value: %d\n", data_type); return -1; } gpCmdBlk[1] = (data_type & 0x1f); gpCmdBlk[2] = (unsigned char)((starting_lba >> 24) & 0xff); gpCmdBlk[3] = (unsigned char)((starting_lba >> 16) & 0xff); gpCmdBlk[4] = (unsigned char)((starting_lba >> 8) & 0xff); gpCmdBlk[3] = (unsigned char)(starting_lba & 0xff); if ((max_num_desc < 0) || (max_num_desc > 0xffff)) { fprintf(sg_warnings_strm, "Bad max_num_desc: 0x%x\n", max_num_desc); return -1; } gpCmdBlk[8] = (unsigned char)((max_num_desc >> 8) & 0xff); gpCmdBlk[9] = (unsigned char)(max_num_desc & 0xff); if ((ttype < 0) || (ttype > 0xff)) { fprintf(sg_warnings_strm, "Bad type: 0x%x\n", ttype); return -1; } gpCmdBlk[10] = (unsigned char)ttype; if (verbose) { fprintf(sg_warnings_strm, " Get Performance cdb: "); for (k = 0; k < GET_PERFORMANCE_CMD_LEN; ++k) fprintf(sg_warnings_strm, "%02x ", gpCmdBlk[k]); fprintf(sg_warnings_strm, "\n"); } ptvp = construct_scsi_pt_obj(); if (NULL == ptvp) { fprintf(sg_warnings_strm, "get performance: out of memory\n"); return -1; } set_scsi_pt_cdb(ptvp, gpCmdBlk, sizeof(gpCmdBlk)); set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); set_scsi_pt_data_in(ptvp, (unsigned char *)resp, mx_resp_len); res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, "get performance", res, mx_resp_len, sense_b, noisy, verbose, &sense_cat); if (-1 == ret) ; else if (-2 == ret) { switch (sense_cat) { case SG_LIB_CAT_INVALID_OP: case SG_LIB_CAT_ILLEGAL_REQ: case SG_LIB_CAT_UNIT_ATTENTION: case SG_LIB_CAT_ABORTED_COMMAND: ret = sense_cat; break; case SG_LIB_CAT_RECOVERED: case SG_LIB_CAT_NO_SENSE: ret = 0; break; default: ret = -1; break; } } else { if ((verbose > 2) && (ret > 3)) { unsigned char * ucp; int len; ucp = (unsigned char *)resp; len = (ucp[0] << 24) + (ucp[1] << 16) + (ucp[2] << 8) + ucp[3] + 4; if (len < 0) len = 0; len = (ret < len) ? ret : len; fprintf(sg_warnings_strm, " get performance:: response%s\n", (len > 256 ? ", first 256 bytes" : "")); dStrHex((const char *)resp, (len > 256 ? 256 : len), -1); } ret = 0; } destruct_scsi_pt_obj(ptvp); return ret; } /* Invokes a SCSI SET STREAMING command (MMC). Return of 0 -> success, * SG_LIB_CAT_INVALID_OP -> Set Streaming not supported, * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_ABORTED_COMMAND, * SG_LIB_CAT_UNIT_ATTENTION, SG_LIB_CAT_NOT_READY -> device not ready, * -1 -> other failure */ int sg_ll_set_streaming(int sg_fd, int type, void * paramp, int param_len, int noisy, int verbose) { int k, res, ret, sense_cat; unsigned char ssCmdBlk[SET_STREAMING_CMDLEN] = {SET_STREAMING_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; unsigned char sense_b[SENSE_BUFF_LEN]; struct sg_pt_base * ptvp; ssCmdBlk[8] = type; ssCmdBlk[9] = (param_len >> 8) & 0xff; ssCmdBlk[10] = param_len & 0xff; if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; if (verbose) { fprintf(sg_warnings_strm, " set streaming cdb: "); for (k = 0; k < SET_STREAMING_CMDLEN; ++k) fprintf(sg_warnings_strm, "%02x ", ssCmdBlk[k]); fprintf(sg_warnings_strm, "\n"); if ((verbose > 1) && paramp && param_len) { fprintf(sg_warnings_strm, " set streaming " "parameter list:\n"); dStrHex((const char *)paramp, param_len, -1); } } ptvp = construct_scsi_pt_obj(); if (NULL == ptvp) { fprintf(sg_warnings_strm, "set streaming: out of memory\n"); return -1; } set_scsi_pt_cdb(ptvp, ssCmdBlk, sizeof(ssCmdBlk)); set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); set_scsi_pt_data_out(ptvp, (unsigned char *)paramp, param_len); res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); ret = sg_cmds_process_resp(ptvp, "set streaming", res, 0, sense_b, noisy, verbose, &sense_cat); if (-1 == ret) ; else if (-2 == ret) { switch (sense_cat) { case SG_LIB_CAT_NOT_READY: case SG_LIB_CAT_INVALID_OP: case SG_LIB_CAT_ILLEGAL_REQ: case SG_LIB_CAT_UNIT_ATTENTION: case SG_LIB_CAT_ABORTED_COMMAND: ret = sense_cat; break; case SG_LIB_CAT_RECOVERED: case SG_LIB_CAT_NO_SENSE: ret = 0; break; default: ret = -1; break; } } else ret = 0; destruct_scsi_pt_obj(ptvp); return ret; } ddpt-0.92/lib/sg_lib.c0000644000175000017500000016107411525020611013546 0ustar douggdougg/* * Copyright (c) 1999-2011 Douglas Gilbert. * All rights reserved. * Use of this source code is governed by a BSD-style * license that can be found in the BSD_LICENSE file. */ /* NOTICE: * On 5th October 2004 (v1.00) this file name was changed from sg_err.c * to sg_lib.c and the previous GPL was changed to a FreeBSD license. * The intention is to maintain this file and the related sg_lib.h file * as open source and encourage their unencumbered use. * * CONTRIBUTIONS: * This file started out as a copy of SCSI opcodes, sense keys and * additional sense codes (ASC/ASCQ) kept in the Linux SCSI subsystem * in the kernel source file: drivers/scsi/constant.c . That file * bore this notice: "Copyright (C) 1993, 1994, 1995 Eric Youngdale" * and a GPL notice. * * Much of the data in this file is derived from SCSI draft standards * found at http://www.t10.org with the "SCSI Primary Commands-4" (SPC-4) * being the central point of reference. * * Other contributions: * Version 0.91 (20031116) * sense key specific field (bytes 15-17) decoding [Trent Piepho] * * CHANGELOG (changes prior to v0.97 removed): * v0.97 (20040830) * safe_strerror(), rename sg_decode_sense() to sg_normalize_sense() * decode descriptor sense data format in full * v0.98 (20040924) [SPC-3 rev 21] * renamed from sg_err.c to sg_lib.c * factor out sg_get_num() and sg_get_llnum() into this file * add 'no_ascii<0' variant to dStrHex for ASCII-hex output only * v1.00 (20041012) * renamed from sg_err.c to sg_lib.c * change GPL to FreeBSD license */ #include #include #include #include #define __STDC_FORMAT_MACROS 1 #include #include "sg_lib.h" #include "sg_lib_data.h" #ifdef HAVE_CONFIG_H #include "config.h" #endif FILE * sg_warnings_strm = NULL; /* would like to default to stderr */ static void dStrHexErr(const char* str, int len, int b_len, char * b); /* Searches 'arr' for match on 'value' then 'peri_type'. If matches 'value' but not 'peri_type' then yields first 'value' match entry. Last element of 'arr' has NULL 'name'. If no match returns NULL. */ static const struct sg_lib_value_name_t * get_value_name(const struct sg_lib_value_name_t * arr, int value, int peri_type) { const struct sg_lib_value_name_t * vp = arr; const struct sg_lib_value_name_t * holdp; for (; vp->name; ++vp) { if (value == vp->value) { if (peri_type == vp->peri_dev_type) return vp; holdp = vp; while ((vp + 1)->name && (value == (vp + 1)->value)) { ++vp; if (peri_type == vp->peri_dev_type) return vp; } return holdp; } } return NULL; } void sg_set_warnings_strm(FILE * warnings_strm) { sg_warnings_strm = warnings_strm; } #define CMD_NAME_LEN 128 void sg_print_command(const unsigned char * command) { int k, sz; char buff[CMD_NAME_LEN]; sg_get_command_name(command, 0, CMD_NAME_LEN, buff); buff[CMD_NAME_LEN - 1] = '\0'; if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; fprintf(sg_warnings_strm, "%s [", buff); if (SG_VARIABLE_LENGTH_CMD == command[0]) sz = command[7] + 8; else sz = sg_get_command_size(command[0]); for (k = 0; k < sz; ++k) fprintf(sg_warnings_strm, "%02x ", command[k]); fprintf(sg_warnings_strm, "]\n"); } void sg_get_scsi_status_str(int scsi_status, int buff_len, char * buff) { const char * ccp; scsi_status &= 0x7e; /* sanitize as much as possible */ switch (scsi_status) { case 0: ccp = "Good"; break; case 0x2: ccp = "Check Condition"; break; case 0x4: ccp = "Condition Met"; break; case 0x8: ccp = "Busy"; break; case 0x10: ccp = "Intermediate (obsolete)"; break; case 0x14: ccp = "Intermediate-Condition Met (obs)"; break; case 0x18: ccp = "Reservation Conflict"; break; case 0x22: ccp = "Command Terminated (obsolete)"; break; case 0x28: ccp = "Task set Full"; break; case 0x30: ccp = "ACA Active"; break; case 0x40: ccp = "Task Aborted"; break; default: ccp = "Unknown status"; break; } strncpy(buff, ccp, buff_len); } void sg_print_scsi_status(int scsi_status) { char buff[128]; sg_get_scsi_status_str(scsi_status, sizeof(buff) - 1, buff); buff[sizeof(buff) - 1] = '\0'; if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; fprintf(sg_warnings_strm, "%s ", buff); } char * sg_get_sense_key_str(int sense_key, int buff_len, char * buff) { if ((sense_key >= 0) && (sense_key < 16)) snprintf(buff, buff_len, "%s", sg_lib_sense_key_desc[sense_key]); else snprintf(buff, buff_len, "invalid value: 0x%x", sense_key); return buff; } char * sg_get_asc_ascq_str(int asc, int ascq, int buff_len, char * buff) { int k, num, rlen; int found = 0; struct sg_lib_asc_ascq_t * eip; struct sg_lib_asc_ascq_range_t * ei2p; for (k = 0; sg_lib_asc_ascq_range[k].text; ++k) { ei2p = &sg_lib_asc_ascq_range[k]; if ((ei2p->asc == asc) && (ascq >= ei2p->ascq_min) && (ascq <= ei2p->ascq_max)) { found = 1; num = snprintf(buff, buff_len, "Additional sense: "); rlen = buff_len - num; num += snprintf(buff + num, ((rlen > 0) ? rlen : 0), ei2p->text, ascq); } } if (found) return buff; for (k = 0; sg_lib_asc_ascq[k].text; ++k) { eip = &sg_lib_asc_ascq[k]; if (eip->asc == asc && eip->ascq == ascq) { found = 1; snprintf(buff, buff_len, "Additional sense: %s", eip->text); } } if (! found) { if (asc >= 0x80) snprintf(buff, buff_len, "vendor specific ASC=%2x, ASCQ=%2x", asc, ascq); else if (ascq >= 0x80) snprintf(buff, buff_len, "ASC=%2x, vendor specific qualification " "ASCQ=%2x", asc, ascq); else snprintf(buff, buff_len, "ASC=%2x, ASCQ=%2x", asc, ascq); } return buff; } const unsigned char * sg_scsi_sense_desc_find(const unsigned char * sensep, int sense_len, int desc_type) { int add_sen_len, add_len, desc_len, k; const unsigned char * descp; if ((sense_len < 8) || (0 == (add_sen_len = sensep[7]))) return NULL; if ((sensep[0] < 0x72) || (sensep[0] > 0x73)) return NULL; add_sen_len = (add_sen_len < (sense_len - 8)) ? add_sen_len : (sense_len - 8); descp = &sensep[8]; for (desc_len = 0, k = 0; k < add_sen_len; k += desc_len) { descp += desc_len; add_len = (k < (add_sen_len - 1)) ? descp[1]: -1; desc_len = add_len + 2; if (descp[0] == desc_type) return descp; if (add_len < 0) /* short descriptor ?? */ break; } return NULL; } int sg_get_sense_info_fld(const unsigned char * sensep, int sb_len, uint64_t * info_outp) { int j; const unsigned char * ucp; uint64_t ull; if (info_outp) *info_outp = 0; if (sb_len < 7) return 0; switch (sensep[0] & 0x7f) { case 0x70: case 0x71: if (info_outp) *info_outp = ((unsigned int)sensep[3] << 24) + (sensep[4] << 16) + (sensep[5] << 8) + sensep[6]; return (sensep[0] & 0x80) ? 1 : 0; case 0x72: case 0x73: ucp = sg_scsi_sense_desc_find(sensep, sb_len, 0 /* info desc */); if (ucp && (0xa == ucp[1])) { ull = 0; for (j = 0; j < 8; ++j) { if (j > 0) ull <<= 8; ull |= ucp[4 + j]; } if (info_outp) *info_outp = ull; return !!(ucp[2] & 0x80); /* since spc3r23 should be set */ } else return 0; default: return 0; } } int sg_get_sense_filemark_eom_ili(const unsigned char * sensep, int sb_len, int * filemark_p, int * eom_p, int * ili_p) { const unsigned char * ucp; if (sb_len < 7) return 0; switch (sensep[0] & 0x7f) { case 0x70: case 0x71: if (sensep[2] & 0xe0) { if (filemark_p) *filemark_p = !!(sensep[2] & 0x80); if (eom_p) *eom_p = !!(sensep[2] & 0x40); if (ili_p) *ili_p = !!(sensep[2] & 0x20); return 1; } else return 0; case 0x72: case 0x73: /* Look for stream commands sense data descriptor */ ucp = sg_scsi_sense_desc_find(sensep, sb_len, 4); if (ucp && (ucp[1] >= 2)) { if (ucp[3] & 0xe0) { if (filemark_p) *filemark_p = !!(ucp[3] & 0x80); if (eom_p) *eom_p = !!(ucp[3] & 0x40); if (ili_p) *ili_p = !!(ucp[3] & 0x20); return 1; } } return 0; default: return 0; } } int sg_get_sense_progress_fld(const unsigned char * sensep, int sb_len, int * progress_outp) { const unsigned char * ucp; int sk, sk_pr; if (sb_len < 7) return 0; switch (sensep[0] & 0x7f) { case 0x70: case 0x71: sk = (sensep[2] & 0xf); if ((sb_len < 18) || ((SPC_SK_NO_SENSE != sk) && (SPC_SK_NOT_READY != sk))) return 0; if (sensep[15] & 0x80) { if (progress_outp) *progress_outp = (sensep[16] << 8) + sensep[17]; return 1; } else return 0; case 0x72: case 0x73: /* sense key specific progress (0x2) or progress descriptor (0xa) */ sk = (sensep[1] & 0xf); sk_pr = (SPC_SK_NO_SENSE == sk) || (SPC_SK_NOT_READY == sk); if (sk_pr && ((ucp = sg_scsi_sense_desc_find(sensep, sb_len, 2))) && (0x6 == ucp[1]) && (0x80 & ucp[4])) { if (progress_outp) *progress_outp = (ucp[5] << 8) + ucp[6]; return 1; } else if (((ucp = sg_scsi_sense_desc_find(sensep, sb_len, 0xa))) && ((0x6 == ucp[1]))) { if (progress_outp) *progress_outp = (ucp[6] << 8) + ucp[7]; return 1; } else return 0; default: return 0; } } char * sg_get_pdt_str(int pdt, int buff_len, char * buff) { if ((pdt < 0) || (pdt > 31)) snprintf(buff, buff_len, "bad pdt"); else snprintf(buff, buff_len, "%s", sg_lib_pdt_strs[pdt]); return buff; } char * sg_get_trans_proto_str(int tpi, int buff_len, char * buff) { if ((tpi < 0) || (tpi > 15)) snprintf(buff, buff_len, "bad tpi"); else snprintf(buff, buff_len, "%s", sg_lib_transport_proto_strs[tpi]); return buff; } #define TPGS_STATE_OPTIMIZED 0x0 #define TPGS_STATE_NONOPTIMIZED 0x1 #define TPGS_STATE_STANDBY 0x2 #define TPGS_STATE_UNAVAILABLE 0x3 #define TPGS_STATE_OFFLINE 0xe #define TPGS_STATE_TRANSITIONING 0xf static int decode_tpgs_state(int st, char * b, int blen) { switch (st) { case TPGS_STATE_OPTIMIZED: return snprintf(b, blen, "active/optimized"); case TPGS_STATE_NONOPTIMIZED: return snprintf(b, blen, "active/non optimized"); case TPGS_STATE_STANDBY: return snprintf(b, blen, "standby"); case TPGS_STATE_UNAVAILABLE: return snprintf(b, blen, "unavailable"); case TPGS_STATE_OFFLINE: return snprintf(b, blen, "offline"); case TPGS_STATE_TRANSITIONING: return snprintf(b, blen, "transitioning between states"); default: return snprintf(b, blen, "unknown: 0x%x", st); } } static int uds_referral_descriptor_str(char * sp, const unsigned char * dp, int alen) { int n = 0; int dlen = alen - 2; int k, j, g, f, tpgd; const unsigned char * tp; uint64_t ull; char c[40]; n += sprintf(sp + n, " Not all referrals: %d\n", !!(dp[2] & 0x1)); dp += 4; for (k = 0, f = 1; (k + 4) < dlen; k += g, dp += g, ++f) { tpgd = dp[3]; g = (tpgd * 4) + 20; n += sprintf(sp + n, " Descriptor %d\n", f); if ((k + g) > dlen) { n += sprintf(sp + n, " truncated descriptor, stop\n"); return n; } ull = 0; for (j = 0; j < 8; ++j) { if (j > 0) ull <<= 8; ull |= dp[4 + j]; } n += sprintf(sp + n, " first uds LBA: 0x%"PRIx64"\n", ull); ull = 0; for (j = 0; j < 8; ++j) { if (j > 0) ull <<= 8; ull |= dp[12 + j]; } n += sprintf(sp + n, " last uds LBA: 0x%"PRIx64"\n", ull); for (j = 0; j < tpgd; ++j) { tp = dp + 20 + (j * 4); decode_tpgs_state(tp[0] & 0xf, c, sizeof(c)); n += sprintf(sp + n, " tpg: %d state: %s\n", (tp[2] << 8) + tp[3], c); } } return n; } static const char * sdata_src[] = { "unknown", "Extended Copy command source device", "Extended Copy command destination device", }; /* Print descriptor format sense descriptors (assumes sense buffer is in descriptor format) */ static void sg_get_sense_descriptors_str(const unsigned char * sense_buffer, int sb_len, int buff_len, char * buff) { int add_sen_len, add_len, desc_len, k, j, sense_key, processed; int n, progress, pr, rem; const unsigned char * descp; const char * dtsp = " >> descriptor too short"; char b[2048]; if ((NULL == buff) || (buff_len <= 0)) return; buff[0] = '\0'; if ((sb_len < 8) || (0 == (add_sen_len = sense_buffer[7]))) return; add_sen_len = (add_sen_len < (sb_len - 8)) ? add_sen_len : (sb_len - 8); descp = &sense_buffer[8]; sense_key = (sense_buffer[1] & 0xf); for (desc_len = 0, k = 0; k < add_sen_len; k += desc_len) { descp += desc_len; add_len = (k < (add_sen_len - 1)) ? descp[1] : -1; if ((k + add_len + 2) > add_sen_len) add_len = add_sen_len - k - 2; desc_len = add_len + 2; n = 0; n += sprintf(b + n, " Descriptor type: "); processed = 1; switch (descp[0]) { case 0: n += sprintf(b + n, "Information\n"); if ((add_len >= 10) && (0x80 & descp[2])) { n += sprintf(b + n, " 0x"); for (j = 0; j < 8; ++j) n += sprintf(b + n, "%02x", descp[4 + j]); n += sprintf(b + n, "\n"); } else { n += sprintf(b + n, "%s\n", dtsp); processed = 0; } break; case 1: n += sprintf(b + n, "Command specific\n"); if (add_len >= 10) { n += sprintf(b + n, " 0x"); for (j = 0; j < 8; ++j) n += sprintf(b + n, "%02x", descp[4 + j]); n += sprintf(b + n, "\n"); } else { n += sprintf(b + n, "%s\n", dtsp); processed = 0; } break; case 2: n += sprintf(b + n, "Sense key specific:"); switch (sense_key) { case SPC_SK_ILLEGAL_REQUEST: n += sprintf(b + n, " Field pointer\n"); if (add_len < 6) { n += sprintf(b + n, "%s\n", dtsp); processed = 0; break; } n += sprintf(b + n, " Error in %s byte %d", (descp[4] & 0x40) ? "Command" : "Data", (descp[5] << 8) | descp[6]); if (descp[4] & 0x08) { n += sprintf(b + n, " bit %d\n", descp[4] & 0x07); } else n += sprintf(b + n, "\n"); break; case SPC_SK_HARDWARE_ERROR: case SPC_SK_MEDIUM_ERROR: case SPC_SK_RECOVERED_ERROR: n += sprintf(b + n, " Actual retry count\n"); if (add_len < 6) { n += sprintf(b + n, "%s\n", dtsp); processed = 0; break; } n += sprintf(b + n, " 0x%02x%02x\n", descp[5], descp[6]); break; case SPC_SK_NO_SENSE: case SPC_SK_NOT_READY: n += sprintf(b + n, " Progress indication: "); if (add_len < 6) { n += sprintf(b + n, "%s\n", dtsp); processed = 0; break; } progress = (descp[5] << 8) + descp[6]; pr = (progress * 100) / 65536; rem = ((progress * 100) % 65536) / 655; n += sprintf(b + n, "%d.%02d%%\n", pr, rem); break; case SPC_SK_COPY_ABORTED: n += sprintf(b + n, " Segment pointer\n"); if (add_len < 6) { n += sprintf(b + n, "%s\n", dtsp); processed = 0; break; } n += sprintf(b + n, " Relative to start of %s, byte %d", (descp[4] & 0x20) ? "segment descriptor" : "parameter list", (descp[5] << 8) | descp[6]); if (descp[4] & 0x08) n += sprintf(b + n, " bit %d\n", descp[4] & 0x07); else n += sprintf(b + n, "\n"); break; case SPC_SK_UNIT_ATTENTION: n += sprintf(b + n, " Unit attention condition queue: "); n += sprintf(b + n, "overflow flag is %d\n", !!(descp[4] & 0x1)); break; default: n += sprintf(b + n, " Sense_key: 0x%x unexpected\n", sense_key); processed = 0; break; } break; case 3: n += sprintf(b + n, "Field replaceable unit\n"); if (add_len >= 2) n += sprintf(b + n, " code=0x%x\n", descp[3]); else { n += sprintf(b + n, "%s\n", dtsp); processed = 0; } break; case 4: n += sprintf(b + n, "Stream commands\n"); if (add_len >= 2) { if (descp[3] & 0x80) n += sprintf(b + n, " FILEMARK"); if (descp[3] & 0x40) n += sprintf(b + n, " End Of Medium (EOM)"); if (descp[3] & 0x20) n += sprintf(b + n, " Incorrect Length Indicator " "(ILI)"); n += sprintf(b + n, "\n"); } else { n += sprintf(b + n, "%s\n", dtsp); processed = 0; } break; case 5: n += sprintf(b + n, "Block commands\n"); if (add_len >= 2) n += sprintf(b + n, " Incorrect Length Indicator " "(ILI) %s\n", (descp[3] & 0x20) ? "set" : "clear"); else { n += sprintf(b + n, "%s\n", dtsp); processed = 0; } break; case 6: n += sprintf(b + n, "OSD object identification\n"); processed = 0; break; case 7: n += sprintf(b + n, "OSD response integrity check value\n"); processed = 0; break; case 8: n += sprintf(b + n, "OSD attribute identification\n"); processed = 0; break; case 9: n += sprintf(b + n, "ATA Status Return\n"); if (add_len >= 12) { int extend, sector_count; extend = descp[2] & 1; sector_count = descp[5] + (extend ? (descp[4] << 8) : 0); n += sprintf(b + n, " extend=%d error=0x%x " " sector_count=0x%x\n", extend, descp[3], sector_count); if (extend) n += sprintf(b + n, " lba=0x%02x%02x%02x%02x%02x%02x\n", descp[10], descp[8], descp[6], descp[11], descp[9], descp[7]); else n += sprintf(b + n, " lba=0x%02x%02x%02x\n", descp[11], descp[9], descp[7]); n += sprintf(b + n, " device=0x%x status=0x%x\n", descp[12], descp[13]); } else { n += sprintf(b + n, "%s\n", dtsp); processed = 0; } break; case 0xa: /* Added in SPC-4 rev 17 */ n += sprintf(b + n, "Progress indication\n"); if (add_len < 6) { n += sprintf(b + n, "%s\n", dtsp); processed = 0; break; } progress = (descp[6] << 8) + descp[7]; pr = (progress * 100) / 65536; rem = ((progress * 100) % 65536) / 655; n += sprintf(b + n, " %d.02%d%%", pr, rem); n += sprintf(b + n, " [sense_key=0x%x asc,ascq=0x%x,0x%x]\n", descp[2], descp[3], descp[4]); break; case 0xb: /* Added in SPC-4 rev 23, defined in SBC-3 rev 22 */ n += sprintf(b + n, "User data segment referral\n"); if (add_len < 2) { n += sprintf(b + n, "%s\n", dtsp); processed = 0; break; } n += uds_referral_descriptor_str(b + n, descp, add_len); break; case 0xc: /* Added in SPC-4 rev 28 */ n += sprintf(b + n, "Forwarded sense data\n"); if (add_len < 2) { n += sprintf(b + n, "%s\n", dtsp); processed = 0; break; } n += sprintf(b + n, " FSDT: %s\n", (descp[2] & 0x80) ? "set" : "clear"); j = descp[2] & 0xf; if (j < 3) n += sprintf(b + n, " Sense data source: %s\n", sdata_src[j]); else n += sprintf(b + n, " Sense data source: reserved [%d]\n", j); { char c[200]; sg_get_scsi_status_str(descp[3], sizeof(c) - 1, c); c[sizeof(c) - 1] = '\0'; n += sprintf(b + n, " Forwarded status: %s\n", c); if (add_len > 2) { /* recursing; hope not to get carried away */ n += sprintf(b + n, " vvvvvvvvvvvvvvvv\n"); sg_get_sense_str(NULL, descp + 4, add_len - 2, 0, sizeof(c), c); n += sprintf(b + n, "%s", c); n += sprintf(b + n, " ^^^^^^^^^^^^^^^^\n"); } } break; default: n += sprintf(b + n, "Unknown or vendor specific [0x%x]\n", descp[0]); processed = 0; break; } if (! processed) { if (add_len > 0) { n += sprintf(b + n, " "); for (j = 0; j < add_len; ++j) { if ((j > 0) && (0 == (j % 24))) n += sprintf(b + n, "\n "); n += sprintf(b + n, "%02x ", descp[j + 2]); } n += sprintf(b + n, "\n"); } } if (add_len < 0) n += sprintf(b + n, " short descriptor\n"); j = strlen(buff); if ((n + j) >= buff_len) { strncpy(buff + j, b, buff_len - j); buff[buff_len - 1] = '\0'; break; } strcpy(buff + j, b); if (add_len < 0) break; } } /* Fetch sense information */ void sg_get_sense_str(const char * leadin, const unsigned char * sense_buffer, int sb_len, int raw_sinfo, int buff_len, char * buff) { int len, valid, progress, n, r, pr, rem; unsigned int info; int descriptor_format = 0; const char * error = NULL; char error_buff[64]; char b[256]; struct sg_scsi_sense_hdr ssh; if ((NULL == buff) || (buff_len <= 0)) return; buff[buff_len - 1] = '\0'; --buff_len; n = 0; if (sb_len < 1) { snprintf(buff, buff_len, "sense buffer empty\n"); return; } if (leadin) { n += snprintf(buff + n, buff_len - n, "%s: ", leadin); if (n >= buff_len) return; } len = sb_len; if (sg_scsi_normalize_sense(sense_buffer, sb_len, &ssh)) { switch (ssh.response_code) { case 0x70: /* fixed, current */ error = "Fixed format, current"; len = (sb_len > 7) ? (sense_buffer[7] + 8) : sb_len; len = (len > sb_len) ? sb_len : len; break; case 0x71: /* fixed, deferred */ /* error related to a previous command */ error = "Fixed format, <<>>"; len = (sb_len > 7) ? (sense_buffer[7] + 8) : sb_len; len = (len > sb_len) ? sb_len : len; break; case 0x72: /* descriptor, current */ descriptor_format = 1; error = "Descriptor format, current"; break; case 0x73: /* descriptor, deferred */ descriptor_format = 1; error = "Descriptor format, <<>>"; break; case 0x0: error = "Response code: 0x0 (?)"; break; default: snprintf(error_buff, sizeof(error_buff), "Unknown response code: 0x%x", ssh.response_code); error = error_buff; break; } n += snprintf(buff + n, buff_len - n, " %s; Sense key: %s\n ", error, sg_lib_sense_key_desc[ssh.sense_key]); if (n >= buff_len) return; if (descriptor_format) { n += snprintf(buff + n, buff_len - n, "%s\n", sg_get_asc_ascq_str(ssh.asc, ssh.ascq, sizeof(b), b)); if (n >= buff_len) return; sg_get_sense_descriptors_str(sense_buffer, len, buff_len - n, buff + n); n = strlen(buff); if (n >= buff_len) return; } else if (len > 2) { /* fixed format */ if (len > 12) { n += snprintf(buff + n, buff_len - n, "%s\n", sg_get_asc_ascq_str(ssh.asc, ssh.ascq, sizeof(b), b)); if (n >= buff_len) return; } r = 0; valid = sense_buffer[0] & 0x80; if (len > 6) { info = (unsigned int)((sense_buffer[3] << 24) | (sense_buffer[4] << 16) | (sense_buffer[5] << 8) | sense_buffer[6]); if (valid) r += sprintf(b + r, " Info fld=0x%x [%u] ", info, info); else if (info > 0) r += sprintf(b + r, " Valid=0, Info fld=0x%x [%u] ", info, info); } else info = 0; if (sense_buffer[2] & 0xe0) { if (sense_buffer[2] & 0x80) r += sprintf(b + r, " FMK"); /* current command has read a filemark */ if (sense_buffer[2] & 0x40) r += sprintf(b + r, " EOM"); /* end-of-medium condition exists */ if (sense_buffer[2] & 0x20) r += sprintf(b + r, " ILI"); /* incorrect block length requested */ r += sprintf(b + r, "\n"); } else if (valid || (info > 0)) r += sprintf(b + r, "\n"); if ((len >= 14) && sense_buffer[14]) r += sprintf(b + r, " Field replaceable unit code: " "%d\n", sense_buffer[14]); if ((len >= 18) && (sense_buffer[15] & 0x80)) { /* sense key specific decoding */ switch (ssh.sense_key) { case SPC_SK_ILLEGAL_REQUEST: r += sprintf(b + r, " Sense Key Specific: Error in " "%s byte %d", (sense_buffer[15] & 0x40) ? "Command" : "Data", (sense_buffer[16] << 8) | sense_buffer[17]); if (sense_buffer[15] & 0x08) r += sprintf(b + r, " bit %d\n", sense_buffer[15] & 0x07); else r += sprintf(b + r, "\n"); break; case SPC_SK_NO_SENSE: case SPC_SK_NOT_READY: progress = (sense_buffer[16] << 8) + sense_buffer[17]; pr = (progress * 100) / 65536; rem = ((progress * 100) % 65536) / 655; r += sprintf(b + r, " Progress indication: %d.%02d%%\n", pr, rem); break; case SPC_SK_HARDWARE_ERROR: case SPC_SK_MEDIUM_ERROR: case SPC_SK_RECOVERED_ERROR: r += sprintf(b + r, " Actual retry count: " "0x%02x%02x\n", sense_buffer[16], sense_buffer[17]); break; case SPC_SK_COPY_ABORTED: r += sprintf(b + r, " Segment pointer: "); r += sprintf(b + r, "Relative to start of %s, byte %d", (sense_buffer[15] & 0x20) ? "segment descriptor" : "parameter list", (sense_buffer[16] << 8) + sense_buffer[17]); if (sense_buffer[15] & 0x08) r += sprintf(b + r, " bit %d\n", sense_buffer[15] & 0x07); else r += sprintf(b + r, "\n"); break; case SPC_SK_UNIT_ATTENTION: r += sprintf(b + r, " Unit attention condition queue: "); r += sprintf(b + r, "overflow flag is %d\n", !!(sense_buffer[15] & 0x1)); break; default: r += sprintf(b + r, " Sense_key: 0x%x unexpected\n", ssh.sense_key); break; } } if (r > 0) { n += snprintf(buff + n, buff_len - n, "%s", b); if (n >= buff_len) return; } } else { n += snprintf(buff + n, buff_len - n, " fixed descriptor " "length too short, len=%d\n", len); if (n >= buff_len) return; } } else { /* non-extended SCSI-1 sense data ?? */ if (sb_len < 4) { n += snprintf(buff + n, buff_len - n, "sense buffer too short " "(4 byte minimum)\n"); return; } r = 0; r += sprintf(b + r, "Probably uninitialized data.\n Try to view " "as SCSI-1 non-extended sense:\n"); r += sprintf(b + r, " AdValid=%d Error class=%d Error code=%d\n", !!(sense_buffer[0] & 0x80), ((sense_buffer[0] >> 4) & 0x7), (sense_buffer[0] & 0xf)); if (sense_buffer[0] & 0x80) r += sprintf(b + r, " lba=0x%x\n", ((sense_buffer[1] & 0x1f) << 16) + (sense_buffer[2] << 8) + sense_buffer[3]); n += snprintf(buff + n, buff_len - n, "%s\n", b); if (n >= buff_len) return; len = sb_len; if (len > 32) len = 32; /* trim in case there is a lot of rubbish */ } if (raw_sinfo) { n += snprintf(buff + n, buff_len - n, " Raw sense data (in hex):\n"); if (n >= buff_len) return; dStrHexErr((const char *)sense_buffer, len, buff_len - n, buff + n); } } /* Print sense information */ void sg_print_sense(const char * leadin, const unsigned char * sense_buffer, int sb_len, int raw_sinfo) { char b[1024]; sg_get_sense_str(leadin, sense_buffer, sb_len, raw_sinfo, sizeof(b), b); if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; fprintf(sg_warnings_strm, "%s", b); } int sg_scsi_normalize_sense(const unsigned char * sensep, int sb_len, struct sg_scsi_sense_hdr * sshp) { if (sshp) memset(sshp, 0, sizeof(struct sg_scsi_sense_hdr)); if ((NULL == sensep) || (0 == sb_len) || (0x70 != (0x70 & sensep[0]))) return 0; if (sshp) { sshp->response_code = (0x7f & sensep[0]); if (sshp->response_code >= 0x72) { /* descriptor format */ if (sb_len > 1) sshp->sense_key = (0xf & sensep[1]); if (sb_len > 2) sshp->asc = sensep[2]; if (sb_len > 3) sshp->ascq = sensep[3]; if (sb_len > 7) sshp->additional_length = sensep[7]; } else { /* fixed format */ if (sb_len > 2) sshp->sense_key = (0xf & sensep[2]); if (sb_len > 7) { sb_len = (sb_len < (sensep[7] + 8)) ? sb_len : (sensep[7] + 8); if (sb_len > 12) sshp->asc = sensep[12]; if (sb_len > 13) sshp->ascq = sensep[13]; } } } return 1; } int sg_err_category_sense(const unsigned char * sense_buffer, int sb_len) { struct sg_scsi_sense_hdr ssh; if ((sense_buffer && (sb_len > 2)) && (sg_scsi_normalize_sense(sense_buffer, sb_len, &ssh))) { switch (ssh.sense_key) { case SPC_SK_NO_SENSE: return SG_LIB_CAT_NO_SENSE; case SPC_SK_RECOVERED_ERROR: return SG_LIB_CAT_RECOVERED; case SPC_SK_NOT_READY: return SG_LIB_CAT_NOT_READY; case SPC_SK_MEDIUM_ERROR: case SPC_SK_HARDWARE_ERROR: case SPC_SK_BLANK_CHECK: return SG_LIB_CAT_MEDIUM_HARD; case SPC_SK_UNIT_ATTENTION: return SG_LIB_CAT_UNIT_ATTENTION; /* used to return SG_LIB_CAT_MEDIA_CHANGED when ssh.asc==0x28 */ case SPC_SK_ILLEGAL_REQUEST: if ((0x20 == ssh.asc) && (0x0 == ssh.ascq)) return SG_LIB_CAT_INVALID_OP; else return SG_LIB_CAT_ILLEGAL_REQ; break; case SPC_SK_ABORTED_COMMAND: return SG_LIB_CAT_ABORTED_COMMAND; } } return SG_LIB_CAT_SENSE; } /* gives wrong answer for variable length command (opcode=0x7f) */ int sg_get_command_size(unsigned char opcode) { switch ((opcode >> 5) & 0x7) { case 0: return 6; case 1: case 2: case 6: case 7: return 10; case 3: case 5: return 12; break; case 4: return 16; default: return 10; } } void sg_get_command_name(const unsigned char * cmdp, int peri_type, int buff_len, char * buff) { int service_action; if ((NULL == buff) || (buff_len < 1)) return; if (NULL == cmdp) { strncpy(buff, " command pointer", buff_len); return; } service_action = (SG_VARIABLE_LENGTH_CMD == cmdp[0]) ? (cmdp[1] & 0x1f) : ((cmdp[8] << 8) | cmdp[9]); sg_get_opcode_sa_name(cmdp[0], service_action, peri_type, buff_len, buff); } void sg_get_opcode_sa_name(unsigned char cmd_byte0, int service_action, int peri_type, int buff_len, char * buff) { const struct sg_lib_value_name_t * vnp; if ((NULL == buff) || (buff_len < 1)) return; switch ((int)cmd_byte0) { case SG_VARIABLE_LENGTH_CMD: vnp = get_value_name(sg_lib_variable_length_arr, service_action, peri_type); if (vnp) strncpy(buff, vnp->name, buff_len); else snprintf(buff, buff_len, "Variable length service action=0x%x", service_action); break; case SG_MAINTENANCE_IN: vnp = get_value_name(sg_lib_maint_in_arr, service_action, peri_type); if (vnp) strncpy(buff, vnp->name, buff_len); else snprintf(buff, buff_len, "Maintenance in service action=0x%x", service_action); break; case SG_MAINTENANCE_OUT: vnp = get_value_name(sg_lib_maint_out_arr, service_action, peri_type); if (vnp) strncpy(buff, vnp->name, buff_len); else snprintf(buff, buff_len, "Maintenance out service action=0x%x", service_action); break; case SG_SERVICE_ACTION_IN_12: vnp = get_value_name(sg_lib_serv_in12_arr, service_action, peri_type); if (vnp) strncpy(buff, vnp->name, buff_len); else snprintf(buff, buff_len, "Service action in(12)=0x%x", service_action); break; case SG_SERVICE_ACTION_OUT_12: vnp = get_value_name(sg_lib_serv_out12_arr, service_action, peri_type); if (vnp) strncpy(buff, vnp->name, buff_len); else snprintf(buff, buff_len, "Service action out(12)=0x%x", service_action); break; case SG_SERVICE_ACTION_IN_16: vnp = get_value_name(sg_lib_serv_in16_arr, service_action, peri_type); if (vnp) strncpy(buff, vnp->name, buff_len); else snprintf(buff, buff_len, "Service action in(16)=0x%x", service_action); break; case SG_SERVICE_ACTION_OUT_16: vnp = get_value_name(sg_lib_serv_out16_arr, service_action, peri_type); if (vnp) strncpy(buff, vnp->name, buff_len); else snprintf(buff, buff_len, "Service action out(16)=0x%x", service_action); break; case SG_PERSISTENT_RESERVE_IN: vnp = get_value_name(sg_lib_pr_in_arr, service_action, peri_type); if (vnp) strncpy(buff, vnp->name, buff_len); else snprintf(buff, buff_len, "Persistent reserve in, service " "action=0x%x", service_action); break; case SG_PERSISTENT_RESERVE_OUT: vnp = get_value_name(sg_lib_pr_out_arr, service_action, peri_type); if (vnp) strncpy(buff, vnp->name, buff_len); else snprintf(buff, buff_len, "Persistent reserve out, service " "action=0x%x", service_action); break; default: sg_get_opcode_name(cmd_byte0, peri_type, buff_len, buff); break; } } void sg_get_opcode_name(unsigned char cmd_byte0, int peri_type, int buff_len, char * buff) { const struct sg_lib_value_name_t * vnp; int grp; if ((NULL == buff) || (buff_len < 1)) return; if (SG_VARIABLE_LENGTH_CMD == cmd_byte0) { strncpy(buff, "Variable length", buff_len); return; } grp = (cmd_byte0 >> 5) & 0x7; switch (grp) { case 0: case 1: case 2: case 4: case 5: vnp = get_value_name(sg_lib_normal_opcodes, cmd_byte0, peri_type); if (vnp) strncpy(buff, vnp->name, buff_len); else snprintf(buff, buff_len, "Opcode=0x%x", (int)cmd_byte0); break; case 3: snprintf(buff, buff_len, "Reserved [0x%x]", (int)cmd_byte0); break; case 6: case 7: snprintf(buff, buff_len, "Vendor specific [0x%x]", (int)cmd_byte0); break; default: snprintf(buff, buff_len, "Opcode=0x%x", (int)cmd_byte0); break; } } int sg_vpd_dev_id_iter(const unsigned char * initial_desig_desc, int page_len, int * off, int m_assoc, int m_desig_type, int m_code_set) { const unsigned char * ucp; int k, c_set, assoc, desig_type; for (k = *off, ucp = initial_desig_desc ; (k + 3) < page_len; ) { k = (k < 0) ? 0 : (k + ucp[k + 3] + 4); if ((k + 4) > page_len) break; c_set = (ucp[k] & 0xf); if ((m_code_set >= 0) && (m_code_set != c_set)) continue; assoc = ((ucp[k + 1] >> 4) & 0x3); if ((m_assoc >= 0) && (m_assoc != assoc)) continue; desig_type = (ucp[k + 1] & 0xf); if ((m_desig_type >= 0) && (m_desig_type != desig_type)) continue; *off = k; return 0; } return (k == page_len) ? -1 : -2; } /* safe_strerror() contributed by Clayton Weaver Allows for situation in which strerror() is given a wild value (or the C library is incomplete) and returns NULL. Still not thread safe. */ static char safe_errbuf[64] = {'u', 'n', 'k', 'n', 'o', 'w', 'n', ' ', 'e', 'r', 'r', 'n', 'o', ':', ' ', 0}; char * safe_strerror(int errnum) { size_t len; char * errstr; if (errnum < 0) errnum = -errnum; errstr = strerror(errnum); if (NULL == errstr) { len = strlen(safe_errbuf); snprintf(safe_errbuf + len, sizeof(safe_errbuf) - len, "%i", errnum); safe_errbuf[sizeof(safe_errbuf) - 1] = '\0'; /* bombproof */ return safe_errbuf; } return errstr; } /* Note the ASCII-hex output goes to stdout. [Most other output from functions in this file go to sg_warnings_strm (default stderr).] 'no_ascii' allows for 3 output types: > 0 each line has address then up to 16 ASCII-hex bytes = 0 in addition, the bytes are listed in ASCII to the right < 0 only the ASCII-hex bytes are listed (i.e. without address) */ void dStrHex(const char* str, int len, int no_ascii) { const char * p = str; const char * formatstr; unsigned char c; char buff[82]; int a = 0; const int bpstart = 5; const int cpstart = 60; int cpos = cpstart; int bpos = bpstart; int i, k; if (len <= 0) return; formatstr = (0 == no_ascii) ? "%.76s\n" : "%.56s\n"; memset(buff, ' ', 80); buff[80] = '\0'; if (no_ascii < 0) { for (k = 0; k < len; k++) { c = *p++; bpos += 3; if (bpos == (bpstart + (9 * 3))) bpos++; sprintf(&buff[bpos], "%.2x", (int)(unsigned char)c); buff[bpos + 2] = ' '; if ((k > 0) && (0 == ((k + 1) % 16))) { printf(formatstr, buff); bpos = bpstart; memset(buff, ' ', 80); } } if (bpos > bpstart) { buff[bpos + 2] = '\0'; printf("%s\n", buff); } return; } /* no_ascii>=0, start each line with address (offset) */ k = sprintf(buff + 1, "%.2x", a); buff[k + 1] = ' '; for (i = 0; i < len; i++) { c = *p++; bpos += 3; if (bpos == (bpstart + (9 * 3))) bpos++; sprintf(&buff[bpos], "%.2x", (int)(unsigned char)c); buff[bpos + 2] = ' '; if (no_ascii) buff[cpos++] = ' '; else { if ((c < ' ') || (c >= 0x7f)) c = '.'; buff[cpos++] = c; } if (cpos > (cpstart + 15)) { printf(formatstr, buff); bpos = bpstart; cpos = cpstart; a += 16; memset(buff, ' ', 80); k = sprintf(buff + 1, "%.2x", a); buff[k + 1] = ' '; } } if (cpos > cpstart) { buff[cpos] = '\0'; printf("%s\n", buff); } } /* Output to ASCII-Hex bytes to 'b' not to exceed 'b_len' characters. * 16 bytes per line with an extra space between the 8th and 9th bytes */ static void dStrHexErr(const char* str, int len, int b_len, char * b) { const char * p = str; unsigned char c; char buff[82]; const int bpstart = 5; int bpos = bpstart; int k, n; if (len <= 0) return; n = 0; memset(buff, ' ', 80); buff[80] = '\0'; for (k = 0; k < len; k++) { c = *p++; bpos += 3; if (bpos == (bpstart + (9 * 3))) bpos++; sprintf(&buff[bpos], "%.2x", (int)(unsigned char)c); buff[bpos + 2] = ' '; if ((k > 0) && (0 == ((k + 1) % 16))) { n += snprintf(b + n, b_len - n, "%.60s\n", buff); if (n >= b_len) return; bpos = bpstart; memset(buff, ' ', 80); } } if (bpos > bpstart) n += snprintf(b + n, b_len - n, "%.60s\n", buff); return; } /* Returns 1 when executed on big endian machine; else returns 0. Useful for displaying ATA identify words (which need swapping on a big endian machine). */ int sg_is_big_endian() { union u_t { unsigned short s; unsigned char c[sizeof(unsigned short)]; } u; u.s = 0x0102; return (u.c[0] == 0x01); /* The lowest address contains the most significant byte */ } static unsigned short swapb_ushort(unsigned short u) { unsigned short r; r = (u >> 8) & 0xff; r |= ((u & 0xff) << 8); return r; } /* Note the ASCII-hex output goes to stdout. [Most other output from functions in this file go to sg_warnings_strm (default stderr).] 'no_ascii' allows for 3 output types: > 0 each line has address then up to 8 ASCII-hex 16 bit words = 0 in addition, the ASCI bytes pairs are listed to the right = -1 only the ASCII-hex words are listed (i.e. without address) = -2 only the ASCII-hex words, formatted for "hdparm --Istdin" < -2 same as -1 If 'swapb' non-zero then bytes in each word swapped. Needs to be set for ATA IDENTIFY DEVICE response on big-endian machines. */ void dWordHex(const unsigned short* words, int num, int no_ascii, int swapb) { const unsigned short * p = words; unsigned short c; char buff[82]; unsigned char upp, low; int a = 0; const int bpstart = 3; const int cpstart = 52; int cpos = cpstart; int bpos = bpstart; int i, k; if (num <= 0) return; memset(buff, ' ', 80); buff[80] = '\0'; if (no_ascii < 0) { for (k = 0; k < num; k++) { c = *p++; if (swapb) c = swapb_ushort(c); bpos += 5; sprintf(&buff[bpos], "%.4x", (unsigned int)c); buff[bpos + 4] = ' '; if ((k > 0) && (0 == ((k + 1) % 8))) { if (-2 == no_ascii) printf("%.39s\n", buff +8); else printf("%.47s\n", buff); bpos = bpstart; memset(buff, ' ', 80); } } if (bpos > bpstart) { if (-2 == no_ascii) printf("%.39s\n", buff +8); else printf("%.47s\n", buff); } return; } /* no_ascii>=0, start each line with address (offset) */ k = sprintf(buff + 1, "%.2x", a); buff[k + 1] = ' '; for (i = 0; i < num; i++) { c = *p++; if (swapb) c = swapb_ushort(c); bpos += 5; sprintf(&buff[bpos], "%.4x", (unsigned int)c); buff[bpos + 4] = ' '; if (no_ascii) { buff[cpos++] = ' '; buff[cpos++] = ' '; buff[cpos++] = ' '; } else { upp = (c >> 8) & 0xff; low = c & 0xff; if ((upp < 0x20) || (upp >= 0x7f)) upp = '.'; buff[cpos++] = upp; if ((low < 0x20) || (low >= 0x7f)) low = '.'; buff[cpos++] = low; buff[cpos++] = ' '; } if (cpos > (cpstart + 23)) { printf("%.76s\n", buff); bpos = bpstart; cpos = cpstart; a += 8; memset(buff, ' ', 80); k = sprintf(buff + 1, "%.2x", a); buff[k + 1] = ' '; } } if (cpos > cpstart) printf("%.76s\n", buff); } /* If the number in 'buf' can be decoded or the multiplier is unknown then -1 is returned. Accepts a hex prefix (0x or 0X) or a decimal multiplier suffix (as per GNU's dd (since 2002: SI and IEC 60027-2)). Main (SI) multipliers supported: K, M, G. */ int sg_get_num(const char * buf) { int res, num, n, len; unsigned int unum; char * cp; char c = 'c'; char c2, c3; if ((NULL == buf) || ('\0' == buf[0])) return -1; len = strlen(buf); if (('0' == buf[0]) && (('x' == buf[1]) || ('X' == buf[1]))) { res = sscanf(buf + 2, "%x", &unum); num = unum; } else if ('H' == toupper((int)buf[len - 1])) { res = sscanf(buf, "%x", &unum); num = unum; } else res = sscanf(buf, "%d%c%c%c", &num, &c, &c2, &c3); if (res < 1) return -1LL; else if (1 == res) return num; else { if (res > 2) c2 = toupper((int)c2); if (res > 3) c3 = toupper((int)c3); switch (toupper((int)c)) { case 'C': return num; case 'W': return num * 2; case 'B': return num * 512; case 'K': if (2 == res) return num * 1024; if (('B' == c2) || ('D' == c2)) return num * 1000; if (('I' == c2) && (4 == res) && ('B' == c3)) return num * 1024; return -1; case 'M': if (2 == res) return num * 1048576; if (('B' == c2) || ('D' == c2)) return num * 1000000; if (('I' == c2) && (4 == res) && ('B' == c3)) return num * 1048576; return -1; case 'G': if (2 == res) return num * 1073741824; if (('B' == c2) || ('D' == c2)) return num * 1000000000; if (('I' == c2) && (4 == res) && ('B' == c3)) return num * 1073741824; return -1; case 'X': cp = strchr(buf, 'x'); if (NULL == cp) cp = strchr(buf, 'X'); if (cp) { n = sg_get_num(cp + 1); if (-1 != n) return num * n; } return -1; default: if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; fprintf(sg_warnings_strm, "unrecognized multiplier\n"); return -1; } } } /* If the number in 'buf' can not be decoded then -1 is returned. Accepts a hex prefix (0x or 0X) or a 'h' (or 'H') suffix; otherwise decimal is assumed. Does not accept multipliers. Accept a comma (","), a whitespace or newline as terminator. */ int sg_get_num_nomult(const char * buf) { int res, len, num; unsigned int unum; const char * commap; if ((NULL == buf) || ('\0' == buf[0])) return -1; len = strlen(buf); commap = strchr(buf + 1, ','); if (('0' == buf[0]) && (('x' == buf[1]) || ('X' == buf[1]))) { res = sscanf(buf + 2, "%x", &unum); num = unum; } else if (commap && ('H' == toupper((int)*(commap - 1)))) { res = sscanf(buf, "%x", &unum); num = unum; } else if ((NULL == commap) && ('H' == toupper((int)buf[len - 1]))) { res = sscanf(buf, "%x", &unum); num = unum; } else res = sscanf(buf, "%d", &num); if (1 == res) return num; else return -1; } /* If the number in 'buf' can be decoded or the multiplier is unknown then -1LL is returned. Accepts a hex prefix (0x or 0X) or a decimal multiplier suffix (as per GNU's dd (since 2002: SI and IEC 60027-2)). Main (SI) multipliers supported: K, M, G, T, P. */ int64_t sg_get_llnum(const char * buf) { int res, len; int64_t num, ll; uint64_t unum; char * cp; char c = 'c'; char c2, c3; if ((NULL == buf) || ('\0' == buf[0])) return -1LL; len = strlen(buf); if (('0' == buf[0]) && (('x' == buf[1]) || ('X' == buf[1]))) { res = sscanf(buf + 2, "%" SCNx64 "", &unum); num = unum; } else if ('H' == toupper((int)buf[len - 1])) { res = sscanf(buf, "%" SCNx64 "", &unum); num = unum; } else res = sscanf(buf, "%" SCNd64 "%c%c%c", &num, &c, &c2, &c3); if (res < 1) return -1LL; else if (1 == res) return num; else { if (res > 2) c2 = toupper((int)c2); if (res > 3) c3 = toupper((int)c3); switch (toupper((int)c)) { case 'C': return num; case 'W': return num * 2; case 'B': return num * 512; case 'K': if (2 == res) return num * 1024; if (('B' == c2) || ('D' == c2)) return num * 1000; if (('I' == c2) && (4 == res) && ('B' == c3)) return num * 1024; return -1LL; case 'M': if (2 == res) return num * 1048576; if (('B' == c2) || ('D' == c2)) return num * 1000000; if (('I' == c2) && (4 == res) && ('B' == c3)) return num * 1048576; return -1LL; case 'G': if (2 == res) return num * 1073741824; if (('B' == c2) || ('D' == c2)) return num * 1000000000; if (('I' == c2) && (4 == res) && ('B' == c3)) return num * 1073741824; return -1LL; case 'T': if (2 == res) return num * 1099511627776LL; if (('B' == c2) || ('D' == c2)) return num * 1000000000000LL; if (('I' == c2) && (4 == res) && ('B' == c3)) return num * 1099511627776LL; return -1LL; case 'P': if (2 == res) return num * 1099511627776LL * 1024; if (('B' == c2) || ('D' == c2)) return num * 1000000000000LL * 1000; if (('I' == c2) && (4 == res) && ('B' == c3)) return num * 1099511627776LL * 1024; return -1LL; case 'X': cp = strchr(buf, 'x'); if (NULL == cp) cp = strchr(buf, 'X'); if (cp) { ll = sg_get_llnum(cp + 1); if (-1LL != ll) return num * ll; } return -1LL; default: if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; fprintf(sg_warnings_strm, "unrecognized multiplier\n"); return -1LL; } } } /* Extract character sequence from ATA words as in the model string in a IDENTIFY DEVICE response. Returns number of characters written to 'ochars' before 0 character is found or 'num' words are processed. */ int sg_ata_get_chars(const unsigned short * word_arr, int start_word, int num_words, int is_big_endian, char * ochars) { int k; unsigned short s; char a, b; char * op = ochars; for (k = start_word; k < (start_word + num_words); ++k) { s = word_arr[k]; if (is_big_endian) { a = s & 0xff; b = (s >> 8) & 0xff; } else { a = (s >> 8) & 0xff; b = s & 0xff; } if (a == 0) break; *op++ = a; if (b == 0) break; *op++ = b; } return op - ochars; } const char * sg_lib_version() { return sg_lib_version_str; } #ifdef SG_LIB_MINGW /* Non Unix OSes distinguish between text and binary files. Set text mode on fd. Does nothing in Unix. Returns negative number on failure. */ #include #include int sg_set_text_mode(int fd) { return setmode(fd, O_TEXT); } /* Set binary mode on fd. Does nothing in Unix. Returns negative number on failure. */ int sg_set_binary_mode(int fd) { return setmode(fd, O_BINARY); } #else /* For Unix the following functions are dummies. */ int sg_set_text_mode(int fd) { return fd; /* fd should be >= 0 */ } int sg_set_binary_mode(int fd) { return fd; } #endif ddpt-0.92/lib/sg_pt_osf1.c0000644000175000017500000003024411351460102014345 0ustar douggdougg/* * Copyright (c) 2005-2010 Douglas Gilbert. * All rights reserved. * Use of this source code is governed by a BSD-style * license that can be found in the BSD_LICENSE file. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "sg_pt.h" #include "sg_lib.h" /* Changed to use struct sg_pt_base 20070403 */ #define OSF1_MAXDEV 64 struct osf1_dev_channel { int bus; int tgt; int lun; }; // Private table of open devices: guaranteed zero on startup since // part of static data. static struct osf1_dev_channel *devicetable[OSF1_MAXDEV] = {0}; static char *cam_dev = "/dev/cam"; static int camfd; static int camopened = 0; struct sg_pt_osf1_scsi { unsigned char * cdb; int cdb_len; unsigned char * sense; int sense_len; unsigned char * dxferp; int dxfer_len; int dxfer_dir; int scsi_status; int resid; int sense_resid; int in_err; int os_err; int transport_err; }; struct sg_pt_base { struct sg_pt_osf1_scsi impl; }; /* Returns >= 0 if successful. If error in Unix returns negated errno. */ int scsi_pt_open_device(const char * device_name, int read_only, int verbose) { int oflags = 0 /* O_NONBLOCK*/ ; oflags |= (read_only ? O_RDONLY : O_RDWR); return scsi_pt_open_flags(device_name, oflags, verbose); } /* Similar to scsi_pt_open_device() but takes Unix style open flags OR-ed * together. The 'flags' argument is ignored in OSF-1. * Returns >= 0 if successful, otherwise returns negated errno. */ int scsi_pt_open_flags(const char * device_name, int flags, int verbose) { struct osf1_dev_channel *fdchan; int fd, k; if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; if (!camopened) { camfd = open(cam_dev, O_RDWR, 0); if (camfd < 0) return -1; camopened++; } // Search table for a free entry for (k = 0; k < OSF1_MAXDEV; k++) if (! devicetable[k]) break; if (k == OSF1_MAXDEV) { if (verbose) fprintf(sg_warnings_strm, "too many open devices " "(%d)\n", OSF1_MAXDEV); errno=EMFILE; return -1; } fdchan = (struct osf1_dev_channel *)calloc(1, sizeof(struct osf1_dev_channel)); if (fdchan == NULL) { // errno already set by call to malloc() return -1; } fd = open(device_name, O_RDONLY|O_NONBLOCK); if (fd > 0) { device_info_t devinfo; bzero(&devinfo, sizeof(devinfo)); if (ioctl(fd, DEVGETINFO, &devinfo) == 0) { fdchan->bus = devinfo.v1.businfo.bus.scsi.bus_num; fdchan->tgt = devinfo.v1.businfo.bus.scsi.tgt_id; fdchan->lun = devinfo.v1.businfo.bus.scsi.lun; } close (fd); } else { free(fdchan); return -1; } devicetable[k] = fdchan; return k; } /* Returns 0 if successful. If error in Unix returns negated errno. */ int scsi_pt_close_device(int device_fd) { struct osf1_dev_channel *fdchan; int i; if ((device_fd < 0) || (device_fd >= OSF1_MAXDEV)) { errno = ENODEV; return -1; } fdchan = devicetable[device_fd]; if (NULL == fdchan) { errno = ENODEV; return -1; } free(fdchan); devicetable[device_fd] = NULL; for (i = 0; i < OSF1_MAXDEV; i++) { if (devicetable[i]) break; } if (i == OSF1_MAXDEV) { close(camfd); camopened = 0; } return 0; } struct sg_pt_base * construct_scsi_pt_obj() { struct sg_pt_osf1_scsi * ptp; ptp = (struct sg_pt_osf1_scsi *)malloc(sizeof(struct sg_pt_osf1_scsi)); if (ptp) { bzero(ptp, sizeof(struct sg_pt_osf1_scsi)); ptp->dxfer_dir = CAM_DIR_NONE; } return (struct sg_pt_base *)ptp; } void destruct_scsi_pt_obj(struct sg_pt_base * vp) { struct sg_pt_osf1_scsi * ptp = &vp->impl; if (ptp) free(ptp); } void clear_scsi_pt_obj(struct sg_pt_base * vp) { struct sg_pt_osf1_scsi * ptp = &vp->impl; if (ptp) { bzero(ptp, sizeof(struct sg_pt_osf1_scsi)); ptp->dxfer_dir = CAM_DIR_NONE; } } void set_scsi_pt_cdb(struct sg_pt_base * vp, const unsigned char * cdb, int cdb_len) { struct sg_pt_osf1_scsi * ptp = &vp->impl; if (ptp->cdb) ++ptp->in_err; ptp->cdb = (unsigned char *)cdb; ptp->cdb_len = cdb_len; } void set_scsi_pt_sense(struct sg_pt_base * vp, unsigned char * sense, int max_sense_len) { struct sg_pt_osf1_scsi * ptp = &vp->impl; if (ptp->sense) ++ptp->in_err; bzero(sense, max_sense_len); ptp->sense = sense; ptp->sense_len = max_sense_len; } /* from device */ void set_scsi_pt_data_in(struct sg_pt_base * vp, unsigned char * dxferp, int dxfer_len) { struct sg_pt_osf1_scsi * ptp = &vp->impl; if (ptp->dxferp) ++ptp->in_err; if (dxfer_len > 0) { ptp->dxferp = dxferp; ptp->dxfer_len = dxfer_len; ptp->dxfer_dir = CAM_DIR_IN; } } /* to device */ void set_scsi_pt_data_out(struct sg_pt_base * vp, const unsigned char * dxferp, int dxfer_len) { struct sg_pt_osf1_scsi * ptp = &vp->impl; if (ptp->dxferp) ++ptp->in_err; if (dxfer_len > 0) { ptp->dxferp = (unsigned char *)dxferp; ptp->dxfer_len = dxfer_len; ptp->dxfer_dir = CAM_DIR_OUT; } } void set_scsi_pt_packet_id(struct sg_pt_base * vp, int pack_id) { } void set_scsi_pt_tag(struct sg_pt_base * vp, uint64_t tag) { struct sg_pt_osf1_scsi * ptp = &vp->impl; ++ptp->in_err; } void set_scsi_pt_task_management(struct sg_pt_base * vp, int tmf_code) { struct sg_pt_osf1_scsi * ptp = &vp->impl; ++ptp->in_err; } void set_scsi_pt_task_attr(struct sg_pt_base * vp, int attrib, int priority) { struct sg_pt_osf1_scsi * ptp = &vp->impl; ++ptp->in_err; } void set_scsi_pt_flags(struct sg_pt_base * objp, int flags) { /* do nothing, suppress warnings */ objp = objp; flags = flags; } static int release_sim(struct sg_pt_base *vp, int device_fd, int verbose) { struct sg_pt_osf1_scsi * ptp = &vp->impl; struct osf1_dev_channel *fdchan = devicetable[device_fd]; UAGT_CAM_CCB uagt; CCB_RELSIM relsim; int retval; if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; bzero(&uagt, sizeof(uagt)); bzero(&relsim, sizeof(relsim)); uagt.uagt_ccb = (CCB_HEADER *) &relsim; uagt.uagt_ccblen = sizeof(relsim); relsim.cam_ch.cam_ccb_len = sizeof(relsim); relsim.cam_ch.cam_func_code = XPT_REL_SIMQ; relsim.cam_ch.cam_flags = CAM_DIR_IN | CAM_DIS_CALLBACK; relsim.cam_ch.cam_path_id = fdchan->bus; relsim.cam_ch.cam_target_id = fdchan->tgt; relsim.cam_ch.cam_target_lun = fdchan->lun; retval = ioctl(camfd, UAGT_CAM_IO, &uagt); if (retval < 0) { if (verbose) fprintf(sg_warnings_strm, "CAM ioctl error (Release SIM Queue)\n"); } return retval; } int do_scsi_pt(struct sg_pt_base * vp, int device_fd, int time_secs, int verbose) { struct sg_pt_osf1_scsi * ptp = &vp->impl; struct osf1_dev_channel *fdchan; int len, retval; CCB_SCSIIO ccb; UAGT_CAM_CCB uagt; unsigned char sensep[ADDL_SENSE_LENGTH]; if (NULL == sg_warnings_strm) sg_warnings_strm = stderr; ptp->os_err = 0; if (ptp->in_err) { if (verbose) fprintf(sg_warnings_strm, "Replicated or unused set_scsi_pt...\n"); return SCSI_PT_DO_BAD_PARAMS; } if (NULL == ptp->cdb) { if (verbose) fprintf(sg_warnings_strm, "No command (cdb) given\n"); return SCSI_PT_DO_BAD_PARAMS; } if ((device_fd < 0) || (device_fd >= OSF1_MAXDEV)) { if (verbose) fprintf(sg_warnings_strm, "Bad file descriptor\n"); ptp->os_err = ENODEV; return -ptp->os_err; } fdchan = devicetable[device_fd]; if (NULL == fdchan) { if (verbose) fprintf(sg_warnings_strm, "File descriptor closed??\n"); ptp->os_err = ENODEV; return -ptp->os_err; } if (0 == camopened) { if (verbose) fprintf(sg_warnings_strm, "No open CAM device\n"); return SCSI_PT_DO_BAD_PARAMS; } bzero(&uagt, sizeof(uagt)); bzero(&ccb, sizeof(ccb)); uagt.uagt_ccb = (CCB_HEADER *) &ccb; uagt.uagt_ccblen = sizeof(ccb); uagt.uagt_snsbuf = ccb.cam_sense_ptr = ptp->sense ? ptp->sense : sensep; uagt.uagt_snslen = ccb.cam_sense_len = ptp->sense ? ptp->sense_len : sizeof sensep; uagt.uagt_buffer = ccb.cam_data_ptr = ptp->dxferp; uagt.uagt_buflen = ccb.cam_dxfer_len = ptp->dxfer_len; ccb.cam_timeout = time_secs; ccb.cam_ch.my_addr = (CCB_HEADER *) &ccb; ccb.cam_ch.cam_ccb_len = sizeof(ccb); ccb.cam_ch.cam_func_code = XPT_SCSI_IO; ccb.cam_ch.cam_flags = ptp->dxfer_dir; ccb.cam_cdb_len = ptp->cdb_len; memcpy(ccb.cam_cdb_io.cam_cdb_bytes, ptp->cdb, ptp->cdb_len); ccb.cam_ch.cam_path_id = fdchan->bus; ccb.cam_ch.cam_target_id = fdchan->tgt; ccb.cam_ch.cam_target_lun = fdchan->lun; if (ioctl(camfd, UAGT_CAM_IO, &uagt) < 0) { if (verbose) fprintf(sg_warnings_strm, "CAN I/O Error\n"); ptp->os_err = EIO; return -ptp->os_err; } if (((ccb.cam_ch.cam_status & CAM_STATUS_MASK) == CAM_REQ_CMP) || ((ccb.cam_ch.cam_status & CAM_STATUS_MASK) == CAM_REQ_CMP_ERR)) { ptp->scsi_status = ccb.cam_scsi_status; ptp->resid = ccb.cam_resid; if (ptp->sense) ptp->sense_resid = ccb.cam_sense_resid; } else { ptp->transport_err = 1; } /* If the SIM queue is frozen, release SIM queue. */ if (ccb.cam_ch.cam_status & CAM_SIM_QFRZN) release_sim(vp, device_fd, verbose); return 0; } int get_scsi_pt_result_category(const struct sg_pt_base * vp) { const struct sg_pt_osf1_scsi * ptp = &vp->impl; if (ptp->os_err) return SCSI_PT_RESULT_OS_ERR; else if (ptp->transport_err) return SCSI_PT_RESULT_TRANSPORT_ERR; else if ((SAM_STAT_CHECK_CONDITION == ptp->scsi_status) || (SAM_STAT_COMMAND_TERMINATED == ptp->scsi_status)) return SCSI_PT_RESULT_SENSE; else if (ptp->scsi_status) return SCSI_PT_RESULT_STATUS; else return SCSI_PT_RESULT_GOOD; } int get_scsi_pt_resid(const struct sg_pt_base * vp) { const struct sg_pt_osf1_scsi * ptp = &vp->impl; return ptp->resid; } int get_scsi_pt_status_response(const struct sg_pt_base * vp) { const struct sg_pt_osf1_scsi * ptp = &vp->impl; return ptp->scsi_status; } int get_scsi_pt_sense_len(const struct sg_pt_base * vp) { const struct sg_pt_osf1_scsi * ptp = &vp->impl; int len; len = ptp->sense_len - ptp->sense_resid; return (len > 0) ? len : 0; } int get_scsi_pt_duration_ms(const struct sg_pt_base * vp) { // const struct sg_pt_osf1_scsi * ptp = &vp->impl; return -1; } int get_scsi_pt_transport_err(const struct sg_pt_base * vp) { const struct sg_pt_osf1_scsi * ptp = &vp->impl; return ptp->transport_err; } int get_scsi_pt_os_err(const struct sg_pt_base * vp) { const struct sg_pt_osf1_scsi * ptp = &vp->impl; return ptp->os_err; } char * get_scsi_pt_transport_err_str(const struct sg_pt_base * vp, int max_b_len, char * b) { const struct sg_pt_osf1_scsi * ptp = &vp->impl; if (0 == ptp->transport_err) { strncpy(b, "no transport error available", max_b_len); b[max_b_len - 1] = '\0'; return b; } strncpy(b, "no transport error available", max_b_len); b[max_b_len - 1] = '\0'; return b; } char * get_scsi_pt_os_err_str(const struct sg_pt_base * vp, int max_b_len, char * b) { const struct sg_pt_osf1_scsi * ptp = &vp->impl; const char * cp; cp = safe_strerror(ptp->os_err); strncpy(b, cp, max_b_len); if ((int)strlen(cp) >= max_b_len) b[max_b_len - 1] = '\0'; return b; } ddpt-0.92/CREDITS0000644000175000017500000000110111425121733012403 0ustar douggdouggThe author of ddpt would like to thank the following people who have made contributions: Mark Knibbs proposed write sparing and sparse writing. [20081212] proposed granularity control for sparing+sparse; oflag=resume; lazy seeks; trim and self-trim. [20100730] Peter Allworth original dd clone design used by sg3_utils's dd variants (e.g. sg_dd). The sg_dd linux utility has been generalized to become this utility (ddpt). [20081212] Doug Gilbert 30th July 2010 ddpt-0.92/aclocal.m40000644000175000017500000010766311526513027013252 0ustar douggdougg# generated automatically by aclocal 1.11.1 -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, # 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.67],, [m4_warning([this file was generated for autoconf 2.67. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically `autoreconf'.])]) # Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.11' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. m4_if([$1], [1.11.1], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) # _AM_AUTOCONF_VERSION(VERSION) # ----------------------------- # aclocal traces this macro to find the Autoconf version. # This is a private macro too. Using m4_define simplifies # the logic in aclocal, which can simply ignore this definition. m4_define([_AM_AUTOCONF_VERSION], []) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.11.1])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to # `$srcdir', `$srcdir/..', or `$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is `.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], [dnl Rely on autoconf to set up CDPATH properly. AC_PREREQ([2.50])dnl # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 9 # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ(2.52)dnl ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl _AM_SUBST_NOTMAKE([$1_FALSE])dnl m4_define([_AM_COND_VALUE_$1], [$2])dnl if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) # Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 10 # There are a few dirty hacks below to avoid letting `AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "GCJ", or "OBJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl ifelse([$1], CC, [depcc="$CC" am_compiler_list=], [$1], CXX, [depcc="$CXX" am_compiler_list=], [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], UPC, [depcc="$UPC" am_compiler_list=], [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi am__universal=false m4_case([$1], [CC], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac], [CXX], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac]) for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvisualcpp | msvcmsys) # This compiler won't grok `-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE(dependency-tracking, [ --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH])dnl _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. #serial 5 # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ # Autoconf 2.62 quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named `Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running `make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n 's/^U = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` AS_MKDIR_P([$dirpart/$fdir]) # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking # is enabled. FIXME. This creates each `.P' file that we will # need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) # Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 8 # AM_CONFIG_HEADER is obsolete. It has been replaced by AC_CONFIG_HEADERS. AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, # 2005, 2006, 2008, 2009 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 16 # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.62])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl # test to see if srcdir already configured if test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) AM_MISSING_PROG(AUTOCONF, autoconf) AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) AM_MISSING_PROG(AUTOHEADER, autoheader) AM_MISSING_PROG(MAKEINFO, makeinfo) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AM_PROG_MKDIR_P])dnl # We need awk for the "check" target. The system "awk" is bad on # some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES(CC)], [define([AC_PROG_CC], defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES(CXX)], [define([AC_PROG_CXX], defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES(OBJC)], [define([AC_PROG_OBJC], defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl ]) _AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl dnl The `parallel-tests' driver may need to know about EXEEXT, so add the dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl ]) dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_arg=$1 _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001, 2003, 2005, 2008 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl if test x"${install_sh}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi AC_SUBST(install_sh)]) # Copyright (C) 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 2 # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # Add --enable-maintainer-mode option to configure. -*- Autoconf -*- # From Jim Meyering # Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 5 # AM_MAINTAINER_MODE([DEFAULT-MODE]) # ---------------------------------- # Control maintainer-specific portions of Makefiles. # Default is to disable them, unless `enable' is passed literally. # For symmetry, `disable' may be passed as well. Anyway, the user # can override the default with the --enable/--disable switch. AC_DEFUN([AM_MAINTAINER_MODE], [m4_case(m4_default([$1], [disable]), [enable], [m4_define([am_maintainer_other], [disable])], [disable], [m4_define([am_maintainer_other], [enable])], [m4_define([am_maintainer_other], [enable]) m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])]) AC_MSG_CHECKING([whether to am_maintainer_other maintainer-specific portions of Makefiles]) dnl maintainer-mode's default is 'disable' unless 'enable' is passed AC_ARG_ENABLE([maintainer-mode], [ --][am_maintainer_other][-maintainer-mode am_maintainer_other make rules and dependencies not useful (and sometimes confusing) to the casual installer], [USE_MAINTAINER_MODE=$enableval], [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes])) AC_MSG_RESULT([$USE_MAINTAINER_MODE]) AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes]) MAINT=$MAINTAINER_MODE_TRUE AC_SUBST([MAINT])dnl ] ) AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE]) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 4 # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. AC_DEFUN([AM_MAKE_INCLUDE], [am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from `make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi AC_SUBST([am__include]) AC_SUBST([am__quote]) AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 6 # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it supports --run. # If it does, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= AC_MSG_WARN([`missing' script is too old or missing]) fi ]) # Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_MKDIR_P # --------------- # Check for `mkdir -p'. AC_DEFUN([AM_PROG_MKDIR_P], [AC_PREREQ([2.60])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, dnl while keeping a definition of mkdir_p for backward compatibility. dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of dnl Makefile.ins that do not define MKDIR_P, so we do our own dnl adjustment using top_builddir (which is defined more often than dnl MKDIR_P). AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl case $mkdir_p in [[\\/$]]* | ?:[[\\/]]*) ;; */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; esac ]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001, 2002, 2003, 2005, 2008 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 4 # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # ------------------------------ # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), 1)]) # _AM_SET_OPTIONS(OPTIONS) # ---------------------------------- # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 5 # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Just in case sleep 1 echo timestamp > conftest.file # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[[\\\"\#\$\&\'\`$am_lf]]*) AC_MSG_ERROR([unsafe absolute working directory name]);; esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);; esac # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi rm -f conftest.file if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT(yes)]) # Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_STRIP # --------------------- # One issue with vendor `install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in `make install-strip', and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using `strip' when the user # run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the `STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be `maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Copyright (C) 2006, 2008 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 2 # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. # This macro is traced by Automake. AC_DEFUN([_AM_SUBST_NOTMAKE]) # AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Public sister of _AM_SUBST_NOTMAKE. AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 2 # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. # FORMAT should be one of `v7', `ustar', or `pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory # $tardir. # tardir=directory && $(am__tar) > result.tar # # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. AM_MISSING_PROG([AMTAR], [tar]) m4_if([$1], [v7], [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], [m4_case([$1], [ustar],, [pax],, [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' _am_tools=${am_cv_prog_tar_$1-$_am_tools} # Do not fold the above two line into one, because Tru64 sh and # Solaris sh will not grok spaces in the rhs of `-'. for _am_tool in $_am_tools do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar /dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR ddpt-0.92/config.sub0000755000175000017500000010344511511200143013351 0ustar douggdougg#! /bin/sh # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 # Free Software Foundation, Inc. timestamp='2010-01-22' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software # can handle that machine. It does not imply ALL GNU software can. # # This file 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 of the License, 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., 51 Franklin Street - Fifth Floor, Boston, MA # 02110-1301, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Please send patches to . Submit a context # diff and a properly formatted GNU ChangeLog entry. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS $0 [OPTION] ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ kopensolaris*-gnu* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis | -knuth | -cray | -microblaze) os= basic_machine=$1 ;; -bluegene*) os=-cnk ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco6) os=-sco5v6 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5v6*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ | bfin \ | c4x | clipper \ | d10v | d30v | dlx | dsp16xx \ | fido | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | mcore | mep | metag \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64octeon | mips64octeonel \ | mips64orion | mips64orionel \ | mips64r5900 | mips64r5900el \ | mips64vr | mips64vrel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ | nios | nios2 \ | ns16k | ns32k \ | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ | pyramid \ | rx \ | score \ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ | spu | strongarm \ | tahoe | thumb | tic4x | tic80 | tron \ | ubicom32 \ | v850 | v850e \ | we32k \ | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown ;; m6811 | m68hc11 | m6812 | m68hc12 | picochip) # Motorola 68HC11/12. basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; ms1) basic_machine=mt-unknown ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64octeon-* | mips64octeonel-* \ | mips64orion-* | mips64orionel-* \ | mips64r5900-* | mips64r5900el-* \ | mips64vr-* | mips64vrel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nios-* | nios2-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ | pyramid-* \ | romp-* | rs6000-* | rx-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ | tahoe-* | thumb-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tile-* | tilegx-* \ | tron-* \ | ubicom32-* \ | v850-* | v850e-* | vax-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ | xstormy16-* | xtensa*-* \ | ymp-* \ | z8k-* | z80-*) ;; # Recognize the basic CPU types without company name, with glob match. xtensa*) basic_machine=$basic_machine-unknown ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aros) basic_machine=i386-pc os=-aros ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; blackfin) basic_machine=bfin-unknown os=-linux ;; blackfin-*) basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; bluegene*) basic_machine=powerpc-ibm os=-cnk ;; c90) basic_machine=c90-cray os=-unicos ;; cegcc) basic_machine=arm-unknown os=-cegcc ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; craynv) basic_machine=craynv-cray os=-unicosmp ;; cr16) basic_machine=cr16-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; crisv32 | crisv32-* | etraxfs*) basic_machine=crisv32-axis ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; dicos) basic_machine=i686-pc os=-dicos ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; # I'm not sure what "Sysv32" means. Should this be sysv3.2? i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; m68knommu) basic_machine=m68k-unknown os=-linux ;; m68knommu-*) basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; microblaze) basic_machine=microblaze-xilinx ;; mingw32) basic_machine=i386-pc os=-mingw32 ;; mingw32ce) basic_machine=arm-unknown os=-mingw32ce ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; msdos) basic_machine=i386-pc os=-msdos ;; ms1-*) basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; mvs) basic_machine=i370-ibm os=-mvs ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; openrisc | openrisc-*) basic_machine=or32-unknown ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; parisc) basic_machine=hppa-unknown os=-linux ;; parisc-*) basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pc98) basic_machine=i386-pc ;; pc98-*) basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc) basic_machine=powerpc-unknown ;; ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rdos) basic_machine=i386-pc os=-rdos ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sde) basic_machine=mipsisa32-sde os=-elf ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sh5el) basic_machine=sh5le-unknown ;; sh64) basic_machine=sh64-unknown ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tic54x | c54x*) basic_machine=tic54x-unknown os=-coff ;; tic55x | c55x*) basic_machine=tic55x-unknown os=-coff ;; tic6x | c6x*) basic_machine=tic6x-unknown os=-coff ;; # This must be matched before tile*. tilegx*) basic_machine=tilegx-unknown os=-linux-gnu ;; tile*) basic_machine=tile-unknown os=-linux-gnu ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; xbox) basic_machine=i686-pc os=-mingw32 ;; xps | xps100) basic_machine=xps100-honeywell ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; z80-*-coff) basic_machine=z80-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; mmix) basic_machine=mmix-knuth ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -auroraux) os=-auroraux ;; -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ | -sym* | -kopensolaris* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* | -aros* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ | -openbsd* | -solidbsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* | -cegcc* \ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -aros*) os=-aros ;; -kaos*) os=-kaos ;; -zvmoe) os=-zvmoe ;; -dicos*) os=-dicos ;; -nacl*) ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in score-*) os=-elf ;; spu-*) os=-elf ;; *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 # This also exists in the configure program, but was not the # default. # os=-sunos4 ;; m68*-cisco) os=-aout ;; mep-*) os=-elf ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-haiku) os=-haiku ;; *-ibm) os=-aix ;; *-knuth) os=-mmixware ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -cnk*|-aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: ddpt-0.92/configure0000755000175000017500000050576111526513027013322 0ustar douggdougg#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.67 for ddpt 0.92. # # Report bugs to . # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software # Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV export CONFIG_SHELL exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org and $0: dgilbert@interlog.com about your system, including any $0: error possibly output before this message. Then install $0: a modern shell, or manually run the script under such a $0: shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in #( -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='ddpt' PACKAGE_TARNAME='ddpt' PACKAGE_VERSION='0.92' PACKAGE_STRING='ddpt 0.92' PACKAGE_BUGREPORT='dgilbert@interlog.com' PACKAGE_URL='' ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBOBJS HAVE_SGUTILS_FALSE HAVE_SGUTILS_TRUE SGUTILS_LIBS os_libs os_deps host_os host_vendor host_cpu host build_os build_vendor build_cpu build rt_libs EGREP GREP CPP am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE am__quote am__include DEPDIR OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC MAINT MAINTAINER_MODE_FALSE MAINTAINER_MODE_TRUE am__untar am__tar AMTAR am__leading_dot SET_MAKE AWK mkdir_p MKDIR_P INSTALL_STRIP_PROGRAM STRIP install_sh MAKEINFO AUTOHEADER AUTOMAKE AUTOCONF ACLOCAL VERSION PACKAGE CYGPATH_W am__isrc INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_maintainer_mode enable_dependency_tracking enable_no_linux_bsg ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CPP' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used" >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures ddpt 0.92 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/ddpt] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of ddpt 0.92:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-maintainer-mode enable make rules and dependencies not useful (and sometimes confusing) to the casual installer --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors --enable-no-linux-bsg ignore linux bsg (sgv4) if present Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to . _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF ddpt configure 0.92 generated by GNU Autoconf 2.67 Copyright (C) 2010 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} } # ac_fn_c_check_header_compile # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} } # ac_fn_c_check_func cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by ddpt $as_me 0.92, which was generated by GNU Autoconf 2.67. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5 ; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu am__api_version='1.11' ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in #(( ./ | .// | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } # Just in case sleep 1 echo timestamp > conftest.file # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[\\\"\#\$\&\'\`$am_lf]*) as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5 ;; esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5 ;; esac # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi rm -f conftest.file if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". as_fn_error $? "ls -t appears to fail. Make sure there is not a broken alias in your environment" "$LINENO" 5 fi test "$2" = conftest.file ) then # Ok. : else as_fn_error $? "newly created file is older than distributed files! Check your system clock" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. # By default was `s,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5 $as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} fi if test x"${install_sh}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi # Installed binaries are usually stripped using `strip' when the user # run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the `STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_STRIP+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 $as_echo_n "checking for a thread-safe mkdir -p... " >&6; } if test -z "$MKDIR_P"; then if test "${ac_cv_path_mkdir+set}" = set; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir (GNU coreutils) '* | \ 'mkdir (coreutils) '* | \ 'mkdir (fileutils) '4.1*) ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext break 3;; esac done done done IFS=$as_save_IFS fi test -d ./--version && rmdir ./--version if test "${ac_cv_path_mkdir+set}" = set; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use the slow shell script. Don't cache a # value for MKDIR_P within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. MKDIR_P="$ac_install_sh -d" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } mkdir_p="$MKDIR_P" case $mkdir_p in [\\/$]* | ?:[\\/]*) ;; */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; esac for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_AWK+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\"" = set; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." am__isrc=' -I$(srcdir)' # test to see if srcdir already configured if test -f $srcdir/config.status; then as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE='ddpt' VERSION='0.92' cat >>confdefs.h <<_ACEOF #define PACKAGE "$PACKAGE" _ACEOF cat >>confdefs.h <<_ACEOF #define VERSION "$VERSION" _ACEOF # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # We need awk for the "check" target. The system "awk" is bad on # some platforms. # Always define AMTAR for backward compatibility. AMTAR=${AMTAR-"${am_missing_run}tar"} am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 $as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } # Check whether --enable-maintainer-mode was given. if test "${enable_maintainer_mode+set}" = set; then : enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval else USE_MAINTAINER_MODE=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5 $as_echo "$USE_MAINTAINER_MODE" >&6; } if test $USE_MAINTAINER_MODE = yes; then MAINTAINER_MODE_TRUE= MAINTAINER_MODE_FALSE='#' else MAINTAINER_MODE_TRUE='#' MAINTAINER_MODE_FALSE= fi MAINT=$MAINTAINER_MODE_TRUE ac_config_headers="$ac_config_headers config.h" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5 ; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5 ; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 $as_echo_n "checking for C compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5 ; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5 ; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if test "${ac_cv_objext+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5 ; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if test "${ac_cv_c_compiler_gnu+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if test "${ac_cv_prog_cc_g+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if test "${ac_cv_prog_cc_c89+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 $as_echo_n "checking for style of include used by $am_make... " >&6; } am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from `make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 $as_echo "$_am_result" >&6; } rm -f confinc confmf # Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then : enableval=$enable_dependency_tracking; fi if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvisualcpp | msvcmsys) # This compiler won't grok `-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi # AC_PROG_CXX # check for headers ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if test "${ac_cv_prog_CPP+set}" = set; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5 ; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if test "${ac_cv_path_GREP+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if test "${ac_cv_path_EGREP+set}" = set; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if test "${ac_cv_header_stdc+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi for ac_header in linux/types.h linux/bsg.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "#ifdef HAVE_LINUX_TYPES_H # include #endif " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in posix_fadvise do : ac_fn_c_check_func "$LINENO" "posix_fadvise" "ac_cv_func_posix_fadvise" if test "x$ac_cv_func_posix_fadvise" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_POSIX_FADVISE 1 _ACEOF fi done for ac_func in fsync do : ac_fn_c_check_func "$LINENO" "fsync" "ac_cv_func_fsync" if test "x$ac_cv_func_fsync" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_FSYNC 1 _ACEOF fi done for ac_func in fdatasync do : ac_fn_c_check_func "$LINENO" "fdatasync" "ac_cv_func_fdatasync" if test "x$ac_cv_func_fdatasync" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_FDATASYNC 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for clock_gettime in -lrt" >&5 $as_echo_n "checking for clock_gettime in -lrt... " >&6; } if test "${ac_cv_lib_rt_clock_gettime+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lrt $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char clock_gettime (); int main () { return clock_gettime (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_rt_clock_gettime=yes else ac_cv_lib_rt_clock_gettime=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_clock_gettime" >&5 $as_echo "$ac_cv_lib_rt_clock_gettime" >&6; } if test "x$ac_cv_lib_rt_clock_gettime" = x""yes; then : rt_libs='-lrt' else rt_libs='' fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for clock_gettime in -lrt" >&5 $as_echo_n "checking for clock_gettime in -lrt... " >&6; } if test "${ac_cv_lib_rt_clock_gettime+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lrt $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char clock_gettime (); int main () { return clock_gettime (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_rt_clock_gettime=yes else ac_cv_lib_rt_clock_gettime=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_clock_gettime" >&5 $as_echo "$ac_cv_lib_rt_clock_gettime" >&6; } if test "x$ac_cv_lib_rt_clock_gettime" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBRT 1 _ACEOF LIBS="-lrt $LIBS" fi for ac_func in clock_gettime do : ac_fn_c_check_func "$LINENO" "clock_gettime" "ac_cv_func_clock_gettime" if test "x$ac_cv_func_clock_gettime" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_CLOCK_GETTIME 1 _ACEOF fi done for ac_func in gettimeofday do : ac_fn_c_check_func "$LINENO" "gettimeofday" "ac_cv_func_gettimeofday" if test "x$ac_cv_func_gettimeofday" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_GETTIMEOFDAY 1 _ACEOF fi done # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } if test "${ac_cv_build+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` test "x$ac_build_alias" = x && as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5 ;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } if test "${ac_cv_host+set}" = set; then : $as_echo_n "(cached) " >&6 else if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5 ;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac cat >>confdefs.h <<_ACEOF #define SG_LIB_BUILD_HOST "${host}" _ACEOF case "${host}" in *-*-linux-gnu*) os_deps='sg_pt_linux.o' cat >>confdefs.h <<_ACEOF #define SG_LIB_LINUX 1 _ACEOF os_libs='' ;; *-*-linux*) os_deps='sg_pt_linux.o' cat >>confdefs.h <<_ACEOF #define SG_LIB_LINUX 1 _ACEOF os_libs='' ;; *-*-freebsd*|*-*-kfreebsd*-gnu*) os_deps='sg_pt_freebsd.o' cat >>confdefs.h <<_ACEOF #define SG_LIB_FREEBSD 1 _ACEOF os_libs='-lcam' ;; *-*-solaris*) os_deps='sg_pt_solaris.o' cat >>confdefs.h <<_ACEOF #define SG_LIB_SOLARIS 1 _ACEOF os_libs='' ;; *-*-cygwin*) os_deps='sg_pt_win32.o' cat >>confdefs.h <<_ACEOF #define SG_LIB_WIN32 1 _ACEOF cat >>confdefs.h <<_ACEOF #define WIN32_SPT_DIRECT 1 _ACEOF os_libs='' ;; *-*-mingw*) os_deps='sg_pt_win32.o' cat >>confdefs.h <<_ACEOF #define SG_LIB_WIN32 1 _ACEOF cat >>confdefs.h <<_ACEOF #define WIN32_SPT_DIRECT 1 _ACEOF cat >>confdefs.h <<_ACEOF #define SG_LIB_MINGW 1 _ACEOF os_libs='' ;; *) os_deps='sg_pt_linux.o' cat >>confdefs.h <<_ACEOF #define SG_LIB_LINUX 1 _ACEOF os_libs='' ;; esac # Check whether --enable-no-linux-bsg was given. if test "${enable_no_linux_bsg+set}" = set; then : enableval=$enable_no_linux_bsg; cat >>confdefs.h <<_ACEOF #define IGNORE_LINUX_BSG 1 _ACEOF fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sg_ll_inquiry in -lsgutils2" >&5 $as_echo_n "checking for sg_ll_inquiry in -lsgutils2... " >&6; } if test "${ac_cv_lib_sgutils2_sg_ll_inquiry+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsgutils2 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char sg_ll_inquiry (); int main () { return sg_ll_inquiry (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_sgutils2_sg_ll_inquiry=yes else ac_cv_lib_sgutils2_sg_ll_inquiry=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sgutils2_sg_ll_inquiry" >&5 $as_echo "$ac_cv_lib_sgutils2_sg_ll_inquiry" >&6; } if test "x$ac_cv_lib_sgutils2_sg_ll_inquiry" = x""yes; then : SGUTILS_LIBS="-lsgutils2"; have_sgutils=yes else have_sgutils=no fi if test x"$have_sgutils" = xyes; then HAVE_SGUTILS_TRUE= HAVE_SGUTILS_FALSE='#' else HAVE_SGUTILS_TRUE='#' HAVE_SGUTILS_FALSE= fi # AC_PROG_LIBTOOL ac_config_files="$ac_config_files Makefile src/Makefile doc/Makefile" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then test "x$cache_file" != "x/dev/null" && { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} cat confcache >$cache_file else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' else am__EXEEXT_TRUE='#' am__EXEEXT_FALSE= fi if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then as_fn_error $? "conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_SGUTILS_TRUE}" && test -z "${HAVE_SGUTILS_FALSE}"; then as_fn_error $? "conditional \"HAVE_SGUTILS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi : ${CONFIG_STATUS=./config.status} ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in #( -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by ddpt $as_me 0.92, which was generated by GNU Autoconf 2.67. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ ddpt config.status 0.92 configured by $0, generated by GNU Autoconf 2.67, with options \\"\$ac_cs_config\\" Copyright (C) 2010 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' MKDIR_P='$MKDIR_P' AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5 ;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= trap 'exit_status=$? { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_t=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_t"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5 ;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5 ;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac ac_MKDIR_P=$MKDIR_P case $MKDIR_P in [\\/$]* | ?:[\\/]* ) ;; */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$tmp/stdin" case $ac_file in -) cat "$tmp/out" && rm -f "$tmp/out";; *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" } >"$tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi # Compute "$ac_file"'s index in $config_headers. _am_arg="$ac_file" _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || $as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$_am_arg" : 'X\(//\)[^/]' \| \ X"$_am_arg" : 'X\(//\)$' \| \ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$_am_arg" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'`/stamp-h$_am_stamp_count ;; :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 $as_echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || { # Autoconf 2.62 quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named `Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`$as_dirname -- "$mf" || $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$mf" : 'X\(//\)[^/]' \| \ X"$mf" : 'X\(//\)$' \| \ X"$mf" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running `make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n 's/^U = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`$as_dirname -- "$file" || $as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$file" : 'X\(//\)[^/]' \| \ X"$file" : 'X\(//\)$' \| \ X"$file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir=$dirpart/$fdir; as_fn_mkdir_p # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi ddpt-0.92/src/0000755000175000017500000000000011527261465012173 5ustar douggdouggddpt-0.92/src/ddpt.h0000644000175000017500000001336111524675616013307 0ustar douggdougg#ifndef DDPT_H #define DDPT_H /* This is a C header file for the ddpt utility. See ddpt.c and ddpt.8 * for more information. */ #ifndef _XOPEN_SOURCE #define _XOPEN_SOURCE 600 #endif #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef SG_LIB_WIN32 #include #endif #ifdef SG_LIB_FREEBSD #ifndef SIGINFO /* hack to undo hiding by _XOPEN_SOURCE and _GNU_SOURCE */ #define SIGINFO 29 #endif #endif #ifdef SG_LIB_WIN32 #ifdef SG_LIB_MINGW #define SIGPIPE 13 #define SIGQUIT 3 #define SIGUSR1 25 #endif #endif #define STR_SZ 1024 #define INOUTF_SZ 512 #define EBUFF_SZ 512 #define DEF_BLOCK_SIZE 512 #define DEF_BPT_LT8 8192 /* BPT when IBS < 8 */ #define DEF_BPT_LT64 1024 /* BPT when IBS < 64 */ #define DEF_BPT_LT1024 128 /* BPT when IBS < 1024 */ #define DEF_BPT_LT8192 16 /* BPT when IBS < 8192 */ #define DEF_BPT_LT32768 4 /* BPT when IBS < 32768 */ #define DEF_BPT_GE32768 1 /* BPT when IBS >= 32768 */ #define DEF_SCSI_CDBSZ 10 #define MAX_SCSI_CDBSZ 16 #define SENSE_BUFF_LEN 32 /* Arbitrary, could be larger */ #define READ_CAP_REPLY_LEN 8 #define RCAP16_REPLY_LEN 32 #define DEF_TIMEOUT 60000 /* 60,000 millisecs == 60 seconds */ #define WRITE_SAME16_TIMEOUT 180000 /* 3 minutes */ #ifdef SG_LIB_LINUX #ifndef RAW_MAJOR #define RAW_MAJOR 255 /*unlikey value */ #endif #define DEV_NULL_MINOR_NUM 3 #endif #define SG_LIB_FLOCK_ERR 90 /* File type categorizations */ #define FT_OTHER 1 /* unknown (unable to identify) */ #define FT_PT 2 /* SCSI commands can be sent via a pass-through */ #define FT_REG 4 /* a normal (regular) file */ #define FT_DEV_NULL 8 /* either "/dev/null" or "." as filename */ #define FT_TAPE 16 /* tape style device */ #define FT_BLOCK 32 /* block device */ #define FT_FIFO 64 /* fifo (named or unnamed pipe (stdout)) */ #define FT_CHAR 128 /* char dev, doesn't fit another category */ #define FT_ERROR 256 /* couldn't "stat" file */ /* If O_DIRECT or O_SYNC not supported then define harmlessly */ #ifndef O_DIRECT #define O_DIRECT 0 #endif #ifndef O_SYNC #define O_SYNC 0 #endif #ifndef O_NONBLOCK #define O_NONBLOCK 0 #endif #define DDPT_ARG_IN 0 #define DDPT_ARG_OUT 1 #define DDPT_ARG_OUT2 2 #define MIN_RESERVED_SIZE 8192 #define MAX_UNIT_ATTENTIONS 10 #define MAX_ABORTED_CMDS 16 #define ERRBLK_SUPPORTED 1 /* One instance for arguments to iflag= , another instance for oflag= */ /* conv= arguments are mapped to flag arguments */ struct flags_t { int append; int cdbsz; int coe; int direct; int dpo; #ifdef ERRBLK_SUPPORTED int errblk; #endif int excl; int fdatasync; int flock; int force; int fsync; int fua; int fua_nv; int pdt; int nocache; int norcap; int nowrite; int pt; int resume; int retries; int self; int sparing; int sparse; int ssync; int strunc; int sync; int trunc; int wsame16; }; /* command line options */ /* The _given fields indicate whether option was given or is a default */ struct opts_t { int64_t skip; int64_t seek; int bs_given; /* 1 implies bs= option given on command line */ int ibs; int ibs_given; int obs; int obs_given; int bpt_i; /* blocks (of input) per transfer */ int bpt_given; int obpc; char inf[INOUTF_SZ]; int in_type; int infd; char outf[INOUTF_SZ]; int outf_given; int out_type; int outfd; char out2f[INOUTF_SZ]; int out2_type; int out2fd; int cdbsz_given; struct flags_t * iflagp; struct flags_t * oflagp; #ifdef SG_LIB_WIN32 HANDLE ib_fh; HANDLE ob_fh; #endif }; /* state of working variables within do_copy() */ /* permits do_copy() to be broken up into lots of helpers */ struct cp_state_t { int64_t if_filepos; int64_t of_filepos; int icbpt; int ocbpt; int bytes_read; int bytes_of; int bytes_of2; int leave_after_write; int leave_reason; /* ==0 for no error (e.g. EOF) */ int partial_write_bytes; }; struct signum_name_t { int num; char * name; }; #ifdef SG_LIB_WIN32 extern int dd_filetype(const char * fn); extern int get_blkdev_capacity(struct opts_t * optsp, int which_arg, int64_t * num_sect, int * sect_sz, int verbose); extern void win32_adjust_fns(struct opts_t * optsp); extern int win32_open_if(struct opts_t * optsp, int verbose); extern int win32_open_of(struct opts_t * optsp, int verbose); extern int win32_set_file_pos(struct opts_t * optsp, int if0_of1, int64_t pos, int verbose); extern int win32_block_read(struct opts_t * optsp, unsigned char * bp, int num_bytes, int verbose); extern int win32_block_read_from_of(struct opts_t * optsp, unsigned char * bp, int num_bytes, int verbose); extern int win32_block_write(struct opts_t * optsp, const unsigned char * bp, int num_bytes, int verbose); extern int win32_cp_read_block(struct opts_t * optsp, struct cp_state_t * csp, unsigned char * wrkPos, int * ifull_extrap, int verbose); extern int coe_process_eio(int64_t skip); extern void zero_coe_limit_count(void); extern int sg_do_wscan(char letter, int do_scan, int verb); #ifdef SG_LIB_MINGW /* Without this gives a warning about implicit declaration. * This stop the warning but if getpagesize() appears may need to * remove this declaration. */ extern int getpagesize(void); #endif #endif #endif ddpt-0.92/src/ddpt.c0000644000175000017500000042401511527261361013273 0ustar douggdougg/* * Copyright (c) 2008-2011 Douglas Gilbert. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */ /* ddpt is a utility program for copying files. It broadly follows the syntax * and semantics of the "dd" program found in Unix. ddpt is specialised for * "files" that represent storage devices, especially those that understand * the SCSI command set accessed via a pass-through. */ /* * The ddpt utility is a rewritten and extended version of the sg_dd utility * found in the sg3_utils package. sg_dd has a GPL (version 2) which has been * changed to a somewhat freer FreeBSD style license in ddpt. * Both licenses are considered "open source". * * Windows "block" devices, when _not_ accessed via the pass-through, don't * seem to work when POSIX/Unix like IO calls are used (e.g. write()). * So may need CreateFile, ReadFile, WriteFile, SetFilePointer and friends. */ static char * version_str = "0.92 20110217 [svn: r157]"; /* Was needed for posix_fadvise() */ /* #define _XOPEN_SOURCE 600 */ /* Need _GNU_SOURCE for O_DIRECT */ #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #include #include #include #include #include #include #include #include #include #include #include #define __STDC_FORMAT_MACROS 1 #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC) #include #elif defined(HAVE_GETTIMEOFDAY) #include #include #endif #include "ddpt.h" #ifdef SG_LIB_LINUX #include #include #include #include #include /* */ #endif #ifdef SG_LIB_FREEBSD #include #include #include #include #endif #ifdef SG_LIB_SOLARIS #include #include #endif #ifdef SG_LIB_WIN32 #ifndef SG_LIB_MINGW /* cygwin */ #include #endif #endif #include "sg_lib.h" #include "sg_cmds_basic.h" #include "sg_cmds_extra.h" #include "sg_pt.h" #ifndef EREMOTEIO #define EREMOTEIO EIO #endif static int64_t dd_count = -1; /* of input blocks */ static int64_t in_full = 0; static int in_partial = 0; /* unrecoverable reads considered partial */ static int64_t out_full = 0; static int out_partial = 0; static int out_sparse_active = 0; static int out_sparing_active = 0; static int out_trim_active = 0; static int64_t out_sparse = 0; /* used for sparse, sparing + trim */ static int out_sparse_partial = 0; static int recovered_errs = 0; /* on reads */ static int unrecovered_errs = 0; /* on reads */ static int wr_recovered_errs = 0; static int wr_unrecovered_errs = 0; static int trim_errs = 0; static int64_t lowest_unrecovered = 0; /* on reads */ static int64_t highest_unrecovered = -1; /* on reads */ static int num_retries = 0; static int sum_of_resids = 0; static int interrupted_retries = 0; static int err_to_report = 0; static int reading_fifo = 0; static struct sg_pt_base * if_ptvp = NULL; static struct sg_pt_base * of_ptvp = NULL; static int do_time = 1; /* default was 0 in sg_dd */ static int verbose = 0; static int quiet = 0; #if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC) static int start_tm_valid = 0; static struct timespec start_tm; #elif defined(HAVE_GETTIMEOFDAY) static int start_tm_valid = 0; static struct timeval start_tm; #endif static int read1_or_transfer = 0; /* 1 when of=/dev/null or similar */ static int ibs_hold = 0; static int out_type_hold = 0; static int max_uas = MAX_UNIT_ATTENTIONS; static int max_aborted = MAX_ABORTED_CMDS; static int coe_limit = 0; static int coe_count = 0; #ifdef SG_LIB_WIN32 static int wscan = 0; #endif static unsigned char * zeros_buff = NULL; #ifdef ERRBLK_SUPPORTED static const char * errblk_file = "errblk.txt"; static FILE * errblk_fp; #endif static struct signum_name_t signum_name_arr[] = { {SIGINT, "SIGINT"}, {SIGQUIT, "SIGQUIT"}, {SIGPIPE, "SIGPIPE"}, {SIGUSR1, "SIGUSR1"}, #ifdef SIGINFO {SIGINFO, "SIGINFO"}, #endif {0, NULL}, }; static void calc_duration_throughput(const char * leadin, int contin); static void usage() { fprintf(stderr, "Usage: " "ddpt [bpt=BPT[,OBPC]] [bs=BS] [cdbsz=6|10|12|16] [coe=0|1]\n" " [coe_limit=CL] [conv=CONVS] [count=COUNT] " "[ibs=IBS] if=IFILE\n" " [iflag=FLAGS] [obs=OBS] [of=OFILE] [of2=OFILE2] " "[oflag=FLAGS]\n" " [retries=RETR] [seek=SEEK] [skip=SKIP] " "[status=STAT]\n" #ifdef SG_LIB_WIN32 " [verbose=VERB] [--help] [--verbose] [--version] " "[--wscan]\n" #else " [verbose=VERB] [--help] [--verbose] [--version]\n" #endif " where:\n" " bpt input Blocks Per Transfer (BPT) (def: 128 when " "IBS is 512)\n" " Output Blocks Per Check (OBPC) (def: 0 implies " "BPT*IBS/OBS)\n" " bs block size for input and output (overrides " "ibs and obs)\n"); fprintf(stderr, " cdbsz size of SCSI READ or WRITE cdb (default is " "10)\n" " coe 0->exit on error (def), 1->continue on pt " "error (zero fill)\n" " coe_limit limit consecutive 'bad' blocks on reads to CL " "times\n" " when coe=1 (default: 0 which is no limit)\n" " conv conversions, comma separated list of CONVS " "(see below)\n" " count number of input blocks to copy (def: " "(remaining)\n" " device size)\n" " ibs input block size (default 512 bytes)\n" " if file or device to read from (for stdin use " "'-')\n" " iflag input flags, comma separated list from FLAGS " "(see below)\n" " obs output block size (def: 512), when IBS is " "not equal OBS\n" " [ (((IBS * BPT) %% OBS) == 0) is required\n" " of file or device to write to (def: /dev/null)\n"); fprintf(stderr, " of2 additional output file (def: /dev/null), " "OFILE2 should be\n" " normal file or pipe\n" " oflag output flags, comma separated list from FLAGS " "(see below)\n" " retries retry pass-through errors RETR times " "(def: 0)\n" " seek block position to start writing to OFILE\n" " skip block position to start reading from IFILE\n" " status value: 'noxfer' suppresses throughput " "calculation\n" " verbose 0->normal(def), 1->some noise, 2->more noise, " "etc\n" " -1->quiet (stderr->/dev/null)\n" " --help print out this usage message then exit\n" " --verbose equivalent to verbose=1\n" " --version print version information then exit\n" #ifdef SG_LIB_WIN32 " --wscan windows scan for device names and volumes\n" #endif "\nCopy all or part of IFILE to OFILE, IBS*BPT bytes at a time. " "Similar to\n" "dd command. Support for block devices, especially those " "accessed via\na SCSI pass-through.\n" "FLAGS: append(o),coe,direct,dpo,errblk(i),excl,fdatasync(o)," "flock,force\n" "fsync(o),fua,fua_nv,nocache,norcap,nowrite(o),null,pt," "resume(o),self\n" "sparing(o),sparse(o),ssync(o),strunc(o),sync,trim(o),trunc(o)," "unmap(o).\n" "CONVS: fdatasync,fsync,noerror,null,resume,sparing,sparse,sync," "trunc\n"); } static void print_stats(const char * str) { if ((0 != dd_count) && (! reading_fifo)) fprintf(stderr, " remaining block count=%"PRId64"\n", dd_count); fprintf(stderr, "%s%"PRId64"+%d records in\n", str, in_full, in_partial); fprintf(stderr, "%s%"PRId64"+%d records out\n", str, out_full, out_partial); if (out_sparse_active || out_sparing_active) { if (out_trim_active) { const char * cp; cp = trim_errs ? "attempted trim" : "trimmed"; if (out_sparse_partial > 0) fprintf(stderr, "%s%"PRId64"+%d %s records out\n", str, out_sparse, out_sparse_partial, cp); else fprintf(stderr, "%s%"PRId64" %s records out\n", str, out_sparse, cp); } else if (out_sparse_partial > 0) fprintf(stderr, "%s%"PRId64"+%d bypassed records out\n", str, out_sparse, out_sparse_partial); else fprintf(stderr, "%s%"PRId64" bypassed records out\n", str, out_sparse); } if (recovered_errs > 0) fprintf(stderr, "%s%d recovered read errors\n", str, recovered_errs); if (num_retries > 0) fprintf(stderr, "%s%d retries attempted\n", str, num_retries); if (unrecovered_errs > 0) fprintf(stderr, "%s%d unrecovered read error%s\n", str, unrecovered_errs, ((1 == unrecovered_errs) ? "" : "s")); if (unrecovered_errs && (highest_unrecovered >= 0)) fprintf(stderr, "lowest unrecovered read lba=%"PRId64", highest " "unrecovered lba=%"PRId64"\n", lowest_unrecovered, highest_unrecovered); if (wr_recovered_errs > 0) fprintf(stderr, "%s%d recovered write errors\n", str, wr_recovered_errs); if (wr_unrecovered_errs > 0) fprintf(stderr, "%s%d unrecovered write error%s\n", str, wr_unrecovered_errs, ((1 == wr_unrecovered_errs) ? "" : "s")); if (trim_errs) fprintf(stderr, "%s%d trim errors\n", str, trim_errs); if (interrupted_retries > 0) fprintf(stderr, "%s%d %s after interrupted system call(s)\n", str, interrupted_retries, ((1 == interrupted_retries) ? "retry" : "retries")); } /* Return signal name for signum if known, else return signum as a string. */ static const char * get_signal_name(int signum, char * b, int blen) { const struct signum_name_t * sp; for (sp = signum_name_arr; sp->num; ++sp) { if (signum == sp->num) break; } b[blen - 1] = '\0'; if (sp->num) strncpy(b, sp->name, blen - 1); else snprintf(b, blen - 1, "%d", signum); return b; } /* Register given sig_handler function to be associated with signal * sig_num. */ static void register_handler(int sig_num, void (*sig_handler) (int sig)) { #ifdef SG_LIB_MINGW if ((signal(sig_num, sig_handler) == SIG_ERR) && verbose) fprintf(stderr, "register_handler: failed in sig_num=%d\n", sig_num); #else struct sigaction sigact; sigaction(sig_num, NULL, &sigact); if (((SIGINT != sig_num) && (SIGQUIT != sig_num)) || (sigact.sa_handler != SIG_IGN)) { sigact.sa_handler = sig_handler; sigemptyset(&sigact.sa_mask); sigact.sa_flags = 0; // SA_RESTART (automatically after interrupt) sigaction(sig_num, &sigact, NULL); } #endif } /* Signal handler for signals that normally terminate a process. * Simpler implementation for MinGW that print stats then exits. * More complex implementation re-registers signal with its default * action then re-issues the same signal. */ static void interrupt_handler(int sig) { char b[32]; #ifdef SG_LIB_MINGW fprintf(stderr, "Interrupted by signal %s,", get_signal_name(sig, b, sizeof(b))); print_stats(""); if (do_time) calc_duration_throughput("", 0); /* kill(getpid(), sig); */ exit(127); #else struct sigaction sigact; sigact.sa_handler = SIG_DFL; sigemptyset(&sigact.sa_mask); sigact.sa_flags = 0; sigaction(sig, &sigact, NULL); fprintf(stderr, "Interrupted by signal %s,", get_signal_name(sig, b, sizeof(b))); print_stats(""); if (do_time) calc_duration_throughput("", 0); if (FT_REG & out_type_hold) fprintf(stderr, "To resume, invoke with same arguments plus " "oflag=resume\n"); kill(getpid(), sig); #endif } /* Signal handler for SIGUSR1 (Linux) or SIGINFO */ static void siginfo_handler(int sig) { sig = sig; /* dummy to stop -W warning messages */ fprintf(stderr, "Progress report:\n"); print_stats(" "); if (do_time) calc_duration_throughput(" ", 1); fprintf(stderr, " continuing ...\n"); } #ifdef ERRBLK_SUPPORTED /* Create errblk file (see iflag=errblk) and if we have gettimeofday * puts are start timestampl on the first line. */ static void open_errblk(void) { errblk_fp = fopen(errblk_file, "a"); /* append */ if (NULL == errblk_fp) fprintf(stderr, "unable to open or create %s\n", errblk_file); else { #ifdef HAVE_GETTIMEOFDAY { time_t t; char b[64]; t = time(NULL); strftime(b, sizeof(b), "# start: %Y-%m-%d %H:%M:%S\n", localtime(&t)); fputs(b, errblk_fp); } #else fputs("# start\n", errblk_fp); #endif } } static void put_errblk(uint64_t lba) { if (errblk_fp) fprintf(errblk_fp, "0x%"PRIx64"\n", lba); } static void put_range_errblk(uint64_t lba, int num) { if (errblk_fp) { if (1 == num) put_errblk(lba); else if (num > 1) fprintf(errblk_fp, "0x%"PRIx64"-0x%"PRIx64"\n", lba, lba + (num - 1)); } } static void close_errblk(void) { if (errblk_fp) { #ifdef HAVE_GETTIMEOFDAY { time_t t; char b[64]; t = time(NULL); strftime(b, sizeof(b), "# stop: %Y-%m-%d %H:%M:%S\n", localtime(&t)); fputs(b, errblk_fp); } #else fputs("# stop\n", errblk_fp); #endif fclose(errblk_fp); errblk_fp = NULL; } } #endif /* Process arguments given to 'conv=" option. Returns 0 on success, * 1 on error. */ static int process_conv(const char * arg, struct flags_t * ifp, struct flags_t * ofp) { char buff[256]; char * cp; char * np; strncpy(buff, arg, sizeof(buff)); buff[sizeof(buff) - 1] = '\0'; if ('\0' == buff[0]) { fprintf(stderr, "no conversions found\n"); return 1; } cp = buff; do { np = strchr(cp, ','); if (np) *np++ = '\0'; if (0 == strcmp(cp, "fdatasync")) ++ofp->fdatasync; else if (0 == strcmp(cp, "fsync")) ++ofp->fsync; else if (0 == strcmp(cp, "noerror")) ++ifp->coe; /* will still fail on write error */ else if (0 == strcmp(cp, "null")) ; else if (0 == strcmp(cp, "resume")) ++ofp->resume; else if (0 == strcmp(cp, "sparing")) ++ofp->sparing; else if (0 == strcmp(cp, "sparse")) ++ofp->sparse; else if (0 == strcmp(cp, "sync")) ; /* dd(susv4): pad errored block(s) with zeros but ddpt does * that by default. Typical dd use: 'conv=noerror,sync' */ else if (0 == strcmp(cp, "trunc")) ++ofp->trunc; else { fprintf(stderr, "unrecognised flag: %s\n", cp); return 1; } cp = np; } while (cp); return 0; } /* Process arguments given to 'iflag=" and 'oflag=" options. Returns 0 * on success, 1 on error. */ static int process_flags(const char * arg, struct flags_t * fp) { char buff[256]; char * cp; char * np; strncpy(buff, arg, sizeof(buff)); buff[sizeof(buff) - 1] = '\0'; if ('\0' == buff[0]) { fprintf(stderr, "no flag found\n"); return 1; } cp = buff; do { np = strchr(cp, ','); if (np) *np++ = '\0'; if (0 == strcmp(cp, "append")) ++fp->append; else if (0 == strcmp(cp, "coe")) ++fp->coe; else if (0 == strcmp(cp, "direct")) ++fp->direct; else if (0 == strcmp(cp, "dpo")) ++fp->dpo; #ifdef ERRBLK_SUPPORTED else if (0 == strcmp(cp, "errblk")) ++fp->errblk; #endif else if (0 == strcmp(cp, "excl")) ++fp->excl; else if (0 == strcmp(cp, "fdatasync")) ++fp->fdatasync; else if (0 == strcmp(cp, "flock")) ++fp->flock; else if (0 == strcmp(cp, "force")) ++fp->force; else if (0 == strcmp(cp, "fsync")) ++fp->fsync; else if (0 == strcmp(cp, "fua_nv")) /* check fua_nv before fua */ ++fp->fua_nv; else if (0 == strcmp(cp, "fua")) ++fp->fua; else if (0 == strcmp(cp, "nocache")) ++fp->nocache; else if (0 == strcmp(cp, "norcap")) ++fp->norcap; else if (0 == strcmp(cp, "nowrite")) ++fp->nowrite; else if (0 == strcmp(cp, "null")) ; else if (0 == strcmp(cp, "pt")) ++fp->pt; else if (0 == strcmp(cp, "resume")) ++fp->resume; else if (0 == strcmp(cp, "self")) ++fp->self; else if (0 == strcmp(cp, "sparing")) ++fp->sparing; else if (0 == strcmp(cp, "sparse")) ++fp->sparse; else if (0 == strcmp(cp, "ssync")) ++fp->ssync; else if (0 == strcmp(cp, "strunc")) ++fp->strunc; else if (0 == strcmp(cp, "sync")) ++fp->sync; else if ((0 == strcmp(cp, "trim")) || (0 == strcmp(cp, "unmap"))) { /* treat trim (ATA term) and unmap (SCSI term) as synonyms */ ++fp->wsame16; } else if (0 == strcmp(cp, "trunc")) ++fp->trunc; else { fprintf(stderr, "unrecognised flag: %s\n", cp); return 1; } cp = np; } while (cp); return 0; } /* Command line processing helper, checks sanity and applies some * defaults. Returns 0 on success, > 0 for error. */ static int cl_sanity_defaults(struct opts_t * optsp) { if ((0 == optsp->ibs) && (0 == optsp->obs)) { optsp->ibs = DEF_BLOCK_SIZE; optsp->obs = DEF_BLOCK_SIZE; if (optsp->inf[0]) fprintf(stderr, "Assume block size of %d bytes for both " "input and output\n", DEF_BLOCK_SIZE); } else if (0 == optsp->obs) { optsp->obs = DEF_BLOCK_SIZE; if ((optsp->ibs != DEF_BLOCK_SIZE) && optsp->outf[0]) fprintf(stderr, "Neither obs nor bs given so set obs=%d " "(default block size)\n", optsp->obs); } else if (0 == optsp->ibs) { optsp->ibs = DEF_BLOCK_SIZE; if (optsp->obs != DEF_BLOCK_SIZE) fprintf(stderr, "Neither ibs nor bs given so set ibs=%d " "(default block size)\n", optsp->ibs); } ibs_hold = optsp->ibs; /* defaulting transfer (copy buffer) size depending on IBS. 128*2048 for CD/DVDs is too large for the block layer in lk 2.6 and results in an EIO on the SG_IO ioctl. So reduce it in that case. */ if (0 == optsp->bpt_given) { if (optsp->ibs < 8) optsp->bpt_i = DEF_BPT_LT8; else if (optsp->ibs < 64) optsp->bpt_i = DEF_BPT_LT64; else if (optsp->ibs < 1024) optsp->bpt_i = DEF_BPT_LT1024; else if (optsp->ibs < 8192) optsp->bpt_i = DEF_BPT_LT8192; else if (optsp->ibs < 31768) optsp->bpt_i = DEF_BPT_LT32768; else optsp->bpt_i = DEF_BPT_GE32768; } if ((optsp->ibs != optsp->obs) && (0 != ((optsp->ibs * optsp->bpt_i) % optsp->obs))) { fprintf(stderr, "when 'ibs' and 'obs' differ, ((ibs*bpt)/obs) " "must have no remainder (bpt=%d)\n", optsp->bpt_i); return SG_LIB_SYNTAX_ERROR; } if ((optsp->skip < 0) || (optsp->seek < 0)) { fprintf(stderr, "neither skip nor seek can be negative\n"); return SG_LIB_SYNTAX_ERROR; } if ((optsp->oflagp->append > 0) && (optsp->seek > 0)) { fprintf(stderr, "Can't use both append and seek switches\n"); return SG_LIB_SYNTAX_ERROR; } if (optsp->bpt_i < 1) { fprintf(stderr, "bpt must be greater than 0\n"); return SG_LIB_SYNTAX_ERROR; } if (optsp->iflagp->append) fprintf(stderr, "append flag ignored on input\n"); if (optsp->iflagp->sparing) fprintf(stderr, "sparing flag ignored on input\n"); if (optsp->iflagp->ssync) fprintf(stderr, "ssync flag ignored on input\n"); if (optsp->oflagp->trunc) { if (optsp->oflagp->resume) { optsp->oflagp->trunc = 0; if (verbose) fprintf(stderr, "trunc ignored due to resume flag, " "otherwise open_of() truncates too early\n"); } else if (optsp->oflagp->append) { optsp->oflagp->trunc = 0; fprintf(stderr, "trunc ignored due to append flag\n"); } else if (optsp->oflagp->sparing) { fprintf(stderr, "trunc flag conflicts with sparing\n"); return SG_LIB_SYNTAX_ERROR; } } if (optsp->iflagp->self || optsp->oflagp->self) { if (! optsp->oflagp->self) ++optsp->oflagp->self; if (optsp->iflagp->wsame16 || optsp->oflagp->wsame16) { if (! optsp->oflagp->wsame16) ++optsp->oflagp->wsame16; if (! optsp->oflagp->nowrite) ++optsp->oflagp->nowrite; } if ('\0' == optsp->outf[0]) strcpy(optsp->outf, optsp->inf); if ((0 == optsp->seek) && (optsp->skip > 0)) { if (optsp->ibs == optsp->obs) optsp->seek = optsp->skip; else if (optsp->obs > 0) { int64_t l; l = optsp->skip * optsp->ibs; optsp->seek = l / optsp->obs; if ((optsp->seek * optsp->obs) != l) { fprintf(stderr, "self cannot translate skip to seek " "properly, try different skip value\n"); return SG_LIB_SYNTAX_ERROR; } } if (verbose) fprintf(stderr, "self: set seek=%"PRId64"\n", optsp->seek); } } if (optsp->oflagp->wsame16) optsp->oflagp->sparse += 2; if (optsp->oflagp->strunc && (0 == optsp->oflagp->sparse)) ++optsp->oflagp->sparse; if (verbose) { /* report flags used but not supported */ #ifndef SG_LIB_LINUX if (optsp->iflagp->flock || optsp->oflagp->flock) fprintf(stderr, "warning: 'flock' flag not supported on this " "platform\n"); #endif #ifndef HAVE_POSIX_FADVISE if (optsp->iflagp->nocache || optsp->oflagp->nocache) fprintf(stderr, "warning: 'nocache' flag not supported on this " "platform\n"); #endif #if O_SYNC == 0 if (optsp->iflagp->sync || optsp->oflagp->sync) fprintf(stderr, "warning: 'sync' flag (O_SYNC) not supported on " "this platform\n"); #endif #if O_DIRECT == 0 if (optsp->iflagp->direct || optsp->oflagp->direct) fprintf(stderr, "warning: 'direct' flag (O_DIRECT) not supported " "on this platform\n"); #endif } return 0; } /* Process options on the command line. Returns 0 if successful, > 0 for * (syntax) error and -1 for early exit (e.g. after '--help') */ static int process_cl(struct opts_t * optsp, int argc, char * argv[]) { char str[STR_SZ]; char * key; char * buf; char * cp; int k, n; for (k = 1; k < argc; ++k) { if (argv[k]) { strncpy(str, argv[k], STR_SZ); str[STR_SZ - 1] = '\0'; } else continue; // replace '=' with null and set buf pointer to following char for (key = str, buf = key; *buf && *buf != '=';) ++buf; if (*buf) *buf++ = '\0'; // check for option names, in alphabetical order if (0 == strcmp(key, "bpt")) { cp = strchr(buf, ','); if (cp) *cp = '\0'; if ((n = sg_get_num(buf)) < 0) { fprintf(stderr, "bad BPT argument to 'bpt='\n"); return SG_LIB_SYNTAX_ERROR; } if (n > 0) { optsp->bpt_i = n; optsp->bpt_given = 1; } if (cp) { n = sg_get_num(cp + 1); if (n < 0) { fprintf(stderr, "bad OBPC argument to 'bpt='\n"); return SG_LIB_SYNTAX_ERROR; } optsp->obpc = n; } } else if (0 == strcmp(key, "bs")) { n = sg_get_num(buf); if (n < 0) { fprintf(stderr, "bad argument to 'bs='\n"); return SG_LIB_SYNTAX_ERROR; } if (optsp->bs_given) { fprintf(stderr, "second 'bs=' option given, dangerous\n"); return SG_LIB_SYNTAX_ERROR; } else optsp->bs_given = 1; if ((optsp->ibs_given) || (optsp->obs_given)) { fprintf(stderr, "'bs=' option cannot be combined with " "'ibs=' or 'obs='\n"); return SG_LIB_SYNTAX_ERROR; } optsp->ibs = n; optsp->obs = n; } else if (0 == strcmp(key, "cbs")) fprintf(stderr, "the cbs= option is ignored\n"); else if (0 == strcmp(key, "cdbsz")) { optsp->iflagp->cdbsz = sg_get_num(buf); optsp->oflagp->cdbsz = optsp->iflagp->cdbsz; optsp->cdbsz_given = 1; } else if (0 == strcmp(key, "coe")) { optsp->iflagp->coe = sg_get_num(buf); optsp->oflagp->coe = optsp->iflagp->coe; } else if (0 == strcmp(key, "coe_limit")) { coe_limit = sg_get_num(buf); if (-1 == coe_limit) { fprintf(stderr, "bad argument to 'coe_limit='\n"); return SG_LIB_SYNTAX_ERROR; } } else if (0 == strcmp(key, "conv")) { if (process_conv(buf, optsp->iflagp, optsp->oflagp)) { fprintf(stderr, "bad argument to 'conv='\n"); return SG_LIB_SYNTAX_ERROR; } } else if (0 == strcmp(key, "count")) { if (0 != strcmp("-1", buf)) { dd_count = sg_get_llnum(buf); if (-1LL == dd_count) { fprintf(stderr, "bad argument to 'count='\n"); return SG_LIB_SYNTAX_ERROR; } } /* 'count=-1' is accepted, means calculate count */ } else if (0 == strcmp(key, "ibs")) { n = sg_get_num(buf); if (n < 0) { fprintf(stderr, "bad argument to 'ibs='\n"); return SG_LIB_SYNTAX_ERROR; } if (optsp->bs_given) { fprintf(stderr, "'ibs=' option cannot be combined with " "'bs='; try 'obs=' instead\n"); return SG_LIB_SYNTAX_ERROR; } ++optsp->ibs_given; optsp->ibs = n; } else if (strcmp(key, "if") == 0) { if ('\0' != optsp->inf[0]) { fprintf(stderr, "Second IFILE argument??\n"); return SG_LIB_SYNTAX_ERROR; } else strncpy(optsp->inf, buf, INOUTF_SZ); } else if (0 == strcmp(key, "iflag")) { if (process_flags(buf, optsp->iflagp)) { fprintf(stderr, "bad argument to 'iflag='\n"); return SG_LIB_SYNTAX_ERROR; } } else if (0 == strcmp(key, "obs")) { n = sg_get_num(buf); if (n < 0) { fprintf(stderr, "bad argument to 'obs='\n"); return SG_LIB_SYNTAX_ERROR; } if (optsp->bs_given) { fprintf(stderr, "'obs=' option cannot be combined with " "'bs='; try 'ibs=' instead\n"); return SG_LIB_SYNTAX_ERROR; } ++optsp->obs_given; optsp->obs = n; } else if (strcmp(key, "of") == 0) { if ('\0' != optsp->outf[0]) { fprintf(stderr, "Second OFILE argument??\n"); return SG_LIB_SYNTAX_ERROR; } strncpy(optsp->outf, buf, INOUTF_SZ); ++optsp->outf_given; } else if (strcmp(key, "of2") == 0) { if ('\0' != optsp->out2f[0]) { fprintf(stderr, "Second OFILE2 argument??\n"); return SG_LIB_SYNTAX_ERROR; } else strncpy(optsp->out2f, buf, INOUTF_SZ); } else if (0 == strcmp(key, "oflag")) { if (process_flags(buf, optsp->oflagp)) { fprintf(stderr, "bad argument to 'oflag='\n"); return SG_LIB_SYNTAX_ERROR; } } else if (0 == strcmp(key, "retries")) { optsp->iflagp->retries = sg_get_num(buf); optsp->oflagp->retries = optsp->iflagp->retries; if (-1 == optsp->iflagp->retries) { fprintf(stderr, "bad argument to 'retries='\n"); return SG_LIB_SYNTAX_ERROR; } } else if (0 == strcmp(key, "seek")) { optsp->seek = sg_get_llnum(buf); if (-1LL == optsp->seek) { fprintf(stderr, "bad argument to 'seek='\n"); return SG_LIB_SYNTAX_ERROR; } } else if (0 == strcmp(key, "skip")) { optsp->skip = sg_get_llnum(buf); if (-1LL == optsp->skip) { fprintf(stderr, "bad argument to 'skip='\n"); return SG_LIB_SYNTAX_ERROR; } } else if (0 == strcmp(key, "status")) { if (0 == strncmp(buf, "null", 4)) ; else if (0 == strncmp(buf, "noxfer", 6)) do_time = 0; else { fprintf(stderr, "'status=' expects 'noxfer' or 'null'\n"); return SG_LIB_SYNTAX_ERROR; } } else if (0 == strncmp(key, "verb", 4)) { verbose = sg_get_num(buf); if ((-1 == verbose) && ('-' != buf[0])) { fprintf(stderr, "bad argument to 'verbose='\n"); return SG_LIB_SYNTAX_ERROR; } if (verbose < 0) { ++quiet; verbose = 0; } } else if (0 == strncmp(key, "--verb", 6)) ++verbose; else if (0 == strncmp(key, "-vvvv", 5)) verbose += 4; else if (0 == strncmp(key, "-vvv", 4)) verbose += 3; else if (0 == strncmp(key, "-vv", 3)) verbose += 2; else if (0 == strncmp(key, "-v", 2)) ++verbose; else if ((0 == strncmp(key, "--help", 7)) || (0 == strncmp(key, "-h", 2)) || (0 == strcmp(key, "-?"))) { usage(); return -1; } else if ((0 == strncmp(key, "--vers", 6)) || (0 == strncmp(key, "-V", 2))) { fprintf(stderr, "%s\n", version_str); return -1; } #ifdef SG_LIB_WIN32 else if (0 == strncmp(key, "--wscan", 7)) ++wscan; else if (0 == strncmp(key, "-wwww", 5)) wscan += 4; else if (0 == strncmp(key, "-www", 4)) wscan += 3; else if (0 == strncmp(key, "-ww", 3)) wscan += 2; else if (0 == strncmp(key, "-w", 2)) ++wscan; #endif else { fprintf(stderr, "Unrecognized option '%s'\n", key); fprintf(stderr, "For more information use '--help'\n"); return SG_LIB_SYNTAX_ERROR; } } return cl_sanity_defaults(optsp); } /* Attempt to categorize the file type from the given filename. * Separate version for Windows and Unix. Windows version does some * file name processing. */ #ifndef SG_LIB_WIN32 #ifdef SG_LIB_LINUX static int bsg_major_checked = 0; static int bsg_major = 0; /* In Linux search /proc/devices for bsg character driver in order to * find its major device number since it is allocated dynamically. */ static void find_bsg_major(void) { const char * proc_devices = "/proc/devices"; FILE *fp; char a[128]; char b[128]; char * cp; int n; if (NULL == (fp = fopen(proc_devices, "r"))) { if (verbose) fprintf(stderr, "fopen %s failed: %s\n", proc_devices, strerror(errno)); return; } while ((cp = fgets(b, sizeof(b), fp))) { if ((1 == sscanf(b, "%s", a)) && (0 == memcmp(a, "Character", 9))) break; } while (cp && (cp = fgets(b, sizeof(b), fp))) { if (2 == sscanf(b, "%d %s", &n, a)) { if (0 == strcmp("bsg", a)) { bsg_major = n; break; } } else break; } if (verbose > 5) { if (cp) fprintf(stderr, "found bsg_major=%d\n", bsg_major); else fprintf(stderr, "found no bsg char device in %s\n", proc_devices); } fclose(fp); } #endif /* Categorize file by using the stat() system call on its filename. * If not found FT_ERROR returned. The FT_* constants are a bit mask * and later logic can combine them (e.g. FT_BLOCK | FT_PT). */ static int dd_filetype(const char * filename) { struct stat st; size_t len = strlen(filename); if ((1 == len) && ('.' == filename[0])) return FT_DEV_NULL; if (stat(filename, &st) < 0) return FT_ERROR; if (S_ISREG(st.st_mode)) { // fprintf(stderr, "dd_filetype: regular file, st_size=%"PRId64"\n", // st.st_size); return FT_REG; } else if (S_ISCHR(st.st_mode)) { #ifdef SG_LIB_LINUX /* major() and minor() defined in sys/sysmacros.h */ if ((MEM_MAJOR == major(st.st_rdev)) && (DEV_NULL_MINOR_NUM == minor(st.st_rdev))) return FT_DEV_NULL; if (SCSI_GENERIC_MAJOR == major(st.st_rdev)) return FT_PT; if (SCSI_TAPE_MAJOR == major(st.st_rdev)) return FT_TAPE; if (! bsg_major_checked) { bsg_major_checked = 1; find_bsg_major(); } if (bsg_major == (int)major(st.st_rdev)) return FT_PT; return FT_CHAR; /* assume something like /dev/zero */ #elif SG_LIB_FREEBSD { /* int d_flags; for FIOFTYPE ioctl see sys/filio.h */ char s[STR_SZ]; char * bname; strcpy(s, filename); bname = basename(s); if (0 == strcmp("null", bname)) return FT_DEV_NULL; else if (0 == memcmp("pass", bname, 4)) return FT_PT; else return FT_BLOCK; /* freebsd doesn't have block devices! */ } #elif SG_LIB_SOLARIS /* might be /dev/rdsk or /dev/scsi , require pt override */ return FT_BLOCK; #else return FT_PT; #endif } else if (S_ISBLK(st.st_mode)) return FT_BLOCK; else if (S_ISFIFO(st.st_mode)) return FT_FIFO; return FT_OTHER; } #endif static char * dd_filetype_str(int ft, char * buff, int max_bufflen, const char * fname) { int off = 0; if (FT_DEV_NULL & ft) off += snprintf(buff + off, max_bufflen - off, "null device "); if (FT_PT & ft) off += snprintf(buff + off, max_bufflen - off, "pass-through [pt] device "); if (FT_BLOCK & ft) off += snprintf(buff + off, max_bufflen - off, "block device "); if (FT_FIFO & ft) off += snprintf(buff + off, max_bufflen - off, "fifo [stdin, stdout, named pipe] "); if (FT_TAPE & ft) off += snprintf(buff + off, max_bufflen - off, "SCSI tape device "); if (FT_REG & ft) off += snprintf(buff + off, max_bufflen - off, "regular file "); if (FT_CHAR & ft) off += snprintf(buff + off, max_bufflen - off, "char device "); if (FT_OTHER & ft) off += snprintf(buff + off, max_bufflen - off, "other file type "); if (FT_ERROR & ft) { if (fname) off += snprintf(buff + off, max_bufflen - off, "unable to 'stat' %s ", fname); else off += snprintf(buff + off, max_bufflen - off, "unable to 'stat' file "); } return buff; } /* Fetch number of blocks and block size of a pt device. * Return of 0 -> success, see sg_ll_read_capacity*() otherwise. */ static int scsi_read_capacity(int sg_fd, int64_t * num_sect, int * sect_sz) { int k, res; unsigned int ui; unsigned char rcBuff[RCAP16_REPLY_LEN]; int verb; verb = (verbose ? verbose - 1: 0); res = sg_ll_readcap_10(sg_fd, 0, 0, rcBuff, READ_CAP_REPLY_LEN, 0, verb); if (0 != res) return res; if ((0xff == rcBuff[0]) && (0xff == rcBuff[1]) && (0xff == rcBuff[2]) && (0xff == rcBuff[3])) { int64_t ls; if (verb) fprintf(stderr, " READ CAPACITY (10) response cannot " "represent this capacity\n"); res = sg_ll_readcap_16(sg_fd, 0, 0, rcBuff, RCAP16_REPLY_LEN, 0, verb); if (0 != res) return res; for (k = 0, ls = 0; k < 8; ++k) { ls <<= 8; ls |= rcBuff[k]; } *num_sect = ls + 1; *sect_sz = (rcBuff[8] << 24) | (rcBuff[9] << 16) | (rcBuff[10] << 8) | rcBuff[11]; } else { ui = ((rcBuff[0] << 24) | (rcBuff[1] << 16) | (rcBuff[2] << 8) | rcBuff[3]); /* take care not to sign extend values > 0x7fffffff */ *num_sect = (int64_t)ui + 1; *sect_sz = (rcBuff[4] << 24) | (rcBuff[5] << 16) | (rcBuff[6] << 8) | rcBuff[7]; } return 0; } /* get_blkdev_capacity() returns 0 -> success or -1 -> failure. * which_arg should either be DDPT_ARG_IN, DDPT_ARG_OUT or DDPT_ARG_OUT2. * If successful writes back sector size (logical block * size) using the sect_sz * pointer. Also writes back the number of * sectors (logical blocks) on the block device using num_sect pointer. */ #ifdef SG_LIB_LINUX static int get_blkdev_capacity(struct opts_t * optsp, int which_arg, int64_t * num_sect, int * sect_sz, int verb) { int blk_fd; const char * fname; blk_fd = (DDPT_ARG_IN == which_arg) ? optsp->infd : optsp->outfd; fname = (DDPT_ARG_IN == which_arg) ? optsp->inf : optsp->outf; if (verb > 2) fprintf(stderr, "get_blkdev_capacity: for %s\n", fname); /* BLKGETSIZE64, BLKGETSIZE and BLKSSZGET macros problematic (from * or ). */ #ifdef BLKSSZGET if ((ioctl(blk_fd, BLKSSZGET, sect_sz) < 0) && (*sect_sz > 0)) { perror("BLKSSZGET ioctl error"); return -1; } else { #ifdef BLKGETSIZE64 uint64_t ull; if (ioctl(blk_fd, BLKGETSIZE64, &ull) < 0) { perror("BLKGETSIZE64 ioctl error"); return -1; } *num_sect = ((int64_t)ull / (int64_t)*sect_sz); if (verb > 5) fprintf(stderr, "Used Linux BLKGETSIZE64 ioctl\n"); #else unsigned long ul; if (ioctl(blk_fd, BLKGETSIZE, &ul) < 0) { perror("BLKGETSIZE ioctl error"); return -1; } *num_sect = (int64_t)ul; if (verb > 5) fprintf(stderr, "Used Linux BLKGETSIZE ioctl\n"); #endif } return 0; #else blk_fd = blk_fd; if (verb) fprintf(stderr, " BLKSSZGET+BLKGETSIZE ioctl not available\n"); *num_sect = 0; *sect_sz = 0; return -1; #endif } #endif #ifdef SG_LIB_FREEBSD static int get_blkdev_capacity(struct opts_t * optsp, int which_arg, int64_t * num_sect, int * sect_sz, int verb) { // Why do kernels invent their own typedefs and not use C standards? #define u_int unsigned int off_t mediasize; unsigned int sectorsize; int blk_fd; const char * fname; blk_fd = (DDPT_ARG_IN == which_arg) ? optsp->infd : optsp->outfd; fname = (DDPT_ARG_IN == which_arg) ? optsp->inf : optsp->outf; if (verb > 2) fprintf(stderr, "get_blkdev_capacity: for %s\n", fname); /* For FreeBSD post suggests that /usr/sbin/diskinfo uses * ioctl(fd, DIOCGMEDIASIZE, &mediasize), where mediasize is an off_t. * also: ioctl(fd, DIOCGSECTORSIZE, §orsize) */ if (ioctl(blk_fd, DIOCGSECTORSIZE, §orsize) < 0) { perror("DIOCGSECTORSIZE ioctl error"); return -1; } *sect_sz = sectorsize; if (ioctl(blk_fd, DIOCGMEDIASIZE, &mediasize) < 0) { perror("DIOCGMEDIASIZE ioctl error"); return -1; } if (sectorsize) *num_sect = mediasize / sectorsize; else *num_sect = 0; return 0; } #endif #ifdef SG_LIB_SOLARIS static int get_blkdev_capacity(struct opts_t * optsp, int which_arg, int64_t * num_sect, int * sect_sz, int verb) { struct dk_minfo info; int blk_fd; const char * fname; blk_fd = (DDPT_ARG_IN == which_arg) ? optsp->infd : optsp->outfd; fname = (DDPT_ARG_IN == which_arg) ? optsp->inf : optsp->outf; if (verb > 2) fprintf(stderr, "get_blkdev_capacity: for %s\n", fname); /* this works on "char" block devs (e.g. in /dev/rdsk) but not /dev/dsk */ if (ioctl(blk_fd, DKIOCGMEDIAINFO , &info) < 0) { perror("DKIOCGMEDIAINFO ioctl error"); *num_sect = 0; *sect_sz = 0; return -1; } *num_sect = info.dki_capacity; *sect_sz = info.dki_lbsize; return 0; } #endif /* Build a SCSI READ or WRITE CDB. */ static int pt_build_scsi_cdb(unsigned char * cdbp, int cdb_sz, unsigned int blocks, int64_t start_block, int write_true, int fua, int fua_nv, int dpo) { int rd_opcode[] = {0x8, 0x28, 0xa8, 0x88}; int wr_opcode[] = {0xa, 0x2a, 0xaa, 0x8a}; int sz_ind; memset(cdbp, 0, cdb_sz); if (dpo) cdbp[1] |= 0x10; if (fua) cdbp[1] |= 0x8; if (fua_nv) cdbp[1] |= 0x2; switch (cdb_sz) { case 6: sz_ind = 0; cdbp[0] = (unsigned char)(write_true ? wr_opcode[sz_ind] : rd_opcode[sz_ind]); /* Overwrite fua, fua_nv and dpo settings, n/a for 6 byte variants */ cdbp[1] = (unsigned char)((start_block >> 16) & 0x1f); cdbp[2] = (unsigned char)((start_block >> 8) & 0xff); cdbp[3] = (unsigned char)(start_block & 0xff); cdbp[4] = (256 == blocks) ? 0 : (unsigned char)blocks; if (blocks > 256) { fprintf(stderr, "for 6 byte commands, maximum number of " "blocks is 256\n"); return 1; } if ((start_block + blocks - 1) & (~0x1fffff)) { fprintf(stderr, "for 6 byte commands, can't address blocks" " beyond %d\n", 0x1fffff); return 1; } if (dpo || fua) { fprintf(stderr, "for 6 byte commands, neither dpo nor fua" " bits supported\n"); return 1; } break; case 10: sz_ind = 1; cdbp[0] = (unsigned char)(write_true ? wr_opcode[sz_ind] : rd_opcode[sz_ind]); cdbp[2] = (unsigned char)((start_block >> 24) & 0xff); cdbp[3] = (unsigned char)((start_block >> 16) & 0xff); cdbp[4] = (unsigned char)((start_block >> 8) & 0xff); cdbp[5] = (unsigned char)(start_block & 0xff); cdbp[7] = (unsigned char)((blocks >> 8) & 0xff); cdbp[8] = (unsigned char)(blocks & 0xff); if (blocks & (~0xffff)) { fprintf(stderr, "for 10 byte commands, maximum number of " "blocks is %d\n", 0xffff); return 1; } break; case 12: sz_ind = 2; cdbp[0] = (unsigned char)(write_true ? wr_opcode[sz_ind] : rd_opcode[sz_ind]); cdbp[2] = (unsigned char)((start_block >> 24) & 0xff); cdbp[3] = (unsigned char)((start_block >> 16) & 0xff); cdbp[4] = (unsigned char)((start_block >> 8) & 0xff); cdbp[5] = (unsigned char)(start_block & 0xff); cdbp[6] = (unsigned char)((blocks >> 24) & 0xff); cdbp[7] = (unsigned char)((blocks >> 16) & 0xff); cdbp[8] = (unsigned char)((blocks >> 8) & 0xff); cdbp[9] = (unsigned char)(blocks & 0xff); break; case 16: sz_ind = 3; cdbp[0] = (unsigned char)(write_true ? wr_opcode[sz_ind] : rd_opcode[sz_ind]); cdbp[2] = (unsigned char)((start_block >> 56) & 0xff); cdbp[3] = (unsigned char)((start_block >> 48) & 0xff); cdbp[4] = (unsigned char)((start_block >> 40) & 0xff); cdbp[5] = (unsigned char)((start_block >> 32) & 0xff); cdbp[6] = (unsigned char)((start_block >> 24) & 0xff); cdbp[7] = (unsigned char)((start_block >> 16) & 0xff); cdbp[8] = (unsigned char)((start_block >> 8) & 0xff); cdbp[9] = (unsigned char)(start_block & 0xff); cdbp[10] = (unsigned char)((blocks >> 24) & 0xff); cdbp[11] = (unsigned char)((blocks >> 16) & 0xff); cdbp[12] = (unsigned char)((blocks >> 8) & 0xff); cdbp[13] = (unsigned char)(blocks & 0xff); break; default: fprintf(stderr, "expected cdb size of 6, 10, 12, or 16 but got" " %d\n", cdb_sz); return 1; } return 0; } /* Read using the pass-through. No retries or remedial work here. * 0 -> successful, SG_LIB_SYNTAX_ERROR -> unable to build cdb, * SG_LIB_CAT_UNIT_ATTENTION -> try again, * SG_LIB_CAT_MEDIUM_HARD_WITH_INFO -> 'io_addrp' written to, * SG_LIB_CAT_MEDIUM_HARD -> no info field, * SG_LIB_CAT_NOT_READY, SG_LIB_CAT_ABORTED_COMMAND, * -2 -> ENOMEM * -1 other errors */ static int pt_low_read(int sg_fd, int in0_out1, unsigned char * buff, int blocks, int64_t from_block, int bs, const struct flags_t * ifp, uint64_t * io_addrp) { unsigned char rdCmd[MAX_SCSI_CDBSZ]; unsigned char sense_b[SENSE_BUFF_LEN]; int res, k, info_valid, slen, sense_cat, ret, vt; struct sg_pt_base * ptvp = (in0_out1 ? of_ptvp : if_ptvp); if (pt_build_scsi_cdb(rdCmd, ifp->cdbsz, blocks, from_block, 0, ifp->fua, ifp->fua_nv, ifp->dpo)) { fprintf(stderr, "bad rd cdb build, from_block=%"PRId64", " "blocks=%d\n", from_block, blocks); return SG_LIB_SYNTAX_ERROR; } if (verbose > 2) { fprintf(stderr, " READ cdb: "); for (k = 0; k < ifp->cdbsz; ++k) fprintf(stderr, "%02x ", rdCmd[k]); fprintf(stderr, "\n"); } if (NULL == ptvp) { fprintf(stderr, "pt_low_read: if_ptvp NULL?\n"); return -1; } clear_scsi_pt_obj(ptvp); set_scsi_pt_cdb(ptvp, rdCmd, ifp->cdbsz); set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); set_scsi_pt_data_in(ptvp, buff, bs * blocks); #ifdef SCSI_PT_FLAGS_FUNCTION set_scsi_pt_flags(ptvp, SCSI_PT_FLAGS_QUEUE_AT_TAIL); #endif vt = (verbose ? (verbose - 1) : 0); while (((res = do_scsi_pt(ptvp, sg_fd, DEF_TIMEOUT, vt)) < 0) && (-EINTR == res)) ++interrupted_retries; /* resubmit if interrupted system call */ vt = ((verbose > 1) ? (verbose - 1) : verbose); ret = sg_cmds_process_resp(ptvp, "READ", res, bs * blocks, sense_b, 0 /* noisy */, vt, &sense_cat); if (-1 == ret) ; else if (-2 == ret) { slen = get_scsi_pt_sense_len(ptvp); ret = sense_cat; switch (sense_cat) { case SG_LIB_CAT_NOT_READY: case SG_LIB_CAT_INVALID_OP: ++unrecovered_errs; break; case SG_LIB_CAT_UNIT_ATTENTION: case SG_LIB_CAT_ABORTED_COMMAND: break; case SG_LIB_CAT_RECOVERED: ++recovered_errs; info_valid = sg_get_sense_info_fld(sense_b, slen, io_addrp); if (info_valid) fprintf(stderr, " lba of last recovered error in this " "READ=0x%"PRIx64"\n", *io_addrp); else fprintf(stderr, "Recovered error: [no info] reading from " "block=0x%"PRIx64", num=%d\n", from_block, blocks); break; case SG_LIB_CAT_MEDIUM_HARD: ++unrecovered_errs; info_valid = sg_get_sense_info_fld(sense_b, slen, io_addrp); /* MMC and MO devices don't necessarily set VALID bit */ if (info_valid || ((*io_addrp > 0) && ((5 == ifp->pdt) || (7 == ifp->pdt)))) ret = SG_LIB_CAT_MEDIUM_HARD_WITH_INFO; // <<<<<<<<<<<< else fprintf(stderr, "Medium, hardware or blank check error but " "no lba of failure in sense data\n"); break; case SG_LIB_CAT_NO_SENSE: ret = 0; break; case SG_LIB_CAT_ILLEGAL_REQ: if (5 == ifp->pdt) { /* MMC READs can go down this path */ struct sg_scsi_sense_hdr ssh; int ili; if (sg_scsi_normalize_sense(sense_b, slen, &ssh) && (0x64 == ssh.asc) && (0x0 == ssh.ascq)) { if (sg_get_sense_filemark_eom_ili(sense_b, slen, NULL, NULL, &ili) && ili) { info_valid = sg_get_sense_info_fld(sense_b, slen, io_addrp); if (*io_addrp > 0) { ++unrecovered_errs; ret = SG_LIB_CAT_MEDIUM_HARD_WITH_INFO; } else fprintf(stderr, "MMC READ gave 'illegal mode for " "this track' and ILI but no LBA of failure\n"); } ++unrecovered_errs; ret = SG_LIB_CAT_MEDIUM_HARD; } } default: break; } } else ret = 0; /* We are going to re-read those good blocks */ if (SG_LIB_CAT_MEDIUM_HARD_WITH_INFO != ret) sum_of_resids += get_scsi_pt_resid(ptvp); return ret; } void zero_coe_limit_count(void) { if (coe_limit > 0) coe_count = 0; } /* Control pass-through read retries and coe (continue on error). * Fast path is a call to pt_low_read() that succeeds. If medium * error then back up and re-read good blocks prior to bad block; * then, if coe, use zero for bad block and continue reading at * the next LBA (N.B. more medium errors could occur). * 0 -> successful, SG_LIB_SYNTAX_ERROR -> unable to build cdb, * SG_LIB_CAT_UNIT_ATTENTION -> try again, SG_LIB_CAT_NOT_READY, * SG_LIB_CAT_MEDIUM_HARD, SG_LIB_CAT_ABORTED_COMMAND, * -2 -> ENOMEM, -1 other errors */ static int pt_read(int sg_fd, int in0_out1, unsigned char * buff, int blocks, int64_t from_block, int bs, struct flags_t * ifp, int * blks_readp) { uint64_t io_addr; int64_t lba; int res, blks, use_io_addr, xferred; unsigned char * bp; int retries_tmp; int ret = 0; int may_coe = 0; retries_tmp = ifp->retries; for (xferred = 0, blks = blocks, lba = from_block, bp = buff; blks > 0; blks = blocks - xferred) { io_addr = 0; use_io_addr = 0; may_coe = 0; res = pt_low_read(sg_fd, in0_out1, bp, blks, lba, bs, ifp, &io_addr); switch (res) { case 0: /* this is the fast path after good pt_low_read() */ if (blks_readp) *blks_readp = xferred + blks; zero_coe_limit_count(); return 0; case -2: /* ENOMEM */ return res; case SG_LIB_CAT_NOT_READY: fprintf(stderr, "Device (r) not ready\n"); return res; case SG_LIB_CAT_ABORTED_COMMAND: if (--max_aborted > 0) fprintf(stderr, "Aborted command, continuing (r)\n"); else { fprintf(stderr, "Aborted command, too many (r)\n"); return res; } break; case SG_LIB_CAT_UNIT_ATTENTION: if (--max_uas > 0) fprintf(stderr, "Unit attention, continuing (r)\n"); else { fprintf(stderr, "Unit attention, too many (r)\n"); return res; } break; case SG_LIB_CAT_MEDIUM_HARD_WITH_INFO: if (retries_tmp > 0) { fprintf(stderr, ">>> retrying pt read: starting " "lba=%"PRId64" [0x%"PRIx64"] blocks=%d\n", lba, (uint64_t)lba, blks); --retries_tmp; ++num_retries; if (unrecovered_errs > 0) --unrecovered_errs; } else use_io_addr = 1; ret = SG_LIB_CAT_MEDIUM_HARD; break; /* unrecovered read error at lba=io_addr */ case SG_LIB_SYNTAX_ERROR: ifp->coe = 0; ret = res; goto err_out; case -1: ret = res; goto err_out; case SG_LIB_CAT_MEDIUM_HARD: may_coe = 1; #ifdef ERRBLK_SUPPORTED /* No VALID+INFO field but we know the range of lba_s */ if (0 == retries_tmp) put_range_errblk(lba, blks); #endif /* fall through */ default: if (retries_tmp > 0) { fprintf(stderr, ">>> retrying pt read: starting " "lba=%"PRId64" [0x%"PRIx64"] blocks=%d\n", lba, (uint64_t)lba, blks); --retries_tmp; ++num_retries; if (unrecovered_errs > 0) --unrecovered_errs; break; } ret = res; goto err_out; } if (! use_io_addr) continue; if ((io_addr < (uint64_t)lba) || (io_addr >= (uint64_t)(lba + blks))) { fprintf(stderr, " Unrecovered error lba 0x%"PRIx64" not in " "correct range:\n\t[0x%"PRIx64",0x%"PRIx64"]\n", io_addr, (uint64_t)lba, (uint64_t)(lba + blks - 1)); may_coe = 1; goto err_out; } if (highest_unrecovered < 0) { highest_unrecovered = io_addr; lowest_unrecovered = io_addr; } else { if ((int64_t)io_addr < lowest_unrecovered) lowest_unrecovered = io_addr; if ((int64_t)io_addr > highest_unrecovered) highest_unrecovered = io_addr; } #ifdef ERRBLK_SUPPORTED put_errblk(io_addr); #endif if (ifp->coe) { ++in_partial; --in_full; } blks = (int)(io_addr - (uint64_t)lba); if (blks > 0) { if (verbose) fprintf(stderr, " partial re-read of %d blocks prior to " "medium error\n", blks); res = pt_low_read(sg_fd, in0_out1, bp, blks, lba, bs, ifp, &io_addr); switch (res) { case 0: break; case -1: ifp->coe = 0; ret = res; goto err_out; case -2: fprintf(stderr, "ENOMEM again, unexpected (r)\n"); return -1; case SG_LIB_CAT_NOT_READY: fprintf(stderr, "device (r) not ready\n"); return res; case SG_LIB_CAT_UNIT_ATTENTION: fprintf(stderr, "Unit attention, unexpected (r)\n"); return res; case SG_LIB_CAT_ABORTED_COMMAND: fprintf(stderr, "Aborted command, unexpected (r)\n"); return res; case SG_LIB_CAT_MEDIUM_HARD_WITH_INFO: case SG_LIB_CAT_MEDIUM_HARD: ret = SG_LIB_CAT_MEDIUM_HARD; goto err_out; case SG_LIB_SYNTAX_ERROR: default: fprintf(stderr, ">> unexpected result=%d from " "pt_low_read() 2\n", res); ret = res; goto err_out; } } xferred += blks; if (0 == ifp->coe) { /* give up at block before problem unless 'coe' */ if (blks_readp) *blks_readp = xferred; return ret; } bp += (blks * bs); lba += blks; fprintf(stderr, ">> unrecovered read error at blk=%"PRId64", " "substitute zeros\n", lba); memset(bp, 0, bs); ++xferred; bp += bs; ++lba; if ((coe_limit > 0) && (++coe_count > coe_limit)) { if (blks_readp) *blks_readp = xferred + blks; fprintf(stderr, ">> coe_limit on consecutive reads exceeded\n"); return SG_LIB_CAT_MEDIUM_HARD; } retries_tmp = ifp->retries; } if (blks_readp) *blks_readp = xferred; return 0; err_out: if (ifp->coe) { memset(bp, 0, bs * blks); fprintf(stderr, ">> unable to read at blk=%"PRId64" for " "%d bytes, use zeros\n", lba, bs * blks); if (blks > 1) fprintf(stderr, ">> try reducing bpt to limit number " "of zeros written near bad block(s)\n"); /* fudge success */ if (blks_readp) *blks_readp = xferred + blks; if ((coe_limit > 0) && (++coe_count > coe_limit)) { fprintf(stderr, ">> coe_limit on consecutive reads exceeded\n"); return ret; } return may_coe ? 0 : ret; } else return ret ? ret : -1; } /* Write block(s) via the pass-through. * 0 -> successful, SG_LIB_SYNTAX_ERROR -> unable to build cdb, * SG_LIB_CAT_NOT_READY, SG_LIB_CAT_UNIT_ATTENTION, SG_LIB_CAT_MEDIUM_HARD, * SG_LIB_CAT_ABORTED_COMMAND, -2 -> recoverable (ENOMEM), * -1 -> unrecoverable error + others */ static int pt_low_write(int sg_fd, unsigned char * buff, int blocks, int64_t to_block, int bs, const struct flags_t * ofp) { unsigned char wrCmd[MAX_SCSI_CDBSZ]; unsigned char sense_b[SENSE_BUFF_LEN]; int res, k, info_valid, ret, sense_cat, slen, vt; uint64_t io_addr = 0; struct sg_pt_base * ptvp = of_ptvp; if (pt_build_scsi_cdb(wrCmd, ofp->cdbsz, blocks, to_block, 1, ofp->fua, ofp->fua_nv, ofp->dpo)) { fprintf(stderr, "bad wr cdb build, to_block=%"PRId64", blocks=%d\n", to_block, blocks); return SG_LIB_SYNTAX_ERROR; } if (verbose > 2) { fprintf(stderr, " WRITE cdb: "); for (k = 0; k < ofp->cdbsz; ++k) fprintf(stderr, "%02x ", wrCmd[k]); fprintf(stderr, "\n"); } if (NULL == ptvp) { fprintf(stderr, "pt_low_write: of_ptvp NULL?\n"); return -1; } clear_scsi_pt_obj(ptvp); set_scsi_pt_cdb(ptvp, wrCmd, ofp->cdbsz); set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); set_scsi_pt_data_out(ptvp, buff, bs * blocks); vt = (verbose ? (verbose - 1) : 0); while (((res = do_scsi_pt(ptvp, sg_fd, DEF_TIMEOUT, vt)) < 0) && (-EINTR == res)) ++interrupted_retries; /* resubmit if interrupted system call */ vt = ((verbose > 1) ? (verbose - 1) : verbose); ret = sg_cmds_process_resp(ptvp, "WRITE", res, bs * blocks, sense_b, 0 /* noisy */, vt, &sense_cat); if (-1 == ret) ; else if (-2 == ret) { slen = get_scsi_pt_sense_len(ptvp); ret = sense_cat; switch (sense_cat) { case SG_LIB_CAT_RECOVERED: ++wr_recovered_errs; info_valid = sg_get_sense_info_fld(sense_b, slen, &io_addr); if (info_valid) fprintf(stderr, " lba of last recovered error in this " "WRITE=0x%"PRIx64"\n", io_addr); else fprintf(stderr, "Recovered error: [no info] writing to " "block=0x%"PRIx64", num=%d\n", to_block, blocks); break; case SG_LIB_CAT_ABORTED_COMMAND: case SG_LIB_CAT_UNIT_ATTENTION: break; case SG_LIB_CAT_NOT_READY: ++wr_unrecovered_errs; break; case SG_LIB_CAT_MEDIUM_HARD: default: ++wr_unrecovered_errs; if (ofp->coe) { fprintf(stderr, ">> ignored errors for out blk=%"PRId64" for " "%d bytes\n", to_block, bs * blocks); ret = 0; /* fudge success */ } break; } } else ret = 0; return ret; } /* Control pass-through write retries. * 0 -> successful, SG_LIB_SYNTAX_ERROR -> unable to build cdb, * SG_LIB_CAT_UNIT_ATTENTION -> try again, SG_LIB_CAT_NOT_READY, * SG_LIB_CAT_MEDIUM_HARD, SG_LIB_CAT_ABORTED_COMMAND, * -2 -> ENOMEM, -1 other errors */ static int pt_write(int sg_fd, unsigned char * buff, int blocks, int64_t to_block, int bs, struct flags_t * ofp) { int retries_tmp; int first = 1; int ret = 0; retries_tmp = ofp->retries; while (1) { ret = pt_low_write(sg_fd, buff, blocks, to_block, bs, ofp); if (0 == ret) break; if ((SG_LIB_CAT_NOT_READY == ret) || (SG_LIB_SYNTAX_ERROR == ret)) break; else if ((SG_LIB_CAT_UNIT_ATTENTION == ret) && first) { if (--max_uas > 0) fprintf(stderr, "Unit attention, continuing (w)\n"); else { fprintf(stderr, "Unit attention, too many (w)\n"); break; } } else if ((SG_LIB_CAT_ABORTED_COMMAND == ret) && first) { if (--max_aborted > 0) fprintf(stderr, "Aborted command, continuing (w)\n"); else { fprintf(stderr, "Aborted command, too many (w)\n"); break; } } else if (ret < 0) break; else if (retries_tmp > 0) { fprintf(stderr, ">>> retrying pt write: starting lba=%"PRId64" " "[0x%"PRIx64"] blocks=%d\n", to_block, (uint64_t)to_block, blocks); --retries_tmp; ++num_retries; if (wr_unrecovered_errs > 0) --wr_unrecovered_errs; } else break; first = 0; } return ret; } /* This function performs a "trim" on a pt device. In the SCSI command set * this is either done with the UNMAP command or WRITE SAME command. This * function uses WRITE SAME(16) with the unmap bit set. In Linux libata * translates this to the ATA DATA SET MANAGEMENT command with the trim * field set. Returns 0 on success. */ static int pt_write_same16(int sg_fd, int in0_out1, unsigned char * buff, int bs, int blocks, int64_t start_block) { int k, ret, res, sense_cat, vt; uint64_t llba; uint32_t unum; unsigned char wsCmdBlk[16]; unsigned char sense_b[SENSE_BUFF_LEN]; struct sg_pt_base * ptvp = in0_out1 ? of_ptvp : if_ptvp; memset(wsCmdBlk, 0, sizeof(wsCmdBlk)); wsCmdBlk[0] = 0x93; /* WRITE SAME(16) opcode */ /* set UNMAP; clear wrprotect, anchor, pbdata, lbdata */ wsCmdBlk[1] = 0x8; llba = start_block; for (k = 7; k >= 0; --k) { wsCmdBlk[2 + k] = (llba & 0xff); llba >>= 8; } unum = blocks; for (k = 3; k >= 0; --k) { wsCmdBlk[10 + k] = (unum & 0xff); unum >>= 8; } if (verbose > 2) { fprintf(stderr, " WRITE SAME(16) cdb: "); for (k = 0; k < (int)sizeof(wsCmdBlk); ++k) fprintf(stderr, "%02x ", wsCmdBlk[k]); fprintf(stderr, "\n"); if (verbose > 4) fprintf(stderr, " Data-out buffer length=%d\n", bs); } if (NULL == ptvp) { fprintf(stderr, "pt_write_same16: ptvp NULL?\n"); return -1; } clear_scsi_pt_obj(ptvp); set_scsi_pt_cdb(ptvp, wsCmdBlk, sizeof(wsCmdBlk)); set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); set_scsi_pt_data_out(ptvp, buff, bs); vt = ((verbose > 1) ? (verbose - 1) : 0); while (((res = do_scsi_pt(ptvp, sg_fd, WRITE_SAME16_TIMEOUT, vt)) < 0) && (-EINTR == res)) ++interrupted_retries; /* resubmit if interrupted system call */ ret = sg_cmds_process_resp(ptvp, "Write same(16)", res, 0, sense_b, 1 /*noisy */, vt, &sense_cat); if (-1 == ret) ; else if (-2 == ret) { switch (sense_cat) { case SG_LIB_CAT_NOT_READY: case SG_LIB_CAT_UNIT_ATTENTION: case SG_LIB_CAT_INVALID_OP: case SG_LIB_CAT_ILLEGAL_REQ: case SG_LIB_CAT_ABORTED_COMMAND: ret = sense_cat; break; case SG_LIB_CAT_RECOVERED: case SG_LIB_CAT_NO_SENSE: ret = 0; break; case SG_LIB_CAT_MEDIUM_HARD: { int valid, slen; uint64_t ull = 0; slen = get_scsi_pt_sense_len(ptvp); valid = sg_get_sense_info_fld(sense_b, slen, &ull); if (valid) fprintf(stderr, "Medium or hardware error starting at " "lba=%"PRIu64" [0x%"PRIx64"]\n", ull, ull); } ret = sense_cat; break; default: ret = -1; break; } } else ret = 0; return ret; } /* Print number of blocks, block size. If over 1 MB print size in MB * (10**6 bytes), GB (10**9 bytes) or TB (10**12 bytes) to stderr. */ static void print_blk_sizes(const char * fname, const char * access_typ, int64_t num_sect, int sect_sz) { int mb, gb; size_t len; int64_t n; char b[32]; char dec[4]; mb = 0; if ((num_sect > 0) && (sect_sz > 0)) { n = num_sect * sect_sz; mb = n / 1000000; } if (mb > 999999) { gb = mb / 1000; snprintf(b, sizeof(b), "%d", gb); len = strlen(b); // len must be >= 4 dec[0] = b[len - 3]; dec[1] = b[len - 2]; dec[2] = '\0'; b[len - 3] = '\0'; fprintf(stderr, " %s [%s]: blocks=%"PRId64" [0x%"PRIx64"], " "_bs=%d, %s.%s TB\n", fname, access_typ, num_sect, num_sect, sect_sz, b, dec); } else if (mb > 99999) { gb = mb / 1000; fprintf(stderr, " %s [%s]: blocks=%"PRId64" [0x%"PRIx64"], " "_bs=%d, %d GB\n", fname, access_typ, num_sect, num_sect, sect_sz, gb); } else if (mb > 999) { snprintf(b, sizeof(b), "%d", mb); len = strlen(b); // len must be >= 4 dec[0] = b[len - 3]; dec[1] = b[len - 2]; dec[2] = '\0'; b[len - 3] = '\0'; fprintf(stderr, " %s [%s]: blocks=%"PRId64" [0x%"PRIx64"], " "_bs=%d, %s.%s GB\n", fname, access_typ, num_sect, num_sect, sect_sz, b, dec); } else if (mb > 0) { fprintf(stderr, " %s [%s]: blocks=%"PRId64" [0x%"PRIx64"], " "_bs=%d, %d MB%s\n", fname, access_typ, num_sect, num_sect, sect_sz, mb, ((mb < 10) ? " approx" : "")); } else fprintf(stderr, " %s [%s]: blocks=%"PRId64" [0x%"PRIx64"], " "_bs=%d\n", fname, access_typ, num_sect, num_sect, sect_sz); } /* Calculates transfer throughput, typically in Megabytes per second. * A megabyte in this context is 1000000 bytes (gives bigger numbers so * is preferred by industry). The clock_gettime() interface is preferred * since time is guaranteed to advance; gettimeofday() is impacted if the * user (or something like ntpd) changes the time. * Also if the transfer is large enough and isn't about to finish, it * makes an estimate of the time remaining. */ static void calc_duration_throughput(const char * leadin, int contin) { #if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC) struct timespec end_tm, res_tm; double a, b, r; int secs, h, m; int64_t blks; if (start_tm_valid && (start_tm.tv_sec || start_tm.tv_nsec)) { blks = in_full; clock_gettime(CLOCK_MONOTONIC, &end_tm); res_tm.tv_sec = end_tm.tv_sec - start_tm.tv_sec; res_tm.tv_nsec = end_tm.tv_nsec - start_tm.tv_nsec; if (res_tm.tv_nsec < 0) { --res_tm.tv_sec; res_tm.tv_nsec += 1000000000; } a = res_tm.tv_sec; a += (0.000001 * (res_tm.tv_nsec / 1000)); b = (double)ibs_hold * blks; fprintf(stderr, "%stime to %s data%s: %d.%06d secs", leadin, (read1_or_transfer ? "read" : "transfer"), (contin ? " so far" : ""), (int)res_tm.tv_sec, (int)(res_tm.tv_nsec / 1000)); r = 0.0; if ((a > 0.00001) && (b > 511)) { r = b / (a * 1000000.0); fprintf(stderr, " at %.2f MB/sec\n", r); } else fprintf(stderr, "\n"); if (contin && (! reading_fifo) && (r > 0.01) && (dd_count > 100)) { secs = (int)(((double)ibs_hold * dd_count) / (r * 1000000)); if (secs > 10) { h = secs / 3600; secs = secs - (h * 3600); m = secs / 60; secs = secs - (m * 60); if (h > 0) fprintf(stderr, "%sestimated time remaining: " "%d:%02d:%02d\n", leadin, h, m, secs); else fprintf(stderr, "%sestimated time remaining: " "%d:%02d\n", leadin, m, secs); } } } #elif defined(HAVE_GETTIMEOFDAY) struct timeval end_tm, res_tm; double a, b, r; int secs, h, m; int64_t blks; if (start_tm_valid && (start_tm.tv_sec || start_tm.tv_usec)) { blks = in_full; gettimeofday(&end_tm, NULL); res_tm.tv_sec = end_tm.tv_sec - start_tm.tv_sec; res_tm.tv_usec = end_tm.tv_usec - start_tm.tv_usec; if (res_tm.tv_usec < 0) { --res_tm.tv_sec; res_tm.tv_usec += 1000000; } a = res_tm.tv_sec; a += (0.000001 * res_tm.tv_usec); b = (double)ibs_hold * blks; fprintf(stderr, "%stime to %s data%s: %d.%06d secs", leadin, (read1_or_transfer ? "read" : "transfer"), (contin ? " so far" : ""), (int)res_tm.tv_sec, (int)res_tm.tv_usec); r = 0.0; if ((a > 0.00001) && (b > 511)) { r = b / (a * 1000000.0); fprintf(stderr, " at %.2f MB/sec\n", r); } else fprintf(stderr, "\n"); if (contin && (! reading_fifo) && (r > 0.01) && (dd_count > 100)) { secs = (int)(((double)ibs_hold * dd_count) / (r * 1000000)); if (secs > 10) { h = secs / 3600; secs = secs - (h * 3600); m = secs / 60; secs = secs - (m * 60); if (h > 0) fprintf(stderr, "%sestimated time remaining: " "%d:%02d:%02d\n", leadin, h, m, secs); else fprintf(stderr, "%sestimated time remaining: " "%d:%02d\n", leadin, m, secs); } } } #else leadin = leadin; // suppress warning contin = contin; // suppress warning #endif } /* Returns open input file descriptor (>= 0) or a negative value * (-SG_LIB_FILE_ERROR or -SG_LIB_CAT_OTHER) if error. */ static int open_if(struct opts_t * optsp, int verbose) { int flags, fl, verb; int fd = -SG_LIB_FILE_ERROR; char ebuff[EBUFF_SZ]; struct sg_simple_inquiry_resp sir; struct flags_t * ifp = optsp->iflagp; const char * inf = optsp->inf; verb = (verbose ? verbose - 1: 0); optsp->in_type = dd_filetype(inf); if (FT_ERROR & optsp->in_type) { fprintf(stderr, "unable to access %s\n", inf); goto file_err; } else if (((FT_BLOCK | FT_OTHER) & optsp->in_type) && ifp->pt) optsp->in_type |= FT_PT; if (verbose) fprintf(stderr, " >> Input file type: %s\n", dd_filetype_str(optsp->in_type, ebuff, EBUFF_SZ, inf)); if ((FT_FIFO & optsp->in_type) || (FT_CHAR & optsp->in_type)) ++reading_fifo; if (FT_TAPE & optsp->in_type) { fprintf(stderr, "unable to use scsi tape device %s\n", inf); goto file_err; } else if (FT_PT & optsp->in_type) { flags = O_NONBLOCK; if (ifp->direct) flags |= O_DIRECT; if (ifp->excl) flags |= O_EXCL; if (ifp->sync) flags |= O_SYNC; fl = O_RDWR; if ((fd = scsi_pt_open_flags(inf, (fl | flags), verbose)) < 0) { fl = O_RDONLY; if ((fd = scsi_pt_open_flags(inf, (fl | flags), verbose)) < 0) { fprintf(stderr, "could not open %s for pt reading: %s\n", inf, safe_strerror(-fd)); goto file_err; } } if (sg_simple_inquiry(fd, &sir, 0, verb)) { fprintf(stderr, "INQUIRY failed on %s\n", inf); goto other_err; } ifp->pdt = sir.peripheral_type; if (verbose) fprintf(stderr, " %s: %.8s %.16s %.4s [pdt=%d]\n", inf, sir.vendor, sir.product, sir.revision, ifp->pdt); } #ifdef SG_LIB_WIN32 else if (FT_BLOCK & optsp->in_type) { if (win32_open_if(optsp, verbose)) goto file_err; fd = 0; } #endif else { flags = O_RDONLY; if (ifp->direct) flags |= O_DIRECT; if (ifp->excl) flags |= O_EXCL; if (ifp->sync) flags |= O_SYNC; fd = open(inf, flags); if (fd < 0) { fprintf(stderr, "could not open %s for reading: %s\n", inf, safe_strerror(errno)); goto file_err; } else { if (sg_set_binary_mode(fd) < 0) perror("sg_set_binary_mode"); if (verbose) fprintf(stderr, " open %s, flags=0x%x\n", inf, flags); #ifdef HAVE_POSIX_FADVISE if (ifp->nocache) { int rt; rt = posix_fadvise(fd, 0, 0, POSIX_FADV_SEQUENTIAL); if (rt) fprintf(stderr, "open_if: posix_fadvise(SEQUENTIAL), " "err=%d\n", rt); } #endif } } #ifdef SG_LIB_LINUX if (ifp->flock) { int res; res = flock(fd, LOCK_EX | LOCK_NB); if (res < 0) { close(fd); fprintf(stderr, "flock(LOCK_EX | LOCK_NB) on %s failed: %s\n", inf, safe_strerror(errno)); return -SG_LIB_FLOCK_ERR; } } #endif return fd; file_err: return -SG_LIB_FILE_ERROR; other_err: return -SG_LIB_CAT_OTHER; } /* Returns open output file descriptor (>= 0), -1 for don't * bother opening (e.g. /dev/null), or a more negative value * (-SG_LIB_FILE_ERROR or -SG_LIB_CAT_OTHER) if error. */ static int open_of(struct opts_t * optsp, int verbose) { int flags, verb; int fd = -SG_LIB_FILE_ERROR; int outf_exists = 0; char ebuff[EBUFF_SZ]; struct sg_simple_inquiry_resp sir; struct stat st; struct flags_t * ofp = optsp->oflagp; const char * outf = optsp->outf; verb = (verbose ? verbose - 1: 0); optsp->out_type = dd_filetype(outf); if (((FT_BLOCK | FT_OTHER) & optsp->out_type) && ofp->pt) optsp->out_type |= FT_PT; out_type_hold = optsp->out_type; if (verbose) fprintf(stderr, " >> Output file type: %s\n", dd_filetype_str(optsp->out_type, ebuff, EBUFF_SZ, outf)); if (FT_TAPE & optsp->out_type) { fprintf(stderr, "unable to use scsi tape device %s\n", outf); goto file_err; } else if (FT_PT & optsp->out_type) { flags = O_RDWR | O_NONBLOCK; if (ofp->direct) flags |= O_DIRECT; if (ofp->excl) flags |= O_EXCL; if (ofp->sync) flags |= O_SYNC; if ((fd = scsi_pt_open_flags(outf, flags, verbose)) < 0) { fprintf(stderr, "could not open %s for pt writing: %s\n", outf, safe_strerror(-fd)); goto file_err; } if (sg_simple_inquiry(fd, &sir, 0, verb)) { fprintf(stderr, "INQUIRY failed on %s\n", outf); goto other_err; } ofp->pdt = sir.peripheral_type; if (verbose) fprintf(stderr, " %s: %.8s %.16s %.4s [pdt=%d]\n", outf, sir.vendor, sir.product, sir.revision, ofp->pdt); } else if (FT_DEV_NULL & optsp->out_type) { fd = -1; /* don't bother opening */ } #ifdef SG_LIB_WIN32 else if (FT_BLOCK & optsp->out_type) { if (win32_open_of(optsp, verbose)) goto file_err; fd = 0; } #endif else { /* typically regular file or block device node */ int needs_ftruncate = 0; int64_t offset = 0; memset(&st, 0, sizeof(st)); if (0 == stat(outf, &st)) outf_exists = 1; flags = ofp->sparing ? O_RDWR : O_WRONLY; if (0 == outf_exists) flags |= O_CREAT; if (ofp->direct) flags |= O_DIRECT; if (ofp->excl) flags |= O_EXCL; if (ofp->sync) flags |= O_SYNC; if (ofp->append) flags |= O_APPEND; if ((FT_REG & optsp->out_type) && outf_exists && ofp->trunc && (! ofp->nowrite)) { if (optsp->seek > 0) { offset = optsp->seek * optsp->obs; if (st.st_size > offset) ++needs_ftruncate; // only truncate to shorten } else flags |= O_TRUNC; } if ((fd = open(outf, flags, 0666)) < 0) { fprintf(stderr, "could not open %s for writing: %s\n", outf, safe_strerror(errno)); goto file_err; } if (needs_ftruncate && (offset > 0)) { if (ftruncate(fd, offset) < 0) { fprintf(stderr, "could not ftruncate %s after open (seek): " "%s\n", outf, safe_strerror(errno)); goto file_err; } /* N.B. file offset (pointer) not changed by ftruncate */ } if ((! outf_exists) && (FT_ERROR & optsp->out_type)) { optsp->out_type = FT_REG; /* exists now */ out_type_hold = optsp->out_type; } if (sg_set_binary_mode(fd) < 0) perror("sg_set_binary_mode"); if (verbose) { fprintf(stderr, " %s %s, flags=0x%x\n", (outf_exists ? "open" : "create"), outf, flags); if (needs_ftruncate && (offset > 0)) fprintf(stderr, " truncated file at byte offset " "%"PRId64" \n", offset); } } #ifdef SG_LIB_LINUX if (ofp->flock) { int res; res = flock(fd, LOCK_EX | LOCK_NB); if (res < 0) { close(fd); fprintf(stderr, "flock(LOCK_EX | LOCK_NB) on %s failed: %s\n", outf, safe_strerror(errno)); return -SG_LIB_FLOCK_ERR; } } #endif return fd; file_err: return -SG_LIB_FILE_ERROR; other_err: return -SG_LIB_CAT_OTHER; } /* Helper for calc_count(). Attempts to size IFILE. Returns 0 if no error * detected. */ static int calc_count_in(struct opts_t * optsp, int64_t * in_num_sectp, int * in_sect_szp) { int res; struct stat st; int64_t num_sect, t; int sect_sz; *in_num_sectp = -1; *in_sect_szp = -1; if (FT_PT & optsp->in_type) { if (optsp->iflagp->norcap) { if ((FT_BLOCK & optsp->in_type) && (0 == optsp->iflagp->force)) { fprintf(stderr, ">> warning: norcap on input block device " "accessed via pt is risky.\n"); fprintf(stderr, ">> Abort copy, use iflag=force to " "override.\n"); return -1; } return 0; } res = scsi_read_capacity(optsp->infd, in_num_sectp, in_sect_szp); if (SG_LIB_CAT_UNIT_ATTENTION == res) { fprintf(stderr, "Unit attention (readcap in), continuing\n"); res = scsi_read_capacity(optsp->infd, in_num_sectp, in_sect_szp); } else if (SG_LIB_CAT_ABORTED_COMMAND == res) { fprintf(stderr, "Aborted command (readcap in), continuing\n"); res = scsi_read_capacity(optsp->infd, in_num_sectp, in_sect_szp); } if (0 != res) { if (res == SG_LIB_CAT_INVALID_OP) fprintf(stderr, "read capacity not supported on %s\n", optsp->inf); else if (res == SG_LIB_CAT_NOT_READY) fprintf(stderr, "read capacity failed on %s - not ready\n", optsp->inf); else fprintf(stderr, "Unable to read capacity on %s\n", optsp->inf); *in_num_sectp = -1; return res; } else { if (verbose) print_blk_sizes(optsp->inf, "pt", *in_num_sectp, *in_sect_szp); if (*in_sect_szp != optsp->ibs) { fprintf(stderr, ">> warning: %s block size confusion: ibs=%d, " "device claims=%d\n", optsp->inf, optsp->ibs, *in_sect_szp); if (0 == optsp->iflagp->force) { fprintf(stderr, ">> abort copy, use iflag=force to " "override\n"); return -1; } } } if ((FT_BLOCK & optsp->in_type) && (0 == optsp->iflagp->force) && (0 == get_blkdev_capacity(optsp, DDPT_ARG_IN, &num_sect, §_sz, verbose))) { t = (*in_num_sectp) * (*in_sect_szp); if (t != (num_sect * sect_sz)) { fprintf(stderr, ">> warning: Size of input block device is " "different from pt size.\n>> Pass-through on block " "partition can give unexpected offsets.\n"); fprintf(stderr, ">> Abort copy, use iflag=force to " "override.\n"); return -1; } } } else if ((dd_count > 0) && (0 == optsp->oflagp->resume)) return 0; else if (FT_BLOCK & optsp->in_type) { if (0 != get_blkdev_capacity(optsp, DDPT_ARG_IN, in_num_sectp, in_sect_szp, verbose)) { fprintf(stderr, "Unable to read block capacity on %s\n", optsp->inf); *in_num_sectp = -1; } if (verbose) print_blk_sizes(optsp->inf, "blk", *in_num_sectp, *in_sect_szp); if (optsp->ibs != *in_sect_szp) { fprintf(stderr, ">> warning: %s block size confusion: bs=%d, " "device claims=%d\n", optsp->inf, optsp->ibs, *in_sect_szp); *in_num_sectp = -1; } } else if (FT_REG & optsp->in_type) { if (fstat(optsp->infd, &st) < 0) { perror("fstat(infd) error"); *in_num_sectp = -1; } else { *in_num_sectp = st.st_size / optsp->ibs; if (0 != (st.st_size % optsp->ibs)) ++*in_num_sectp; } } return 0; } /* Helper for calc_count(). Attempts to size OFILE. Returns 0 if no error * detected. */ static int calc_count_out(struct opts_t * optsp, int64_t * out_num_sectp, int * out_sect_szp) { int res; struct stat st; int64_t num_sect, t; int sect_sz; *out_num_sectp = -1; *out_sect_szp = -1; if (FT_PT & optsp->out_type) { if (optsp->oflagp->norcap) { if ((FT_BLOCK & optsp->out_type) && (0 == optsp->oflagp->force)) { fprintf(stderr, ">> warning: norcap on output block device " "accessed via pt is risky.\n"); fprintf(stderr, ">> Abort copy, use oflag=force to " "override.\n"); return -1; } return 0; } res = scsi_read_capacity(optsp->outfd, out_num_sectp, out_sect_szp); if (SG_LIB_CAT_UNIT_ATTENTION == res) { fprintf(stderr, "Unit attention (readcap out), continuing\n"); res = scsi_read_capacity(optsp->outfd, out_num_sectp, out_sect_szp); } else if (SG_LIB_CAT_ABORTED_COMMAND == res) { fprintf(stderr, "Aborted command (readcap out), continuing\n"); res = scsi_read_capacity(optsp->outfd, out_num_sectp, out_sect_szp); } if (0 != res) { if (res == SG_LIB_CAT_INVALID_OP) fprintf(stderr, "read capacity not supported on %s\n", optsp->outf); else fprintf(stderr, "Unable to read capacity on %s\n", optsp->outf); *out_num_sectp = -1; return res; } else { if (verbose) print_blk_sizes(optsp->outf, "pt", *out_num_sectp, *out_sect_szp); if (optsp->obs != *out_sect_szp) { fprintf(stderr, ">> warning: %s block size confusion: " "obs=%d, device claims=%d\n", optsp->outf, optsp->obs, *out_sect_szp); if (0 == optsp->oflagp->force) { fprintf(stderr, ">> abort copy, use oflag=force to " "override\n"); return -1; } } } if ((FT_BLOCK & optsp->out_type) && (0 == optsp->oflagp->force) && (0 == get_blkdev_capacity(optsp, DDPT_ARG_OUT, &num_sect, §_sz, verbose))) { t = (*out_num_sectp) * (*out_sect_szp); if (t != (num_sect * sect_sz)) { fprintf(stderr, ">> warning: size of output block device is " "different from pt size.\n>> Pass-through on block " "partition can give unexpected results.\n"); fprintf(stderr, ">> abort copy, use oflag=force to " "override\n"); return -1; } } } else if ((dd_count > 0) && (0 == optsp->oflagp->resume)) return 0; else if (FT_BLOCK & optsp->out_type) { if (0 != get_blkdev_capacity(optsp, DDPT_ARG_OUT, out_num_sectp, out_sect_szp, verbose)) { fprintf(stderr, "Unable to read block capacity on %s\n", optsp->outf); *out_num_sectp = -1; } else { if (verbose) print_blk_sizes(optsp->outf, "blk", *out_num_sectp, *out_sect_szp); if (optsp->obs != *out_sect_szp) { fprintf(stderr, ">> warning: %s block size confusion: " "obs=%d, device claims=%d\n", optsp->outf, optsp->obs, *out_sect_szp); *out_num_sectp = -1; } } } else if (FT_REG & optsp->out_type) { if (fstat(optsp->outfd, &st) < 0) { perror("fstat(outfd) error"); *out_num_sectp = -1; } else { *out_num_sectp = st.st_size / optsp->obs; if (0 != (st.st_size % optsp->obs)) ++*out_num_sectp; } } return 0; } /* Calculates the number of blocks associated with the in and out files. * May also yield the block size in bytes of devices. For regular files * uses ibs or obs as the block (sector) size. Returns 0 for continue, * otherwise bypass copy and exit. */ static int calc_count(struct opts_t * optsp, int64_t * in_num_sectp, int * in_sect_szp, int64_t * out_num_sectp, int * out_sect_szp) { int res; res = calc_count_in(optsp, in_num_sectp, in_sect_szp); if (res) { *out_num_sectp = -1; *out_sect_szp = -1; return res; } return calc_count_out(optsp, out_num_sectp, out_sect_szp); } #ifdef HAVE_POSIX_FADVISE /* Used by iflag=nocache and oflag=nocache to suggest (via posix_fadvise() * system call) that the OS doesn't cache data it has just read or written * since it is unlikely to be used again in the short term. iflag=nocache * additionally increases the read-ahead. Errors ignored. */ static void do_fadvise(struct opts_t * op, int bytes_if, int bytes_of, int bytes_of2) { int rt, in_valid, out2_valid, out_valid; static off_t lowest_skip = -1; static off_t lowest_seek = -1; in_valid = ((FT_REG == op->in_type) || (FT_BLOCK == op->in_type)); out2_valid = ((FT_REG == op->out2_type) || (FT_BLOCK == op->out2_type)); out_valid = ((FT_REG == op->out_type) || (FT_BLOCK == op->out_type)); if (op->iflagp->nocache && (bytes_if > 0) && in_valid) { if ((lowest_skip < 0) || (op->skip > lowest_skip)) lowest_skip = op->skip; rt = posix_fadvise(op->infd, (lowest_skip * op->ibs), ((op->skip - lowest_skip) * op->ibs) + bytes_if, POSIX_FADV_DONTNEED); if (rt) /* returns error as result */ fprintf(stderr, "posix_fadvise on read, skip=%"PRId64" ,err=%d\n", op->skip, rt); } if ((op->oflagp->nocache & 2) && (bytes_of2 > 0) && out2_valid) { rt = posix_fadvise(op->out2fd, 0, 0, POSIX_FADV_DONTNEED); if (rt) fprintf(stderr, "posix_fadvise on of2, seek=" "%"PRId64" ,err=%d\n", op->seek, rt); } if ((op->oflagp->nocache & 1) && (bytes_of > 0) && out_valid) { if ((lowest_seek < 0) || (op->seek > lowest_seek)) lowest_seek = op->seek; rt = posix_fadvise(op->outfd, (lowest_seek * op->obs), ((op->seek - lowest_seek) * op->obs) + bytes_of, POSIX_FADV_DONTNEED); if (rt) fprintf(stderr, "posix_fadvise on output, seek=%"PRId64" , " "err=%d\n", op->seek, rt); } } #endif /* Main copy loop's read (input) via pt. Returns 0 on success, else see * pt_read()'s return values. */ static int cp_read_pt(struct opts_t * optsp, struct cp_state_t * csp, unsigned char * wrkPos) { int res; int blks_read = 0; res = pt_read(optsp->infd, 0, wrkPos, csp->icbpt, optsp->skip, optsp->ibs, optsp->iflagp, &blks_read); if (res) { if (0 == blks_read) { fprintf(stderr, "pt_read failed,%s at or after lba=%"PRId64" " "[0x%"PRIx64"]\n", ((-2 == res) ? " try reducing bpt," : ""), optsp->skip, optsp->skip); return res; } /* limp on if data, should stop after write; hold err number */ err_to_report = res; } if (blks_read < csp->icbpt) { /* assume close to end, or some data prior to read error */ if (verbose > 1) fprintf(stderr, "short read, requested %d blocks, got " "%d blocks\n", csp->icbpt, blks_read); ++csp->leave_after_write; /* csp->leave_reason = 0; assume at end rather than error */ csp->icbpt = blks_read; /* round down since don't do partial writes from pt reads */ csp->ocbpt = (blks_read * optsp->ibs) / optsp->obs; } in_full += csp->icbpt; return 0; } /* Helper for case when EIO or EREMOTE errno suggests the equivalent * of a medium error. Returns 0 unless coe_limit exceeded. */ int coe_process_eio(int64_t skip) { if ((coe_limit > 0) && (++coe_count > coe_limit)) { fprintf(stderr, ">> coe_limit on consecutive reads " "exceeded\n"); return SG_LIB_CAT_MEDIUM_HARD; } if (highest_unrecovered < 0) { highest_unrecovered = skip; lowest_unrecovered = skip; } else { if (skip < lowest_unrecovered) lowest_unrecovered = skip; if (skip > highest_unrecovered) highest_unrecovered = skip; } ++unrecovered_errs; ++in_partial; --in_full; fprintf(stderr, ">> unrecovered read error at blk=%" PRId64", " "substitute zeros\n", skip); return 0; } /* Error occurred on block/regular read. coe active so assume all full * blocks prior to error are good (if any) and start to read from the * block containing the error, one block at a time, until ibpt. Supply * zeros for unreadable blocks. Return 0 if successful, SG_LIB_CAT_OTHER * if error other than EIO or EREMOTEIO, SG_LIB_FILE_ERROR if lseek fails, * and SG_LIB_CAT_MEDIUM_HARD if the coe_limit is exceeded. */ static int coe_cp_read_block_reg(struct opts_t * optsp, struct cp_state_t * csp, unsigned char * wrkPos, int numread_errno) { int res, res2, k, total_read, num_read; int ibs = optsp->ibs; int64_t offset, off_res, my_skip; if (0 == numread_errno) { csp->icbpt = 0; csp->ocbpt = 0; ++csp->leave_after_write; csp->leave_reason = 0; return 0; /* EOF */ } else if (numread_errno < 0) { if ((-EIO == numread_errno) || (-EREMOTEIO == numread_errno)) { num_read = 0; if (1 == csp->icbpt) { // Don't read again, this must be bad block memset(wrkPos, 0, ibs); if ((res2 = coe_process_eio(optsp->skip))) return res2; ++in_full; csp->bytes_read += ibs; return 0; } } else return SG_LIB_CAT_OTHER; } else num_read = (numread_errno / ibs) * ibs; k = num_read / ibs; if (k > 0) { in_full += k; zero_coe_limit_count(); } csp->bytes_read = num_read; my_skip = optsp->skip + k; offset = my_skip * ibs; wrkPos += num_read; for ( ; k < csp->icbpt; ++k, ++my_skip, wrkPos += ibs, offset += ibs) { if (offset != csp->if_filepos) { if (verbose > 2) fprintf(stderr, "moving if filepos: new_pos=" "%"PRId64"\n", (int64_t)offset); off_res = lseek(optsp->infd, offset, SEEK_SET); if (off_res < 0) { fprintf(stderr, "failed moving if filepos: new_pos=" "%"PRId64"\nlseek on input: %s\n", (int64_t)offset, safe_strerror(errno)); return SG_LIB_FILE_ERROR; } csp->if_filepos = offset; } memset(wrkPos, 0, ibs); while (((res = read(optsp->infd, wrkPos, ibs)) < 0) && (EINTR == errno)) ++interrupted_retries; if (0 == res) { csp->leave_reason = 0; goto short_read; } else if (res < 0) { if ((EIO == errno) || (EREMOTEIO == errno)) { if ((res2 = coe_process_eio(my_skip))) return res2; } else { fprintf(stderr, "reading 1 block, skip=%"PRId64" : %s\n", my_skip, safe_strerror(errno)); csp->leave_reason = SG_LIB_CAT_OTHER; goto short_read; } } else if (res < ibs) { if (verbose) fprintf(stderr, "short read at skip=%"PRId64" , wanted=%d, " "got=%d bytes\n", my_skip, ibs, res); csp->leave_reason = 0; /* assume EOF */ goto short_read; } else { /* if (res == ibs) */ zero_coe_limit_count(); csp->if_filepos += ibs; if (verbose > 2) fprintf(stderr, "reading 1 block, skip=%"PRId64" : okay\n", my_skip); } ++in_full; csp->bytes_read += ibs; } return 0; short_read: total_read = (ibs * k) + ((res > 0) ? res : 0); csp->icbpt = total_read / optsp->ibs; if ((total_read % optsp->ibs) > 0) { ++csp->icbpt; ++in_partial; } csp->ocbpt = total_read / optsp->obs; ++csp->leave_after_write; if (0 == csp->leave_reason) { csp->partial_write_bytes = total_read % optsp->obs; } else { /* if short read (not EOF) implies partial writes, bump obpt */ if ((total_read % optsp->obs) > 0) ++csp->ocbpt; } return 0; } /* Main copy loop's read (input) for block device or regular file. * Returns 0 on success, else SG_LIB_FILE_ERROR, SG_LIB_CAT_MEDIUM_HARD * or -1 . */ static int cp_read_block_reg(struct opts_t * optsp, struct cp_state_t * csp, unsigned char * wrkPos) { int res, res2; int64_t offset = optsp->skip * optsp->ibs; int numbytes = csp->icbpt * optsp->ibs; #ifdef SG_LIB_WIN32 if (FT_BLOCK & optsp->in_type) { int ifull_extra; if ((res = win32_cp_read_block(optsp, csp, wrkPos, &ifull_extra, verbose))) return res; in_full += ifull_extra; return 0; } #endif if (offset != csp->if_filepos) { int64_t off_res; if (verbose > 2) fprintf(stderr, "moving if filepos: new_pos=" "%"PRId64"\n", (int64_t)offset); off_res = lseek(optsp->infd, offset, SEEK_SET); if (off_res < 0) { fprintf(stderr, "failed moving if filepos: new_pos=" "%"PRId64"\nlseek on input: %s\n", (int64_t)offset, safe_strerror(errno)); return SG_LIB_FILE_ERROR; } csp->if_filepos = offset; } while (((res = read(optsp->infd, wrkPos, numbytes)) < 0) && (EINTR == errno)) ++interrupted_retries; if (verbose > 2) fprintf(stderr, "read(unix): requested bytes=%d, res=%d\n", numbytes, res); if ((optsp->iflagp->coe) && (res < numbytes)) { res2 = (res >= 0) ? res : -errno; if ((res < 0) && verbose) { fprintf(stderr, "reading, skip=%"PRId64" : %s, go to coe\n", optsp->skip, safe_strerror(errno)); } else if (verbose) fprintf(stderr, "reading, skip=%"PRId64" : short read, go to " "coe\n", optsp->skip); if (res2 > 0) csp->if_filepos += res2; return coe_cp_read_block_reg(optsp, csp, wrkPos, res2); } if (res < 0) { fprintf(stderr, "reading, skip=%"PRId64" : %s\n", optsp->skip, safe_strerror(errno)); if ((EIO == errno) || (EREMOTEIO == errno)) return SG_LIB_CAT_MEDIUM_HARD; else return SG_LIB_CAT_OTHER; } else if (res < numbytes) { csp->icbpt = res / optsp->ibs; if ((res % optsp->ibs) > 0) { ++csp->icbpt; ++in_partial; --in_full; } csp->ocbpt = res / optsp->obs; ++csp->leave_after_write; csp->leave_reason = 0; /* fall through is assumed EOF */ if (verbose > 1) { if (FT_BLOCK & optsp->in_type) fprintf(stderr, "short read at skip=%"PRId64", requested " "%d blocks, got %d blocks\n", optsp->skip, numbytes / optsp->ibs, csp->icbpt); else fprintf(stderr, "short read, requested %d bytes, got " "%d bytes\n", numbytes, res); } res2 = 0; if ((res >= optsp->ibs) && (res <= (numbytes - optsp->ibs))) { /* Want to check for a EIO lurking */ while (((res2 = read(optsp->infd, wrkPos + res, optsp->ibs)) < 0) && (EINTR == errno)) ++interrupted_retries; if (res2 < 0) { if ((EIO == errno) || (EREMOTEIO == errno)) { csp->leave_reason = SG_LIB_CAT_MEDIUM_HARD; ++unrecovered_errs; } else csp->leave_reason = SG_LIB_CAT_OTHER; if (verbose) fprintf(stderr, "after short read, read at skip=%"PRId64 ": %s\n", optsp->skip + csp->icbpt, safe_strerror(errno)); } else { /* actually expect 0==res2 indicating EOF */ csp->if_filepos += res2; /* could have moved filepos */ if (verbose > 1) fprintf(stderr, "extra read after short read, res=%d\n", res2); } } if (0 == csp->leave_reason) /* if EOF, allow for partial write */ csp->partial_write_bytes = (res + res2) % optsp->obs; else if ((res % optsp->obs) > 0) /* else if extra bytes bump obpt */ ++csp->ocbpt; } csp->if_filepos += res; csp->bytes_read = res; in_full += csp->icbpt; return 0; } /* Main copy loop's write (to of2) for regular file. Returns 0 if success, * else -1 on error. */ static int cp_write_of2(struct opts_t * optsp, struct cp_state_t * csp, unsigned char * wrkPos) { int res, off, part; int numbytes = (csp->ocbpt * optsp->obs) + csp->partial_write_bytes; // write to fifo (reg file ?) is non-atomic so loop if making progress off = 0; part = 0; do { while (((res = write(optsp->out2fd, wrkPos + off, numbytes - off)) < 0) && (EINTR == errno)) ++interrupted_retries; if ((res > 0) && (res < (numbytes - off))) ++part; } while ((FT_FIFO & optsp->out2_type) && (res > 0) && ((off += res) < numbytes)); if (off >= numbytes) { res = numbytes; if (part && verbose) fprintf(stderr, "write to of2 splintered\n"); } else if (off > 0) fprintf(stderr, "write to of2 fifo problem: count=%d, off=%d, " "res=%d\n", numbytes, off, res); if ((verbose > 2) && (0 == off)) fprintf(stderr, "write to of2: count=%d, res=%d\n", numbytes, res); if (res < 0) { fprintf(stderr, "writing to of2, seek=%"PRId64" : %s\n", optsp->seek, safe_strerror(errno)); return -1; } csp->bytes_of2 = res; return 0; } /* Main copy loop's read (output (of)) via pt. Returns 0 on success, else * see pt_read()'s return values. */ static int cp_read_of_pt(struct opts_t * optsp, struct cp_state_t * csp, unsigned char * wrkPos2) { int res, blks_read; res = pt_read(optsp->outfd, 1, wrkPos2, csp->ocbpt, optsp->seek, optsp->obs, optsp->oflagp, &blks_read); if (res) { fprintf(stderr, "pt_read(sparing) failed, at or after " "lba=%"PRId64" [0x%"PRIx64"]\n", optsp->seek, optsp->seek); return res; } else if (blks_read != csp->ocbpt) return 1; return 0; } /* Main copy loop's read (output (of)) for block device or regular file. * Returns 0 on success, else SG_LIB_FILE_ERROR, SG_LIB_CAT_MEDIUM_HARD * or -1 . */ static int cp_read_of_block_reg(struct opts_t * optsp, struct cp_state_t * csp, unsigned char * wrkPos2) { int res; int64_t offset = optsp->seek * optsp->obs; int numbytes = csp->ocbpt * optsp->obs; #ifdef SG_LIB_WIN32 if (FT_BLOCK & optsp->out_type) { if (offset != csp->of_filepos) { if (verbose > 2) fprintf(stderr, "moving of filepos: new_pos=" "%"PRId64"\n", (int64_t)offset); if (win32_set_file_pos(optsp, DDPT_ARG_OUT, offset, verbose)) return SG_LIB_FILE_ERROR; csp->of_filepos = offset; } res = win32_block_read_from_of(optsp, wrkPos2, numbytes, verbose); if (verbose > 2) fprintf(stderr, "read(sparing): requested bytes=%d, res=%d\n", numbytes, res); if (res < 0) { fprintf(stderr, "read(sparing), seek=%"PRId64"\n", optsp->seek); return (-SG_LIB_CAT_MEDIUM_HARD == res) ? -res : -1; } else if (res == numbytes) { csp->of_filepos += numbytes; return 0; } else { if (verbose > 2) fprintf(stderr, "short read\n"); return -1; } } else #endif { if (offset != csp->of_filepos) { int64_t off_res; if (verbose > 2) fprintf(stderr, "moving of filepos: new_pos=" "%"PRId64"\n", (int64_t)offset); off_res = lseek(optsp->outfd, offset, SEEK_SET); if (off_res < 0) { fprintf(stderr, "failed moving of filepos: new_pos=" "%"PRId64"\nlseek on output: %s\n", (int64_t)offset, safe_strerror(errno)); return SG_LIB_FILE_ERROR; } csp->of_filepos = offset; } if (csp->partial_write_bytes > 0) { numbytes += csp->partial_write_bytes; if (verbose) fprintf(stderr, "read(sparing): %d bytes extra to fetch " "due to partial read\n", csp->partial_write_bytes); } while (((res = read(optsp->outfd, wrkPos2, numbytes)) < 0) && (EINTR == errno)) ++interrupted_retries; if (verbose > 2) fprintf(stderr, "read(sparing): requested bytes=%d, res=%d\n", numbytes, res); if (res < 0) { fprintf(stderr, "read(sparing), seek=%"PRId64" : %s\n", optsp->seek, safe_strerror(errno)); return -1; } else if (res == numbytes) { csp->of_filepos += numbytes; return 0; } else { if (verbose > 2) fprintf(stderr, "short read\n"); return 1; } } } /* Main copy loop's write (output (of)) via pt. Returns 0 on success, else * see pt_write()'s return values. */ static int cp_write_pt(struct opts_t * optsp, struct cp_state_t * csp, int seek_delta, int blks, unsigned char * wrkPos) { int res; int64_t aseek = optsp->seek + seek_delta; if (optsp->oflagp->nowrite) return 0; if (csp->partial_write_bytes > 0) fprintf(stderr, ">>> ignore partial write of %d bytes to pt device\n", csp->partial_write_bytes); res = pt_write(optsp->outfd, wrkPos, blks, aseek, optsp->obs, optsp->oflagp); if (0 != res) { fprintf(stderr, "pt_write failed,%s seek=%"PRId64"\n", ((-2 == res) ? " try reducing bpt," : ""), aseek); return res; } else out_full += blks; return 0; } /* Main copy loop's write (output (of)) for block device or regular file. * Returns 0 on success, else SG_LIB_FILE_ERROR, SG_LIB_CAT_MEDIUM_HARD * or -1 . */ static int cp_write_block_reg(struct opts_t * optsp, struct cp_state_t * csp, int seek_delta, int blks, unsigned char * wrkPos) { int res, off, part; int numbytes = blks * optsp->obs; int64_t offset; int64_t aseek = optsp->seek + seek_delta; if (optsp->oflagp->nowrite) return 0; offset = aseek * optsp->obs; #ifdef SG_LIB_WIN32 if (FT_BLOCK & optsp->out_type) { if (csp->partial_write_bytes > 0) fprintf(stderr, ">>> ignore partial write of %d bytes to block " "device\n", csp->partial_write_bytes); if (offset != csp->of_filepos) { if (verbose > 2) fprintf(stderr, "moving of filepos: new_pos=" "%"PRId64"\n", (int64_t)offset); if (win32_set_file_pos(optsp, DDPT_ARG_OUT, offset, verbose)) return SG_LIB_FILE_ERROR; csp->of_filepos = offset; } res = win32_block_write(optsp, wrkPos, numbytes, verbose); if (res < 0) { fprintf(stderr, "write(win32_block, seek=%"PRId64" ", aseek); return (-SG_LIB_CAT_MEDIUM_HARD == res) ? -res : -1; } else if (res < numbytes) { fprintf(stderr, "output file probably full, seek=%"PRId64" ", aseek); out_full += res / optsp->obs; /* can get a partial write due to a short write */ if ((res % optsp->obs) > 0) { ++out_partial; ++out_full; } return -1; } else { csp->of_filepos += numbytes; csp->bytes_of = numbytes; out_full += blks; } return 0; } else #endif { if (csp->partial_write_bytes > 0) { if (FT_BLOCK & optsp->out_type) fprintf(stderr, ">>> ignore partial write of %d bytes to " "block device\n", csp->partial_write_bytes); else { numbytes += csp->partial_write_bytes; ++out_partial; ++out_full; } } if (offset != csp->of_filepos) { int64_t off_res; if (verbose > 2) fprintf(stderr, "moving of filepos: new_pos=" "%"PRId64"\n", (int64_t)offset); off_res = lseek(optsp->outfd, offset, SEEK_SET); if (off_res < 0) { fprintf(stderr, "failed moving of filepos: new_pos=" "%"PRId64"\nlseek on output: %s\n", (int64_t)offset, safe_strerror(errno)); return SG_LIB_FILE_ERROR; } csp->of_filepos = offset; } // write to fifo (reg file ?) is non-atomic so loop if making progress off = 0; part = 0; do { while (((res = write(optsp->outfd, wrkPos + off, numbytes - off)) < 0) && (EINTR == errno)) ++interrupted_retries; if ((res > 0) && (res < (numbytes - off))) ++part; } while ((FT_FIFO & optsp->out_type) && (res > 0) && ((off += res) < numbytes)); if (off >= numbytes) { res = numbytes; if (part && verbose) fprintf(stderr, "write to output file splintered\n"); } else if (off > 0) fprintf(stderr, "write to of fifo problem: count=%d, off=%d, " "res=%d\n", numbytes, off, res); if ((verbose > 2) && (0 == off)) fprintf(stderr, "write(unix): requested bytes=%d, res=%d\n", numbytes, res); if (res < 0) { fprintf(stderr, "writing, seek=%"PRId64" : %s\n", aseek, safe_strerror(errno)); return -1; } else if (res < numbytes) { fprintf(stderr, "output file probably full, seek=%"PRId64"\n", aseek); out_full += res / optsp->obs; /* can get a partial write due to a short write */ if ((res % optsp->obs) > 0) { ++out_partial; ++out_full; } return -1; } else { /* successful write */ csp->of_filepos += numbytes; csp->bytes_of = numbytes; out_full += blks; } return 0; } } /* Only for regular OFILE. Check what to do if last blocks where * not written, may require OFILE length adjustment */ static void cp_sparse_cleanup(struct opts_t * optsp, struct cp_state_t * csp) { int64_t offset = optsp->seek * optsp->obs; struct stat a_st; if (offset > csp->of_filepos) { if ((0 == optsp->oflagp->strunc) && (optsp->oflagp->sparse > 1)) { if (verbose > 1) fprintf(stderr, "asked to bypass writing sparse last block " "zeros\n"); return; } if (fstat(optsp->outfd, &a_st) < 0) { fprintf(stderr, "cp_sparse_cleanup: fstat: %s\n", safe_strerror(errno)); return; } if (offset == a_st.st_size) { if (verbose > 1) fprintf(stderr, "cp_sparse_cleanup: OFILE already " "correct length\n"); return; } if (offset < a_st.st_size) { if (verbose > 1) fprintf(stderr, "cp_sparse_cleanup: OFILE longer " "than required, do nothing\n"); return; } if (optsp->oflagp->strunc) { if (verbose > 1) fprintf(stderr, "About to truncate %s to byte offset " "%"PRId64"\n", optsp->outf, offset); if (ftruncate(optsp->outfd, offset) < 0) { fprintf(stderr, "could not ftruncate after copy: %s\n", safe_strerror(errno)); return; } /* N.B. file offset (pointer) not changed by ftruncate */ } else if (1 == optsp->oflagp->sparse) { if (verbose > 1) fprintf(stderr, "writing sparse last block zeros\n"); if (cp_write_block_reg(optsp, csp, -1, 1, zeros_buff) < 0) fprintf(stderr, "writing sparse last block zeros " "error, seek=%"PRId64"\n", optsp->seek - 1); else --out_sparse; } } } /* Main copy loop's finer grain comparison and possible write (to output * (of)) for all file types. Returns 0 on success. */ static int cp_finer_comp_wr(struct opts_t * optsp, struct cp_state_t * csp, unsigned char * b1p, unsigned char * b2p) { int res, k, n, oblks, numbytes, chunk, need_wr, wr_len, wr_k, obs; int trim_check, need_tr, tr_len, tr_k; oblks = csp->ocbpt; obs = optsp->obs; if (optsp->obpc >= oblks) { if (FT_DEV_NULL & optsp->out_type) ; else if (FT_PT & optsp->out_type) { if ((res = cp_write_pt(optsp, csp, 0, oblks, b1p))) return res; } else if ((res = cp_write_block_reg(optsp, csp, 0, oblks, b1p))) return res; return 0; } numbytes = oblks * obs; if ((FT_REG & optsp->out_type) && (csp->partial_write_bytes > 0)) numbytes += csp->partial_write_bytes; chunk = optsp->obpc * obs; trim_check = (optsp->oflagp->sparse && optsp->oflagp->wsame16 && (FT_PT & optsp->out_type)); need_tr = 0; tr_len = 0; tr_k = 0; for (k = 0, need_wr = 0, wr_len = 0, wr_k = 0; k < numbytes; k += chunk) { n = ((k + chunk) < numbytes) ? chunk : (numbytes - k); if (0 == memcmp(b1p + k, b2p + k, n)) { if (need_wr) { if (FT_DEV_NULL & optsp->out_type) ; else if (FT_PT & optsp->out_type) { if ((res = cp_write_pt(optsp, csp, wr_k / obs, wr_len / obs, b1p + wr_k))) return res; } else if ((res = cp_write_block_reg(optsp, csp, wr_k / obs, wr_len / obs, b1p + wr_k))) return res; need_wr = 0; } if (need_tr) tr_len += n; else if (trim_check) { need_tr = 1; tr_len = n; tr_k = k; } out_sparse += (n / obs); } else { /* look for a sequence of unequals */ if (need_wr) wr_len += n; else { need_wr = 1; wr_len = n; wr_k = k; } if (need_tr) { res = pt_write_same16(optsp->outfd, 1, b2p, obs, tr_len / obs, optsp->seek + (tr_k / obs)); if (res) ++trim_errs; /* continue past trim errors */ need_tr = 0; } } } if (need_wr) { if (FT_DEV_NULL & optsp->out_type) ; else if (FT_PT & optsp->out_type) { if ((res = cp_write_pt(optsp, csp, wr_k / obs, wr_len / obs, b1p + wr_k))) return res; } else if ((res = cp_write_block_reg(optsp, csp, wr_k / obs, wr_len / obs, b1p + wr_k))) return res; } if (need_tr) { res = pt_write_same16(optsp->outfd, 1, b2p, obs, tr_len / obs, optsp->seek + (tr_k / obs)); if (res) ++trim_errs; /* continue past trim errors */ } return 0; } static int cp_construct_pt_zero_buff(struct opts_t * optsp, int obpt) { if ((FT_PT & optsp->in_type) && (NULL == if_ptvp)) { if_ptvp = construct_scsi_pt_obj(); if (NULL == if_ptvp) { fprintf(stderr, "if construct_scsi_pt_obj: out of memory\n"); return -1; } } if ((FT_PT & optsp->out_type) && (NULL == of_ptvp)) { of_ptvp = construct_scsi_pt_obj(); if (NULL == of_ptvp) { fprintf(stderr, "of construct_scsi_pt_obj: out of memory\n"); return -1; } } if ((optsp->oflagp->sparse) && (NULL == zeros_buff)) { zeros_buff = (unsigned char *)calloc(obpt * optsp->obs, 1); if (NULL == zeros_buff) { fprintf(stderr, "zeros_buff calloc failed\n"); return -1; } } return 0; } static void cp_destruct_pt(void) { if (if_ptvp) { destruct_scsi_pt_obj(if_ptvp); if_ptvp = NULL; } if (of_ptvp) { destruct_scsi_pt_obj(of_ptvp); of_ptvp = NULL; } } /* Look at IFILE and OFILE lengths and blocks sizes. If dd_count * not given, try to deduce a value for it. If oflag=resume do skip, * seek, dd_count adjustments. Returns 0 to start copy, otherwise * bypass copy and exit */ static int count_calculate(struct opts_t * op) { int64_t in_num_sect = -1; int64_t out_num_sect = -1; int64_t ibytes, obytes, ibk; int valid_resume = 0; int in_sect_sz, out_sect_sz, res; if ((res = calc_count(op, &in_num_sect, &in_sect_sz, &out_num_sect, &out_sect_sz))) return res; if ((0 == op->oflagp->resume) && (dd_count > 0)) return 0; if (verbose > 2) fprintf(stderr, "calc_count: in_num_sect=%"PRId64", out_num_sect" "=%"PRId64"\n", in_num_sect, out_num_sect); if (op->skip && (FT_REG == op->in_type) && (op->skip > in_num_sect)) { fprintf(stderr, "cannot skip to specified offset on %s\n", op->inf); dd_count = 0; return -1; } if (op->oflagp->resume) { if (FT_REG == op->out_type) { if (out_num_sect < 0) fprintf(stderr, "resume cannot determine size of OFILE, " "ignore\n"); else valid_resume = 1; } else fprintf(stderr, "resume expects OFILE to be regular, ignore\n"); } if ((dd_count < 0) && (! valid_resume)) { /* Scale back in_num_sect by value of skip */ if (op->skip && (in_num_sect > op->skip)) in_num_sect -= op->skip; /* Scale back out_num_sect by value of seek */ if (op->seek && (out_num_sect > op->seek)) out_num_sect -= op->seek; if ((out_num_sect < 0) && (in_num_sect > 0)) dd_count = in_num_sect; else if (reading_fifo) ; else if ((out_num_sect < 0) && (in_num_sect <= 0)) ; else { ibytes = (in_num_sect > 0) ? (op->ibs * in_num_sect) : 0; obytes = op->obs * out_num_sect; if (0 == ibytes) dd_count = obytes / op->ibs; else if ((ibytes > obytes) && (FT_REG != op->out_type)) { dd_count = obytes / op->ibs; } else dd_count = in_num_sect; } } if (valid_resume) { if (dd_count < 0) dd_count = in_num_sect - op->skip; if (out_num_sect <= op->seek) fprintf(stderr, "resume finds no previous copy, restarting\n"); else { obytes = op->obs * (out_num_sect - op->seek); ibk = obytes / op->ibs; if (ibk >= dd_count) { fprintf(stderr, "resume finds copy complete, exiting\n"); dd_count = 0; return -1; } /* align to bpt multiple */ ibk = (ibk / op->bpt_i) * op->bpt_i; op->skip += ibk; op->seek += (ibk * op->ibs) / op->obs; dd_count -= ibk; fprintf(stderr, "resume adjusting skip=%"PRId64", seek=%" PRId64", and count=%"PRId64"\n", op->skip, op->seek, dd_count); } } return 0; } /* This is the main copy loop. Attempts to copy 'dd_count' (a static) * blocks (size given by bs or ibs) in chunks of optsp->bpt_i blocks. * Returns 0 if successful. */ static int do_copy(struct opts_t * optsp, unsigned char * wrkPos, unsigned char * wrkPos2) { int ibpt, obpt, res, n, sparse_skip, sparing_skip, continual_read; int ret = 0; int out_type = optsp->out_type; struct cp_state_t cp_st; struct cp_state_t * csp; if ((dd_count <= 0) && (! reading_fifo)) return 0; continual_read = reading_fifo && (dd_count < 0); csp = &cp_st; memset(csp, 0, sizeof(struct cp_state_t)); ibpt = optsp->bpt_i; obpt = (optsp->ibs * optsp->bpt_i) / optsp->obs; if ((ret = cp_construct_pt_zero_buff(optsp, obpt))) goto copy_end; /* Both csp->if_filepos and csp->of_filepos are 0 */ /* <<< main loop that does the copy >>> */ while ((dd_count > 0) || continual_read) { csp->bytes_read = 0; csp->bytes_of = 0; csp->bytes_of2 = 0; sparing_skip = 0; sparse_skip = 0; if ((dd_count >= ibpt) || continual_read) { csp->icbpt = ibpt; csp->ocbpt = obpt; } else { csp->icbpt = dd_count; res = dd_count; n = res * optsp->ibs; csp->ocbpt = n / optsp->obs; if (n % optsp->obs) { ++csp->ocbpt; memset(wrkPos, 0, optsp->ibs * ibpt); } } /* Start of reading section */ if (FT_PT & optsp->in_type) { if ((ret = cp_read_pt(optsp, csp, wrkPos))) break; } else { if ((ret = cp_read_block_reg(optsp, csp, wrkPos))) break; } if (0 == csp->icbpt) break; /* nothing read so leave loop */ if ((optsp->out2fd >= 0) && ((ret = cp_write_of2(optsp, csp, wrkPos)))) break; if (optsp->oflagp->sparse) { n = (csp->ocbpt * optsp->obs) + csp->partial_write_bytes; if (0 == memcmp(wrkPos, zeros_buff, n)) { sparse_skip = 1; if (optsp->oflagp->wsame16 && (FT_PT & out_type)) { res = pt_write_same16(optsp->outfd, 1, zeros_buff, optsp->obs, csp->ocbpt, optsp->seek); if (res) ++trim_errs; } } else if (optsp->obpc) { ret = cp_finer_comp_wr(optsp, csp, wrkPos, zeros_buff); if (ret) break; goto bypass_write; } } if (optsp->oflagp->sparing && (! sparse_skip)) { /* In write sparing, we read from the output */ if (FT_PT & out_type) res = cp_read_of_pt(optsp, csp, wrkPos2); else res = cp_read_of_block_reg(optsp, csp, wrkPos2); if (0 == res) { n = (csp->ocbpt * optsp->obs) + csp->partial_write_bytes; if (0 == memcmp(wrkPos, wrkPos2, n)) sparing_skip = 1; else if (optsp->obpc) { ret = cp_finer_comp_wr(optsp, csp, wrkPos, wrkPos2); if (ret) break; goto bypass_write; } } else { ret = res; break; } } /* Start of writing section */ if (sparing_skip || sparse_skip) { out_sparse += csp->ocbpt; if (csp->partial_write_bytes > 0) ++out_sparse_partial; } else { if (FT_PT & out_type) { if ((ret = cp_write_pt(optsp, csp, 0, csp->ocbpt, wrkPos))) break; } else if (FT_DEV_NULL & out_type) ; /* don't bump out_full (earlier revs did) */ else if ((ret = cp_write_block_reg(optsp, csp, 0, csp->ocbpt, wrkPos))) break; } bypass_write: #ifdef HAVE_POSIX_FADVISE do_fadvise(optsp, csp->bytes_read, csp->bytes_of, csp->bytes_of2); #endif if (dd_count > 0) dd_count -= csp->icbpt; optsp->skip += csp->icbpt; optsp->seek += csp->ocbpt; if (csp->leave_after_write) { ret = csp->leave_reason; break; } } /* end of main loop that does the copy ... */ /* sparse: clean up ofile length when last block(s) were not written */ if ((FT_REG & out_type) && (0 == optsp->oflagp->nowrite) && optsp->oflagp->sparse) cp_sparse_cleanup(optsp, csp); if ((FT_PT & out_type) || (FT_DEV_NULL & out_type) || (FT_FIFO & out_type) || (FT_CHAR & out_type)) { ; // negating things makes it less clear ... } #ifdef HAVE_FDATASYNC else if (optsp->oflagp->fdatasync) { if (fdatasync(optsp->outfd) < 0) perror("fdatasync() error"); if (verbose) fprintf(stderr, "Called fdatasync() on %s successfully\n", optsp->outf); } #endif #ifdef HAVE_FSYNC else if (optsp->oflagp->fsync) { if (fsync(optsp->outfd) < 0) perror("fsync() error"); if (verbose) fprintf(stderr, "Called fsync() on %s successfully\n", optsp->outf); } #endif copy_end: cp_destruct_pt(); return ret; } int main(int argc, char * argv[]) { int res, fd; unsigned char * wrkBuff = NULL; unsigned char * wrkPos; unsigned char * wrkBuff2 = NULL; unsigned char * wrkPos2 = NULL; int ret = 0; int started_copy = 0; struct opts_t opts; struct flags_t iflag; struct flags_t oflag; memset(&opts, 0, sizeof(opts)); opts.bpt_i = DEF_BPT_LT1024; opts.out_type = FT_OTHER; opts.in_type = FT_OTHER; memset(&iflag, 0, sizeof(iflag)); memset(&oflag, 0, sizeof(oflag)); opts.iflagp = &iflag; opts.oflagp = &oflag; opts.infd = -1; opts.outfd = -1; opts.out2fd = -1; iflag.cdbsz = DEF_SCSI_CDBSZ; oflag.cdbsz = DEF_SCSI_CDBSZ; res = process_cl(&opts, argc, argv); if (res < 0) return 0; else if (res > 0) return res; #ifdef SG_LIB_WIN32 if (wscan) return sg_do_wscan('\0', wscan, verbose); #endif // Seems to work in Windows if (quiet) { if (NULL == freopen("/dev/null", "w", stderr)) fprintf(stderr, "freopen: failed to redirect stderr to " "/dev/null : %s\n", safe_strerror(errno)); } register_handler(SIGINT, interrupt_handler); register_handler(SIGQUIT, interrupt_handler); register_handler(SIGPIPE, interrupt_handler); register_handler(SIGUSR1, siginfo_handler); #ifdef SIGINFO #ifdef SIGUSR1 if (SIGUSR1 != SIGINFO) register_handler(SIGINFO, siginfo_handler); #else register_handler(SIGINFO, siginfo_handler); #endif #endif #ifdef SG_LIB_WIN32 win32_adjust_fns(&opts); #ifdef SG_LIB_WIN32_DIRECT if (verbose > 4) fprintf(stderr, "Initial win32 SPT interface state: %s\n", scsi_pt_win32_spt_state() ? "direct" : "indirect"); scsi_pt_win32_direct(SG_LIB_WIN32_DIRECT /* SPT pt interface */); #endif #endif opts.iflagp->pdt = -1; opts.oflagp->pdt = -1; if (opts.inf[0]) { if (('-' == opts.inf[0]) && ('\0' == opts.inf[1])) { fd = STDIN_FILENO; opts.in_type = FT_FIFO; ++reading_fifo; if (verbose) fprintf(stderr, " >> Input file type: fifo [stdin, stdout, " "named pipe]\n"); } else { fd = open_if(&opts, verbose); if (fd < 0) return -fd; } opts.infd = fd; } else { fprintf(stderr, "'if=IFILE' option must be given. For stdin as " "input use 'if=-'\n"); fprintf(stderr, "For more information use '--help'\n"); return SG_LIB_SYNTAX_ERROR; } if ('\0' == opts.outf[0]) strcpy(opts.outf, "."); /* treat no 'of=OFILE' option as /dev/null */ if (('-' == opts.outf[0]) && ('\0' == opts.outf[1])) { fd = STDOUT_FILENO; opts.out_type = FT_FIFO; out_type_hold = opts.out_type; if (verbose) fprintf(stderr, " >> Output file type: fifo [stdin, stdout, " "named pipe]\n"); } else { fd = open_of(&opts, verbose); if (fd < -1) return -fd; } opts.outfd = fd; if (opts.out2f[0]) { if (('-' == opts.out2f[0]) && ('\0' == opts.out2f[1])) { fd = STDOUT_FILENO; opts.out2_type = FT_FIFO; if (verbose) fprintf(stderr, " >> Output 2 file type: fifo [stdin, " "stdout, named pipe]\n"); } else { opts.out2_type = dd_filetype(opts.out2f); if (FT_DEV_NULL & opts.out2_type) fd = -1; else if (! ((FT_REG & opts.out2_type) || (FT_FIFO & opts.out2_type))) { fprintf(stderr, "Error: output 2 file type must be regular " "file or fifo\n"); return SG_LIB_FILE_ERROR; } else { if ((fd = open(opts.out2f, O_WRONLY | O_CREAT, 0666)) < 0) { res = errno; fprintf(stderr, "could not open %s for writing: %s\n", opts.out2f, safe_strerror(errno)); return res; } if (sg_set_binary_mode(fd) < 0) perror("sg_set_binary_mode"); if (verbose) fprintf(stderr, " >> Output 2 file type: regular\n"); } } } else fd = -1; opts.out2fd = fd; if (opts.iflagp->sparse && (! opts.oflagp->sparse)) { if (FT_DEV_NULL & opts.out_type) { fprintf(stderr, "sparse flag usually ignored on input; set it " "on output in this case\n"); ++opts.oflagp->sparse; } else fprintf(stderr, "sparse flag ignored on input\n"); } if (oflag.sparse) { if (FT_FIFO & opts.out_type) { fprintf(stderr, "oflag=sparse needs seekable output file, " "ignore\n"); oflag.sparse = 0; } else { out_sparse_active = 1; if (oflag.wsame16) out_trim_active = 1; } } if (oflag.sparing) { if ((FT_DEV_NULL & opts.out_type) || (FT_FIFO & opts.out_type)) { fprintf(stderr, "oflag=sparing needs a readable and seekable " "output file, ignore\n"); oflag.sparing = 0; } else out_sparing_active = 1; } if ((ret = count_calculate(&opts))) goto cleanup; if ((dd_count < 0) && (! reading_fifo)) { fprintf(stderr, "Couldn't calculate count, please give one\n"); return SG_LIB_CAT_OTHER; } if (! opts.cdbsz_given) { if ((FT_PT & opts.in_type) && (MAX_SCSI_CDBSZ != opts.iflagp->cdbsz) && (((dd_count + opts.skip) > UINT_MAX) || (opts.bpt_i > USHRT_MAX))) { if (verbose > 0) fprintf(stderr, "SCSI command size increased from 10 to 16 " "bytes on %s\n", opts.inf); opts.iflagp->cdbsz = MAX_SCSI_CDBSZ; } if ((FT_PT & opts.out_type) && (MAX_SCSI_CDBSZ != opts.oflagp->cdbsz) && (((dd_count + opts.seek) > UINT_MAX) || (((opts.ibs * opts.bpt_i) / opts.obs) > USHRT_MAX))) { if (verbose) fprintf(stderr, "SCSI command size increased from 12 to 16 " "bytes on %s\n", opts.outf); opts.oflagp->cdbsz = MAX_SCSI_CDBSZ; } } if (opts.iflagp->direct || opts.oflagp->direct) { size_t psz; #ifdef SG_LIB_MINGW psz = getpagesize(); // implicit definition but links okay #else psz = sysconf(_SC_PAGESIZE); /* was getpagesize() */ #endif wrkBuff = (unsigned char*)calloc(opts.ibs * opts.bpt_i + psz, 1); if (0 == wrkBuff) { fprintf(stderr, "Not enough user memory for aligned usage\n"); return SG_LIB_CAT_OTHER; } // posix_memalign() could be a better way to do this wrkPos = (unsigned char *)(((unsigned long)wrkBuff + psz - 1) & (~(psz - 1))); if (opts.oflagp->sparing) { wrkBuff2 = (unsigned char*)calloc(opts.ibs * opts.bpt_i + psz, 1); if (0 == wrkBuff2) { fprintf(stderr, "Not enough user memory for aligned " "usage(2)\n"); return SG_LIB_CAT_OTHER; } wrkPos2 = (unsigned char *)(((unsigned long)wrkBuff2 + psz - 1) & (~(psz - 1))); } } else { wrkBuff = (unsigned char*)calloc(opts.ibs * opts.bpt_i, 1); if (0 == wrkBuff) { fprintf(stderr, "Not enough user memory\n"); return SG_LIB_CAT_OTHER; } wrkPos = wrkBuff; if (opts.oflagp->sparing) { wrkBuff2 = (unsigned char*)calloc(opts.ibs * opts.bpt_i, 1); if (0 == wrkBuff2) { fprintf(stderr, "Not enough user memory(2)\n"); return SG_LIB_CAT_OTHER; } wrkPos2 = wrkBuff2; } } if (verbose) { fprintf(stderr, "skip=%"PRId64" (blocks on input), seek=%"PRId64" " "(blocks on output)\n", opts.skip, opts.seek); if (verbose > 1) fprintf(stderr, " ibs=%d bytes, obs=%d bytes, OBPC=%d\n", opts.ibs, opts.obs, opts.obpc); fprintf(stderr, " initial count=%"PRId64" (blocks of input), " "blocks_per_transfer=%d\n", dd_count, opts.bpt_i); } read1_or_transfer = !! (FT_DEV_NULL & opts.out_type); if (read1_or_transfer && (! opts.outf_given) && ((dd_count > 0) || reading_fifo)) fprintf(stderr, "Output file not specified so no copy, just " "reading input\n"); #if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC) if (do_time) { start_tm.tv_sec = 0; start_tm.tv_nsec = 0; if (0 == clock_gettime(CLOCK_MONOTONIC, &start_tm)) start_tm_valid = 1; } #elif defined(HAVE_GETTIMEOFDAY) if (do_time) { start_tm.tv_sec = 0; start_tm.tv_usec = 0; gettimeofday(&start_tm, NULL); start_tm_valid = 1; } #endif #ifdef ERRBLK_SUPPORTED if (opts.iflagp->errblk) open_errblk(); #endif // <<<<<<<<<<<<<< finally ready to do copy ++started_copy; ret = do_copy(&opts, wrkPos, wrkPos2); #ifdef ERRBLK_SUPPORTED if (opts.iflagp->errblk) close_errblk(); #endif print_stats(""); if (sum_of_resids) fprintf(stderr, ">> Non-zero sum of residual counts=%d\n", sum_of_resids); if (do_time) calc_duration_throughput("", 0); if ((opts.oflagp->ssync) && (FT_PT & opts.out_type)) { fprintf(stderr, ">> SCSI synchronizing cache on %s\n", opts.outf); res = sg_ll_sync_cache_10(opts.outfd, 0, 0, 0, 0, 0, 0, 0); if (SG_LIB_CAT_UNIT_ATTENTION == res) { fprintf(stderr, "Unit attention (out, sync cache), " "continuing\n"); res = sg_ll_sync_cache_10(opts.outfd, 0, 0, 0, 0, 0, 0, 0); } if (0 != res) fprintf(stderr, "Unable to do SCSI synchronize cache\n"); } cleanup: if (wrkBuff) free(wrkBuff); if (wrkBuff2) free(wrkBuff2); if (zeros_buff) free(zeros_buff); if (FT_PT & opts.in_type) scsi_pt_close_device(opts.infd); else if ((opts.infd >= 0) && (STDIN_FILENO != opts.infd)) close(opts.infd); if (FT_PT & opts.out_type) scsi_pt_close_device(opts.outfd); if ((opts.outfd >= 0) && (STDOUT_FILENO != opts.outfd) && !(FT_DEV_NULL & opts.out_type)) close(opts.outfd); if ((opts.out2fd >= 0) && (STDOUT_FILENO != opts.out2fd)) close(opts.out2fd); if ((0 == ret) && err_to_report) ret = err_to_report; if (started_copy && (0 != dd_count) && (! reading_fifo)) { if (0 == ret) fprintf(stderr, "Early termination, EOF on input?\n"); else if (3 == ret) fprintf(stderr, "Early termination, medium error occurred\n"); else fprintf(stderr, "Early termination, some error occurred\n"); } return (ret >= 0) ? ret : SG_LIB_CAT_OTHER; } ddpt-0.92/src/ddpt_win32.c0000644000175000017500000004465711527062131014321 0ustar douggdougg/* * Copyright (c) 2010-2011 Douglas Gilbert. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */ /* This is a C source file contains Windows specific code for the ddpt * utility. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef SG_LIB_WIN32 #include #include #include #include #include #include #include #include #include #include #include #define __STDC_FORMAT_MACROS 1 #include #include #include #include #include "ddpt.h" #include #include #ifndef SG_LIB_MINGW /* cygwin */ #include #endif #include "sg_lib.h" #include "sg_cmds_basic.h" #include "sg_cmds_extra.h" #include "sg_pt.h" /* Fetches system error message corresponding to errnum, * placing string in b not exceeding blen bytes. Returns * bytes placed in b (excluding trailing NULL) or -1 for * error. */ static int win32_errmsg(int errnum, char * b, int blen) { LPTSTR err_txt = 0; DWORD errn = errnum; int len = 0; if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, errn, 0, (LPTSTR)&err_txt, 0, NULL) == 0) return -1; else { len = strlen(err_txt); if (len) { if ('\n' == err_txt[len - 1]) { err_txt[len - 1] = '\0'; if ((len > 1) && ('\r' == err_txt[len - 2])) err_txt[len - 2] = '\0'; len = strlen(err_txt); } } if (len < 1) b[0] = '\0'; else if (len < blen) strcpy(b, err_txt); else { strncpy(b, err_txt, blen); if (blen > 0) b[blen - 1] = '\0'; } } if (err_txt) LocalFree(err_txt); return len; } /* Return 1 for filenames starting with '\', or of the form ':' * or of the form PD, PHYSICALDRIVE, CDROM or TAPE. The * is one or two digits with no following characters. Otherwise return 0. */ static int is_win_blk_dev(const char * fn) { int len, off; len = strlen(fn); if ((2 == len) && isalpha((int)fn[0]) && (':' == fn[1])) return 1; if (len < 3) return 0; if ('\\' == fn[0]) return 1; if (0 == strncmp(fn, "PD", 2)) off = 2; else if (0 == strncmp(fn, "CDROM", 5)) off = 5; else if (0 == strncmp(fn, "PHYSICALDRIVE", 13)) off = 13; else if (0 == strncmp(fn, "TAPE", 4)) off = 4; else return 0; if (len <= off) return 0; if (! isdigit((int)fn[off])) return 0; if (len == (off + 1)) return 1; if ((len != off + 2) || (! isdigit((int)fn[off + 1]))) return 0; else return 1; } int dd_filetype(const char * fn) { size_t len = strlen(fn); if ((1 == len) && ('.' == fn[0])) return FT_DEV_NULL; else if ((3 == len) && ( (0 == strcmp("NUL", fn)) || (0 == strcmp("nul", fn)))) return FT_DEV_NULL; else if ((len > 8) && (0 == strncmp("\\\\.\\TAPE", fn, 8))) return FT_TAPE; else if ((len > 4) && (0 == strncmp("\\\\.\\", fn, 4))) return FT_BLOCK; else return FT_REG; } /* Adjust device file name for Windows */ void win32_adjust_fns(struct opts_t * optsp) { char b[INOUTF_SZ]; char * fn_arr[2]; char * cp; int k, j, len; memset(fn_arr, 0 , sizeof(fn_arr)); fn_arr[0] = optsp->inf; fn_arr[1] = optsp->outf; for (k = 0; k < 2; ++k) { cp = fn_arr[k]; if (NULL == cp) continue; len = strlen(cp); if (len < 2) continue; if ('\\' == cp[0]) continue; for (j = 0; j < len; ++j) b[j] = toupper((int)cp[j]); b[len] = '\0'; if (is_win_blk_dev(b)) { if (0 == strncmp(b, "PD", 2)) { strcpy(cp, "\\\\.\\PHYSICALDRIVE"); if (b[2]) strncat(cp, b + 2, len - 2); } else { strcpy(cp, "\\\\.\\"); strncat(cp, b, len); } } } } /* Main copy loop's read (input) for win32 block device. Returns 0 on * success, else SG_LIB_FILE_ERROR, SG_LIB_CAT_MEDIUM_HARD or -1 . */ int win32_cp_read_block(struct opts_t * optsp, struct cp_state_t * csp, unsigned char * wrkPos, int * ifull_extrap, int verbose) { int k, res, res2; int ibs = optsp->ibs; int64_t offset = optsp->skip * ibs; int64_t my_skip; int numbytes = csp->icbpt * ibs; if (ifull_extrap) *ifull_extrap = 0; if (offset != csp->if_filepos) { if (verbose > 2) fprintf(stderr, "moving if filepos: new_pos=" "%"PRId64"\n", (int64_t)offset); if (win32_set_file_pos(optsp, DDPT_ARG_IN, offset, verbose)) return SG_LIB_FILE_ERROR; csp->if_filepos = offset; } res = win32_block_read(optsp, wrkPos, numbytes, verbose); if (res < 0) { if ((-SG_LIB_CAT_MEDIUM_HARD == res) && (optsp->iflagp->coe)) { if (1 == csp->icbpt) { // Don't read again, this must be bad block memset(wrkPos, 0, ibs); if ((res2 = coe_process_eio(optsp->skip))) return res2; ++*ifull_extrap; csp->bytes_read += ibs; return 0; } else { my_skip = optsp->skip; for (k = 0; k < csp->icbpt; ++k, ++my_skip, wrkPos += ibs, offset += ibs) { if (offset != csp->if_filepos) { if (verbose > 2) fprintf(stderr, "moving if filepos: new_pos=" "%"PRId64"\n", (int64_t)offset); if (win32_set_file_pos(optsp, DDPT_ARG_IN, offset, verbose)) return SG_LIB_FILE_ERROR; csp->if_filepos = offset; } memset(wrkPos, 0, ibs); res = win32_block_read(optsp, wrkPos, ibs, verbose); if (ibs == res) { zero_coe_limit_count(); csp->if_filepos += ibs; if (verbose > 2) fprintf(stderr, "reading 1 block, skip=%"PRId64 " : okay\n", my_skip); } else if (-SG_LIB_CAT_MEDIUM_HARD == res) { if ((res2 = coe_process_eio(my_skip))) return res2; } else { fprintf(stderr, "reading 1 block, skip=%"PRId64 " failed\n", my_skip); csp->leave_reason = SG_LIB_CAT_OTHER; csp->icbpt = k; csp->ocbpt = (k * ibs) / optsp->obs; if (((k * ibs) % optsp->obs) > 0) ++csp->ocbpt; return 0; } ++*ifull_extrap; csp->bytes_read += ibs; } return 0; } } else { fprintf(stderr, "read(win32_block), skip=%"PRId64 " error occurred\n", optsp->skip); return (-SG_LIB_CAT_MEDIUM_HARD == res) ? -res : -1; } } else { if (res < numbytes) { /* assume no partial reads (i.e. non integral blocks) */ csp->icbpt = res / ibs; ++csp->leave_after_write; csp->leave_reason = 0; /* assume at end rather than error */ csp->ocbpt = res / optsp->obs; if (verbose > 1) fprintf(stderr, "short read, requested %d blocks, got " "%d blocks\n", numbytes / ibs, csp->icbpt); } csp->if_filepos += res; if (ifull_extrap) *ifull_extrap = csp->icbpt; } return 0; } /* Returns 0 on success, 1 on error */ int win32_open_if(struct opts_t * optsp, int verbose) { DISK_GEOMETRY g; DWORD count, err; char b[80]; if (verbose) fprintf(stderr, "CreateFile(%s , in)\n", optsp->inf); optsp->ib_fh = CreateFile(optsp->inf, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); if (INVALID_HANDLE_VALUE == optsp->ib_fh) { err = GetLastError(); if (win32_errmsg(err, b, sizeof(b)) < 0) fprintf(stderr, "CreateFile(in) failed, error=%ld [and " "win32_errmsg() failed]\n", err); else fprintf(stderr, "CreateFile(in) failed, %s [%ld]\n", b, err); return 1; } if (0 == DeviceIoControl(optsp->ib_fh, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &g, sizeof(g), &count, NULL)) { fprintf(stderr, "DeviceIoControl(in, geometry) error=%ld\n", GetLastError()); return 1; } if ((int)g.BytesPerSector != optsp->ibs) { fprintf(stderr, "Specified in block size (%d) doesn't match device " "geometry block size: %d\n", optsp->ibs, (int)g.BytesPerSector); return 1; } return 0; } /* Returns 0 on success, 1 on error. */ int win32_open_of(struct opts_t * optsp, int verbose) { DISK_GEOMETRY g; DWORD count, err; char b[80]; if (verbose) fprintf(stderr, "CreateFile(%s , out)\n", optsp->outf); optsp->ob_fh = CreateFile(optsp->outf, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); if (INVALID_HANDLE_VALUE == optsp->ob_fh) { err = GetLastError(); if (win32_errmsg(err, b, sizeof(b)) < 0) fprintf(stderr, "CreateFile(out) failed, error=%ld [and " "win32_errmsg() failed]\n", err); else fprintf(stderr, "CreateFile(out) failed, %s [%ld]\n", b, err); return 1; } if (0 == DeviceIoControl(optsp->ob_fh, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &g, sizeof(g), &count, NULL)) { fprintf(stderr, "DeviceIoControl(out, geometry) error=%ld\n", GetLastError()); return 1; } if ((int)g.BytesPerSector != optsp->obs) { fprintf(stderr, "Specified out block size (%d) doesn't match device " "geometry block size: %d\n", optsp->obs, (int)g.BytesPerSector); return 1; } return 0; } /* Returns 0 on success, 1 on error */ int win32_set_file_pos(struct opts_t * optsp, int which_arg, int64_t pos, int verbose) { LONG lo32 = pos & 0xffffffff; LONG hi32 = (pos >> 32) & 0xffffffff; DWORD err; DWORD lo_ret; HANDLE fh; const char * cp; fh = (DDPT_ARG_IN == which_arg) ? optsp->ib_fh : optsp->ob_fh; cp = (DDPT_ARG_IN == which_arg) ? "in" : "out"; if (verbose > 2) fprintf(stderr, "SetFilePointer( 0x%"PRIx64", %s)\n", pos, cp); lo_ret = SetFilePointer(fh, lo32, &hi32, FILE_BEGIN); if ((INVALID_SET_FILE_POINTER == lo_ret) && (NO_ERROR != (err = GetLastError()))) { if (verbose) fprintf(stderr, "SetFilePointer failed to set " "pos=[0x%"PRIx64"], error=%ld\n", pos, err); return 1; } return 0; } /* Returns number read, -SG_LIB_CAT_MEDIUM_HARD or -1 on error */ int win32_block_read(struct opts_t * optsp, unsigned char * bp, int num_bytes, int verbose) { DWORD num = num_bytes; DWORD howMany, err; char b[80]; if (verbose > 2) fprintf(stderr, "ReadFile(num=%d, in)\n", num_bytes); if (ReadFile(optsp->ib_fh, bp, num, &howMany, NULL) == 0) { err = GetLastError(); if (verbose) { if (win32_errmsg(err, b, sizeof(b)) < 0) fprintf(stderr, "ReadFile failed, error=%ld [and " "win32_errmsg() failed]\n", err); else fprintf(stderr, "ReadFile failed, %s [%ld]\n", b, err); } if (23 == err) return -SG_LIB_CAT_MEDIUM_HARD; else return -1; } return (int)howMany; } /* Returns number read from OFILE, -SG_LIB_CAT_MEDIUM_HARD or -1 on error */ int win32_block_read_from_of(struct opts_t * optsp, unsigned char * bp, int num_bytes, int verbose) { DWORD num = num_bytes; DWORD howMany, err; char b[80]; if (verbose > 2) fprintf(stderr, "ReadFile(num=%d, out)\n", num_bytes); if (ReadFile(optsp->ob_fh, bp, num, &howMany, NULL) == 0) { err = GetLastError(); if (verbose) { if (win32_errmsg(err, b, sizeof(b)) < 0) fprintf(stderr, "ReadFile failed, error=%ld [and " "win32_errmsg() failed]\n", err); else fprintf(stderr, "ReadFile failed, %s [%ld]\n", b, err); } if (23 == err) return -SG_LIB_CAT_MEDIUM_HARD; else return -1; } return (int)howMany; } /* Returns number written, -SG_LIB_CAT_MEDIUM_HARD or -1 on error */ int win32_block_write(struct opts_t * optsp, const unsigned char * bp, int num_bytes, int verbose) { DWORD num = num_bytes; DWORD howMany, err; char b[80]; if (verbose > 2) fprintf(stderr, "WriteFile(num=%d, out)\n", num_bytes); if (WriteFile(optsp->ob_fh, bp, num, &howMany, NULL) == 0) { err = GetLastError(); if (verbose) { if (win32_errmsg(err, b, sizeof(b)) < 0) fprintf(stderr, "WriteFile failed, error=%ld [and " "win32_errmsg() failed]\n", err); else fprintf(stderr, "WriteFile failed, %s [%ld]\n", b, err); } if (23 == err) return -SG_LIB_CAT_MEDIUM_HARD; else return -1; } return (int)howMany; } /* get_blkdev_capacity() returns 0 -> success or -1 -> failure. If * successful writes back sector size (logical block size) using the sect_sz * pointer. Also writes back the number of sectors (logical blocks) on the * block device using num_sect pointer. Win32 version. */ int get_blkdev_capacity(struct opts_t * optsp, int which_arg, int64_t * num_sect, int * sect_sz, int verbose) { DISK_GEOMETRY g; GET_LENGTH_INFORMATION gli; ULARGE_INTEGER total_bytes; DWORD count; HANDLE fh; const char * fname; int64_t byte_len, blks; int fname_len; char dirName[64]; fh = (DDPT_ARG_IN == which_arg) ? optsp->ib_fh : optsp->ob_fh; fname = (DDPT_ARG_IN == which_arg) ? optsp->inf : optsp->outf; if (verbose > 2) fprintf(stderr, "get_blkdev_capacity: for %s\n", fname); if (0 == DeviceIoControl(fh, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &g, sizeof(g), &count, NULL)) { if (verbose) fprintf(stderr, "DeviceIoControl(blkdev, geometry) error=%ld\n", GetLastError()); *num_sect = 0; *sect_sz = 0; return -1; } *sect_sz = (int)g.BytesPerSector; /* IOCTL_DISK_GET_LENGTH_INFO not defined before XP */ if (DeviceIoControl(fh, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0, &gli, sizeof(gli), &count, NULL)) { byte_len = gli.Length.QuadPart; *num_sect = byte_len / (int)g.BytesPerSector; return 0; } else if (verbose > 2) fprintf(stderr, "DeviceIoControl(blkdev, length_info) " "error=%ld\n", GetLastError()); /* Assume if device name finishes in digit then its physical */ fname_len = (int)strlen(fname); if (isdigit((int)fname[fname_len - 1])) { blks = g.Cylinders.QuadPart; blks *= g.TracksPerCylinder; blks *= g.SectorsPerTrack; *num_sect = blks; return 0; } if ((fname_len < 4) || (fname_len > (int)sizeof(dirName))) { fprintf(stderr, "get_blkdev_capacity: unable to process %s into " "directory name\n", fname); *num_sect = 0; return -1; } memcpy(dirName, fname + 4, fname_len - 4); dirName[fname_len - 4] = '\\'; dirName[fname_len - 3] = '\0'; if (GetDiskFreeSpaceEx(dirName, NULL, &total_bytes, NULL)) { byte_len = total_bytes.QuadPart; *num_sect = byte_len / (int)g.BytesPerSector; } else if (verbose > 1) { fprintf(stderr, "GetDiskFreeSpaceEx(%s) " "error=%ld\n", dirName, GetLastError()); *num_sect = 0; return -1; } return 0; } #endif ddpt-0.92/src/Makefile.in0000644000175000017500000010343511526513027014237 0ustar douggdougg# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, # Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ bin_PROGRAMS = ddpt$(EXEEXT) @HAVE_SGUTILS_FALSE@am__append_1 = $(sglib_SOURCES) @HAVE_SGUTILS_TRUE@ddpt_DEPENDENCIES = subdir = src DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) am__ddpt_SOURCES_DIST = ddpt.c ddpt.h ddpt_win32.c ddpt_wscan.c \ ../lib/sg_lib.c ../include/sg_lib.h ../lib/sg_lib_data.c \ ../include/sg_lib_data.h ../lib/sg_cmds_basic.c \ ../include/sg_cmds_basic.h ../lib/sg_cmds_mmc.c \ ../include/sg_cmds_mmc.h ../include/sg_pt.h \ ../lib/sg_pt_common.c am__objects_1 = sg_lib.$(OBJEXT) sg_lib_data.$(OBJEXT) \ sg_cmds_basic.$(OBJEXT) sg_cmds_mmc.$(OBJEXT) \ sg_pt_common.$(OBJEXT) @HAVE_SGUTILS_FALSE@am__objects_2 = $(am__objects_1) am_ddpt_OBJECTS = ddpt.$(OBJEXT) ddpt_win32.$(OBJEXT) \ ddpt_wscan.$(OBJEXT) $(am__objects_2) ddpt_OBJECTS = $(am_ddpt_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(ddpt_SOURCES) $(EXTRA_ddpt_SOURCES) DIST_SOURCES = $(am__ddpt_SOURCES_DIST) $(EXTRA_ddpt_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ SET_MAKE = @SET_MAKE@ SGUTILS_LIBS = @SGUTILS_LIBS@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ os_deps = @os_deps@ os_libs = @os_libs@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ rt_libs = @rt_libs@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ # INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/include/scsi AM_CFLAGS = -I$(top_srcdir)/include -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -Wall -W # AM_CFLAGS = -I$(top_srcdir)/include -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -Wall -W -pedantic -std=c99 ddpt_SOURCES = ddpt.c ddpt.h ddpt_win32.c ddpt_wscan.c $(am__append_1) sglib_SOURCES = ../lib/sg_lib.c \ ../include/sg_lib.h \ ../lib/sg_lib_data.c \ ../include/sg_lib_data.h \ ../lib/sg_cmds_basic.c \ ../include/sg_cmds_basic.h \ ../lib/sg_cmds_mmc.c \ ../include/sg_cmds_mmc.h \ ../include/sg_pt.h \ ../lib/sg_pt_common.c @HAVE_SGUTILS_FALSE@INCLUDES = -I$(top_srcdir)/include @HAVE_SGUTILS_TRUE@INCLUDES = -I/usr/include/scsi @HAVE_SGUTILS_FALSE@ddpt_LDADD = @os_deps@ @os_libs@ @rt_libs@ @SGUTILS_LIBS@ @HAVE_SGUTILS_TRUE@ddpt_LDADD = @os_libs@ @rt_libs@ @SGUTILS_LIBS@ @HAVE_SGUTILS_FALSE@ddpt_DEPENDENCIES = @os_deps@ EXTRA_ddpt_SOURCES = ../lib/sg_pt_linux.c \ ../include/sg_linux_inc.h \ ../lib/sg_pt_freebsd.c \ ../lib/sg_pt_osf1.c \ ../lib/sg_pt_solaris.c \ ../lib/sg_pt_win32.c \ ../include/sg_pt_win32.h all: all-am .SUFFIXES: .SUFFIXES: .c .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p; \ then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) ddpt$(EXEEXT): $(ddpt_OBJECTS) $(ddpt_DEPENDENCIES) @rm -f ddpt$(EXEEXT) $(LINK) $(ddpt_OBJECTS) $(ddpt_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ddpt.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ddpt_win32.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ddpt_wscan.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_cmds_basic.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_cmds_mmc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_lib.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_lib_data.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_pt_common.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_pt_freebsd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_pt_linux.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_pt_osf1.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_pt_solaris.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_pt_win32.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` sg_lib.o: ../lib/sg_lib.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sg_lib.o -MD -MP -MF $(DEPDIR)/sg_lib.Tpo -c -o sg_lib.o `test -f '../lib/sg_lib.c' || echo '$(srcdir)/'`../lib/sg_lib.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/sg_lib.Tpo $(DEPDIR)/sg_lib.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='../lib/sg_lib.c' object='sg_lib.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sg_lib.o `test -f '../lib/sg_lib.c' || echo '$(srcdir)/'`../lib/sg_lib.c sg_lib.obj: ../lib/sg_lib.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sg_lib.obj -MD -MP -MF $(DEPDIR)/sg_lib.Tpo -c -o sg_lib.obj `if test -f '../lib/sg_lib.c'; then $(CYGPATH_W) '../lib/sg_lib.c'; else $(CYGPATH_W) '$(srcdir)/../lib/sg_lib.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/sg_lib.Tpo $(DEPDIR)/sg_lib.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='../lib/sg_lib.c' object='sg_lib.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sg_lib.obj `if test -f '../lib/sg_lib.c'; then $(CYGPATH_W) '../lib/sg_lib.c'; else $(CYGPATH_W) '$(srcdir)/../lib/sg_lib.c'; fi` sg_lib_data.o: ../lib/sg_lib_data.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sg_lib_data.o -MD -MP -MF $(DEPDIR)/sg_lib_data.Tpo -c -o sg_lib_data.o `test -f '../lib/sg_lib_data.c' || echo '$(srcdir)/'`../lib/sg_lib_data.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/sg_lib_data.Tpo $(DEPDIR)/sg_lib_data.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='../lib/sg_lib_data.c' object='sg_lib_data.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sg_lib_data.o `test -f '../lib/sg_lib_data.c' || echo '$(srcdir)/'`../lib/sg_lib_data.c sg_lib_data.obj: ../lib/sg_lib_data.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sg_lib_data.obj -MD -MP -MF $(DEPDIR)/sg_lib_data.Tpo -c -o sg_lib_data.obj `if test -f '../lib/sg_lib_data.c'; then $(CYGPATH_W) '../lib/sg_lib_data.c'; else $(CYGPATH_W) '$(srcdir)/../lib/sg_lib_data.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/sg_lib_data.Tpo $(DEPDIR)/sg_lib_data.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='../lib/sg_lib_data.c' object='sg_lib_data.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sg_lib_data.obj `if test -f '../lib/sg_lib_data.c'; then $(CYGPATH_W) '../lib/sg_lib_data.c'; else $(CYGPATH_W) '$(srcdir)/../lib/sg_lib_data.c'; fi` sg_cmds_basic.o: ../lib/sg_cmds_basic.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sg_cmds_basic.o -MD -MP -MF $(DEPDIR)/sg_cmds_basic.Tpo -c -o sg_cmds_basic.o `test -f '../lib/sg_cmds_basic.c' || echo '$(srcdir)/'`../lib/sg_cmds_basic.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/sg_cmds_basic.Tpo $(DEPDIR)/sg_cmds_basic.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='../lib/sg_cmds_basic.c' object='sg_cmds_basic.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sg_cmds_basic.o `test -f '../lib/sg_cmds_basic.c' || echo '$(srcdir)/'`../lib/sg_cmds_basic.c sg_cmds_basic.obj: ../lib/sg_cmds_basic.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sg_cmds_basic.obj -MD -MP -MF $(DEPDIR)/sg_cmds_basic.Tpo -c -o sg_cmds_basic.obj `if test -f '../lib/sg_cmds_basic.c'; then $(CYGPATH_W) '../lib/sg_cmds_basic.c'; else $(CYGPATH_W) '$(srcdir)/../lib/sg_cmds_basic.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/sg_cmds_basic.Tpo $(DEPDIR)/sg_cmds_basic.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='../lib/sg_cmds_basic.c' object='sg_cmds_basic.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sg_cmds_basic.obj `if test -f '../lib/sg_cmds_basic.c'; then $(CYGPATH_W) '../lib/sg_cmds_basic.c'; else $(CYGPATH_W) '$(srcdir)/../lib/sg_cmds_basic.c'; fi` sg_cmds_mmc.o: ../lib/sg_cmds_mmc.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sg_cmds_mmc.o -MD -MP -MF $(DEPDIR)/sg_cmds_mmc.Tpo -c -o sg_cmds_mmc.o `test -f '../lib/sg_cmds_mmc.c' || echo '$(srcdir)/'`../lib/sg_cmds_mmc.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/sg_cmds_mmc.Tpo $(DEPDIR)/sg_cmds_mmc.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='../lib/sg_cmds_mmc.c' object='sg_cmds_mmc.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sg_cmds_mmc.o `test -f '../lib/sg_cmds_mmc.c' || echo '$(srcdir)/'`../lib/sg_cmds_mmc.c sg_cmds_mmc.obj: ../lib/sg_cmds_mmc.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sg_cmds_mmc.obj -MD -MP -MF $(DEPDIR)/sg_cmds_mmc.Tpo -c -o sg_cmds_mmc.obj `if test -f '../lib/sg_cmds_mmc.c'; then $(CYGPATH_W) '../lib/sg_cmds_mmc.c'; else $(CYGPATH_W) '$(srcdir)/../lib/sg_cmds_mmc.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/sg_cmds_mmc.Tpo $(DEPDIR)/sg_cmds_mmc.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='../lib/sg_cmds_mmc.c' object='sg_cmds_mmc.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sg_cmds_mmc.obj `if test -f '../lib/sg_cmds_mmc.c'; then $(CYGPATH_W) '../lib/sg_cmds_mmc.c'; else $(CYGPATH_W) '$(srcdir)/../lib/sg_cmds_mmc.c'; fi` sg_pt_common.o: ../lib/sg_pt_common.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sg_pt_common.o -MD -MP -MF $(DEPDIR)/sg_pt_common.Tpo -c -o sg_pt_common.o `test -f '../lib/sg_pt_common.c' || echo '$(srcdir)/'`../lib/sg_pt_common.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/sg_pt_common.Tpo $(DEPDIR)/sg_pt_common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='../lib/sg_pt_common.c' object='sg_pt_common.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sg_pt_common.o `test -f '../lib/sg_pt_common.c' || echo '$(srcdir)/'`../lib/sg_pt_common.c sg_pt_common.obj: ../lib/sg_pt_common.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sg_pt_common.obj -MD -MP -MF $(DEPDIR)/sg_pt_common.Tpo -c -o sg_pt_common.obj `if test -f '../lib/sg_pt_common.c'; then $(CYGPATH_W) '../lib/sg_pt_common.c'; else $(CYGPATH_W) '$(srcdir)/../lib/sg_pt_common.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/sg_pt_common.Tpo $(DEPDIR)/sg_pt_common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='../lib/sg_pt_common.c' object='sg_pt_common.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sg_pt_common.obj `if test -f '../lib/sg_pt_common.c'; then $(CYGPATH_W) '../lib/sg_pt_common.c'; else $(CYGPATH_W) '$(srcdir)/../lib/sg_pt_common.c'; fi` sg_pt_linux.o: ../lib/sg_pt_linux.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sg_pt_linux.o -MD -MP -MF $(DEPDIR)/sg_pt_linux.Tpo -c -o sg_pt_linux.o `test -f '../lib/sg_pt_linux.c' || echo '$(srcdir)/'`../lib/sg_pt_linux.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/sg_pt_linux.Tpo $(DEPDIR)/sg_pt_linux.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='../lib/sg_pt_linux.c' object='sg_pt_linux.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sg_pt_linux.o `test -f '../lib/sg_pt_linux.c' || echo '$(srcdir)/'`../lib/sg_pt_linux.c sg_pt_linux.obj: ../lib/sg_pt_linux.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sg_pt_linux.obj -MD -MP -MF $(DEPDIR)/sg_pt_linux.Tpo -c -o sg_pt_linux.obj `if test -f '../lib/sg_pt_linux.c'; then $(CYGPATH_W) '../lib/sg_pt_linux.c'; else $(CYGPATH_W) '$(srcdir)/../lib/sg_pt_linux.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/sg_pt_linux.Tpo $(DEPDIR)/sg_pt_linux.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='../lib/sg_pt_linux.c' object='sg_pt_linux.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sg_pt_linux.obj `if test -f '../lib/sg_pt_linux.c'; then $(CYGPATH_W) '../lib/sg_pt_linux.c'; else $(CYGPATH_W) '$(srcdir)/../lib/sg_pt_linux.c'; fi` sg_pt_freebsd.o: ../lib/sg_pt_freebsd.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sg_pt_freebsd.o -MD -MP -MF $(DEPDIR)/sg_pt_freebsd.Tpo -c -o sg_pt_freebsd.o `test -f '../lib/sg_pt_freebsd.c' || echo '$(srcdir)/'`../lib/sg_pt_freebsd.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/sg_pt_freebsd.Tpo $(DEPDIR)/sg_pt_freebsd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='../lib/sg_pt_freebsd.c' object='sg_pt_freebsd.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sg_pt_freebsd.o `test -f '../lib/sg_pt_freebsd.c' || echo '$(srcdir)/'`../lib/sg_pt_freebsd.c sg_pt_freebsd.obj: ../lib/sg_pt_freebsd.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sg_pt_freebsd.obj -MD -MP -MF $(DEPDIR)/sg_pt_freebsd.Tpo -c -o sg_pt_freebsd.obj `if test -f '../lib/sg_pt_freebsd.c'; then $(CYGPATH_W) '../lib/sg_pt_freebsd.c'; else $(CYGPATH_W) '$(srcdir)/../lib/sg_pt_freebsd.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/sg_pt_freebsd.Tpo $(DEPDIR)/sg_pt_freebsd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='../lib/sg_pt_freebsd.c' object='sg_pt_freebsd.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sg_pt_freebsd.obj `if test -f '../lib/sg_pt_freebsd.c'; then $(CYGPATH_W) '../lib/sg_pt_freebsd.c'; else $(CYGPATH_W) '$(srcdir)/../lib/sg_pt_freebsd.c'; fi` sg_pt_osf1.o: ../lib/sg_pt_osf1.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sg_pt_osf1.o -MD -MP -MF $(DEPDIR)/sg_pt_osf1.Tpo -c -o sg_pt_osf1.o `test -f '../lib/sg_pt_osf1.c' || echo '$(srcdir)/'`../lib/sg_pt_osf1.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/sg_pt_osf1.Tpo $(DEPDIR)/sg_pt_osf1.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='../lib/sg_pt_osf1.c' object='sg_pt_osf1.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sg_pt_osf1.o `test -f '../lib/sg_pt_osf1.c' || echo '$(srcdir)/'`../lib/sg_pt_osf1.c sg_pt_osf1.obj: ../lib/sg_pt_osf1.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sg_pt_osf1.obj -MD -MP -MF $(DEPDIR)/sg_pt_osf1.Tpo -c -o sg_pt_osf1.obj `if test -f '../lib/sg_pt_osf1.c'; then $(CYGPATH_W) '../lib/sg_pt_osf1.c'; else $(CYGPATH_W) '$(srcdir)/../lib/sg_pt_osf1.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/sg_pt_osf1.Tpo $(DEPDIR)/sg_pt_osf1.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='../lib/sg_pt_osf1.c' object='sg_pt_osf1.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sg_pt_osf1.obj `if test -f '../lib/sg_pt_osf1.c'; then $(CYGPATH_W) '../lib/sg_pt_osf1.c'; else $(CYGPATH_W) '$(srcdir)/../lib/sg_pt_osf1.c'; fi` sg_pt_solaris.o: ../lib/sg_pt_solaris.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sg_pt_solaris.o -MD -MP -MF $(DEPDIR)/sg_pt_solaris.Tpo -c -o sg_pt_solaris.o `test -f '../lib/sg_pt_solaris.c' || echo '$(srcdir)/'`../lib/sg_pt_solaris.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/sg_pt_solaris.Tpo $(DEPDIR)/sg_pt_solaris.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='../lib/sg_pt_solaris.c' object='sg_pt_solaris.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sg_pt_solaris.o `test -f '../lib/sg_pt_solaris.c' || echo '$(srcdir)/'`../lib/sg_pt_solaris.c sg_pt_solaris.obj: ../lib/sg_pt_solaris.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sg_pt_solaris.obj -MD -MP -MF $(DEPDIR)/sg_pt_solaris.Tpo -c -o sg_pt_solaris.obj `if test -f '../lib/sg_pt_solaris.c'; then $(CYGPATH_W) '../lib/sg_pt_solaris.c'; else $(CYGPATH_W) '$(srcdir)/../lib/sg_pt_solaris.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/sg_pt_solaris.Tpo $(DEPDIR)/sg_pt_solaris.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='../lib/sg_pt_solaris.c' object='sg_pt_solaris.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sg_pt_solaris.obj `if test -f '../lib/sg_pt_solaris.c'; then $(CYGPATH_W) '../lib/sg_pt_solaris.c'; else $(CYGPATH_W) '$(srcdir)/../lib/sg_pt_solaris.c'; fi` sg_pt_win32.o: ../lib/sg_pt_win32.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sg_pt_win32.o -MD -MP -MF $(DEPDIR)/sg_pt_win32.Tpo -c -o sg_pt_win32.o `test -f '../lib/sg_pt_win32.c' || echo '$(srcdir)/'`../lib/sg_pt_win32.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/sg_pt_win32.Tpo $(DEPDIR)/sg_pt_win32.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='../lib/sg_pt_win32.c' object='sg_pt_win32.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sg_pt_win32.o `test -f '../lib/sg_pt_win32.c' || echo '$(srcdir)/'`../lib/sg_pt_win32.c sg_pt_win32.obj: ../lib/sg_pt_win32.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sg_pt_win32.obj -MD -MP -MF $(DEPDIR)/sg_pt_win32.Tpo -c -o sg_pt_win32.obj `if test -f '../lib/sg_pt_win32.c'; then $(CYGPATH_W) '../lib/sg_pt_win32.c'; else $(CYGPATH_W) '$(srcdir)/../lib/sg_pt_win32.c'; fi` @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/sg_pt_win32.Tpo $(DEPDIR)/sg_pt_win32.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='../lib/sg_pt_win32.c' object='sg_pt_win32.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sg_pt_win32.obj `if test -f '../lib/sg_pt_win32.c'; then $(CYGPATH_W) '../lib/sg_pt_win32.c'; else $(CYGPATH_W) '$(srcdir)/../lib/sg_pt_win32.c'; fi` ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) installdirs: for dir in "$(DESTDIR)$(bindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ clean-generic ctags distclean distclean-compile \ distclean-generic distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-binPROGRAMS \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ uninstall-am uninstall-binPROGRAMS # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: ddpt-0.92/src/Makefile.am0000644000175000017500000000250711524675616014237 0ustar douggdouggbin_PROGRAMS = ddpt # INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/include/scsi AM_CFLAGS = -I$(top_srcdir)/include -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -Wall -W # AM_CFLAGS = -I$(top_srcdir)/include -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -Wall -W -pedantic -std=c99 ddpt_SOURCES = ddpt.c \ ddpt.h \ ddpt_win32.c \ ddpt_wscan.c sglib_SOURCES = ../lib/sg_lib.c \ ../include/sg_lib.h \ ../lib/sg_lib_data.c \ ../include/sg_lib_data.h \ ../lib/sg_cmds_basic.c \ ../include/sg_cmds_basic.h \ ../lib/sg_cmds_mmc.c \ ../include/sg_cmds_mmc.h \ ../include/sg_pt.h \ ../lib/sg_pt_common.c if HAVE_SGUTILS INCLUDES = -I/usr/include/scsi ddpt_LDADD = @os_libs@ @rt_libs@ @SGUTILS_LIBS@ else INCLUDES = -I$(top_srcdir)/include ddpt_SOURCES += $(sglib_SOURCES) ddpt_LDADD = @os_deps@ @os_libs@ @rt_libs@ @SGUTILS_LIBS@ ddpt_DEPENDENCIES = @os_deps@ endif EXTRA_ddpt_SOURCES = ../lib/sg_pt_linux.c \ ../include/sg_linux_inc.h \ ../lib/sg_pt_freebsd.c \ ../lib/sg_pt_osf1.c \ ../lib/sg_pt_solaris.c \ ../lib/sg_pt_win32.c \ ../include/sg_pt_win32.h ddpt-0.92/src/ddpt_wscan.c0000644000175000017500000005156111524675616014501 0ustar douggdougg/* * Copyright (c) 2006-2011 Douglas Gilbert. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef SG_LIB_WIN32 #include #include #include #include #include #include #include #include "sg_lib.h" #include "sg_pt_win32.h" /* * This is called when the '--wscan' option is given to ddpt. It is * Win32 only code and shows the relationship between various device names * and volumes in Windows OSes (Windows 2000, 2003, XP, Vista and W7). There * is an optional scsi adapter scan. */ #define MAX_SCSI_ELEMS 1024 #define MAX_ADAPTER_NUM 64 #define MAX_PHYSICALDRIVE_NUM 512 #define MAX_CDROM_NUM 512 #define MAX_TAPE_NUM 512 #define MAX_HOLE_COUNT 8 // IOCTL_STORAGE_QUERY_PROPERTY #define FILE_DEVICE_MASS_STORAGE 0x0000002d #define IOCTL_STORAGE_BASE FILE_DEVICE_MASS_STORAGE #define FILE_ANY_ACCESS 0 // #define METHOD_BUFFERED 0 #define IOCTL_STORAGE_QUERY_PROPERTY \ CTL_CODE(IOCTL_STORAGE_BASE, 0x0500, METHOD_BUFFERED, FILE_ANY_ACCESS) typedef enum _STORAGE_BUS_TYPE { BusTypeUnknown = 0x00, BusTypeScsi = 0x01, BusTypeAtapi = 0x02, BusTypeAta = 0x03, BusType1394 = 0x04, BusTypeSsa = 0x05, BusTypeFibre = 0x06, BusTypeUsb = 0x07, BusTypeRAID = 0x08, BusTypeiScsi = 0x09, BusTypeSas = 0x0A, BusTypeSata = 0x0B, BusTypeSd = 0x0C, BusTypeMmc = 0x0D, BusTypeMax = 0x0E, BusTypeMaxReserved = 0x7F } STORAGE_BUS_TYPE, *PSTORAGE_BUS_TYPE; typedef struct _STORAGE_DEVICE_DESCRIPTOR { ULONG Version; ULONG Size; UCHAR DeviceType; UCHAR DeviceTypeModifier; BOOLEAN RemovableMedia; BOOLEAN CommandQueueing; ULONG VendorIdOffset; /* 0 if not available */ ULONG ProductIdOffset; /* 0 if not available */ ULONG ProductRevisionOffset;/* 0 if not available */ ULONG SerialNumberOffset; /* -1 if not available ?? */ STORAGE_BUS_TYPE BusType; ULONG RawPropertiesLength; UCHAR RawDeviceProperties[1]; } STORAGE_DEVICE_DESCRIPTOR, *PSTORAGE_DEVICE_DESCRIPTOR; typedef struct _STORAGE_DEVICE_UNIQUE_IDENTIFIER { ULONG Version; ULONG Size; ULONG StorageDeviceIdOffset; ULONG StorageDeviceOffset; ULONG DriveLayoutSignatureOffset; } STORAGE_DEVICE_UNIQUE_IDENTIFIER, *PSTORAGE_DEVICE_UNIQUE_IDENTIFIER; // Use CompareStorageDuids(PSTORAGE_DEVICE_UNIQUE_IDENTIFIER duid1, duid2) // to test for equality typedef enum _STORAGE_QUERY_TYPE { PropertyStandardQuery = 0, PropertyExistsQuery, PropertyMaskQuery, PropertyQueryMaxDefined } STORAGE_QUERY_TYPE, *PSTORAGE_QUERY_TYPE; typedef enum _STORAGE_PROPERTY_ID { StorageDeviceProperty = 0, StorageAdapterProperty, StorageDeviceIdProperty, StorageDeviceUniqueIdProperty, StorageDeviceWriteCacheProperty, StorageMiniportProperty, StorageAccessAlignmentProperty } STORAGE_PROPERTY_ID, *PSTORAGE_PROPERTY_ID; typedef struct _STORAGE_PROPERTY_QUERY { STORAGE_PROPERTY_ID PropertyId; STORAGE_QUERY_TYPE QueryType; UCHAR AdditionalParameters[1]; } STORAGE_PROPERTY_QUERY, *PSTORAGE_PROPERTY_QUERY; ///////////////////////////////////////////////////////////////////////////// union STORAGE_DEVICE_DESCRIPTOR_DATA { STORAGE_DEVICE_DESCRIPTOR desc; char raw[256]; }; union STORAGE_DEVICE_UID_DATA { STORAGE_DEVICE_UNIQUE_IDENTIFIER desc; char raw[512]; }; struct storage_elem { char name[32]; char volume_letters[32]; int qp_descriptor_valid; int qp_uid_valid; union STORAGE_DEVICE_DESCRIPTOR_DATA qp_descriptor; union STORAGE_DEVICE_UID_DATA qp_uid; }; static struct storage_elem * storage_arr; static int next_unused_elem = 0; static int verbose = 0; static char * get_err_str(DWORD err, int max_b_len, char * b) { LPVOID lpMsgBuf; int k, num, ch; if (max_b_len < 2) { if (1 == max_b_len) b[0] = '\0'; return b; } memset(b, 0, max_b_len); FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL ); num = lstrlen((LPCTSTR)lpMsgBuf); if (num < 1) return b; num = (num < max_b_len) ? num : (max_b_len - 1); for (k = 0; k < num; ++k) { ch = *((LPCTSTR)lpMsgBuf + k); if ((ch >= 0x0) && (ch < 0x7f)) b[k] = ch & 0x7f; else b[k] = '?'; } return b; } static const char * get_bus_type(int bt) { switch (bt) { case BusTypeUnknown: return "Unkno"; case BusTypeScsi: return "Scsi "; case BusTypeAtapi: return "Atapi"; case BusTypeAta: return "Ata "; case BusType1394: return "1394 "; case BusTypeSsa: return "Ssa "; case BusTypeFibre: return "Fibre"; case BusTypeUsb: return "Usb "; case BusTypeRAID: return "RAID "; case BusTypeiScsi: return "iScsi"; case BusTypeSas: return "Sas "; case BusTypeSata: return "Sata "; case BusTypeSd: return "Sd "; case BusTypeMmc: return "Mmc "; case BusTypeMax: return "Max "; default: return "_unkn"; } } static int query_dev_property(HANDLE hdevice, union STORAGE_DEVICE_DESCRIPTOR_DATA * data) { DWORD num_out, err; char b[256]; STORAGE_PROPERTY_QUERY query = {StorageDeviceProperty, PropertyStandardQuery, {0} }; memset(data, 0, sizeof(*data)); if (! DeviceIoControl(hdevice, IOCTL_STORAGE_QUERY_PROPERTY, &query, sizeof(query), data, sizeof(*data), &num_out, NULL)) { if (verbose > 2) { err = GetLastError(); fprintf(stderr, " IOCTL_STORAGE_QUERY_PROPERTY(Devprop) failed, " "Error=%ld %s\n", err, get_err_str(err, sizeof(b), b)); } return -ENOSYS; } if (verbose > 3) fprintf(stderr, " IOCTL_STORAGE_QUERY_PROPERTY(DevProp) num_out=%ld\n", num_out); return 0; } static int query_dev_uid(HANDLE hdevice, union STORAGE_DEVICE_UID_DATA * data) { DWORD num_out, err; char b[256]; STORAGE_PROPERTY_QUERY query = {StorageDeviceUniqueIdProperty, PropertyStandardQuery, {0} }; memset(data, 0, sizeof(*data)); if (! DeviceIoControl(hdevice, IOCTL_STORAGE_QUERY_PROPERTY, &query, sizeof(query), data, sizeof(*data), &num_out, NULL)) { if (verbose > 2) { err = GetLastError(); fprintf(stderr, " IOCTL_STORAGE_QUERY_PROPERTY(DevUid) failed, " "Error=%ld %s\n", err, get_err_str(err, sizeof(b), b)); } return -ENOSYS; } if (verbose > 3) fprintf(stderr, " IOCTL_STORAGE_QUERY_PROPERTY(DevUid) num_out=%ld\n", num_out); return 0; } static int check_devices(const struct storage_elem * sep) { int k, j; struct storage_elem * sarr = storage_arr; for (k = 0; k < next_unused_elem; ++k, ++sarr) { if ('\0' == sarr->name[0]) continue; if (sep->qp_descriptor_valid && sarr->qp_descriptor_valid) { if (0 == memcmp(&sep->qp_descriptor, &sarr->qp_descriptor, sizeof(sep->qp_descriptor))) { for (j = 0; j < (int)sizeof(sep->volume_letters); ++j) { if ('\0' == sarr->volume_letters[j]) { sarr->volume_letters[j] = sep->name[0]; break; } } return 1; } } // should do uid check here (probably before descriptor compare) } return 0; } static int enum_scsi_adapters(void) { int k, j; int hole_count = 0; HANDLE fh; ULONG dummy; DWORD err; BYTE bus; BOOL success; char adapter_name[64]; char inqDataBuff[2048]; PSCSI_ADAPTER_BUS_INFO ai; char b[256]; for (k = 0; k < MAX_ADAPTER_NUM; ++k) { snprintf(adapter_name, sizeof (adapter_name), "\\\\.\\SCSI%d:", k); fh = CreateFile(adapter_name, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (fh != INVALID_HANDLE_VALUE) { hole_count = 0; success = DeviceIoControl(fh, IOCTL_SCSI_GET_INQUIRY_DATA, NULL, 0, inqDataBuff, sizeof(inqDataBuff), &dummy, FALSE); if (success) { PSCSI_BUS_DATA pbd; PSCSI_INQUIRY_DATA pid; int num_lus, off; ai = (PSCSI_ADAPTER_BUS_INFO)inqDataBuff; for (bus = 0; bus < ai->NumberOfBusses; bus++) { pbd = ai->BusData + bus; num_lus = pbd->NumberOfLogicalUnits; off = pbd->InquiryDataOffset; for (j = 0; j < num_lus; ++j) { if ((off < (int)sizeof(SCSI_ADAPTER_BUS_INFO)) || (off > ((int)sizeof(inqDataBuff) - (int)sizeof(SCSI_INQUIRY_DATA)))) break; pid = (PSCSI_INQUIRY_DATA)(inqDataBuff + off); snprintf(b, sizeof(b) - 1, "SCSI%d:%d,%d,%d ", k, pid->PathId, pid->TargetId, pid->Lun); printf("%-15s", b); snprintf(b, sizeof(b) - 1, "claimed=%d pdt=%xh %s ", pid->DeviceClaimed, pid->InquiryData[0] % 0x3f, ((0 == pid->InquiryData[4]) ? "dubious" : "")); printf("%-26s", b); printf("%.8s %.16s %.4s\n", pid->InquiryData + 8, pid->InquiryData + 16, pid->InquiryData + 32); off = pid->NextInquiryDataOffset; } } } else { err = GetLastError(); fprintf(stderr, "%s: IOCTL_SCSI_GET_INQUIRY_DATA failed " "err=%lu\n\t%s", adapter_name, err, get_err_str(err, sizeof(b), b)); } CloseHandle(fh); } else { if (verbose > 3) { err = GetLastError(); fprintf(stderr, "%s: CreateFile failed err=%lu\n\t%s", adapter_name, err, get_err_str(err, sizeof(b), b)); } if (++hole_count >= MAX_HOLE_COUNT) break; } } return 0; } static int enum_volumes(char letter) { int k; HANDLE fh; char adapter_name[64]; struct storage_elem tmp_se; if (verbose > 2) fprintf(stderr, "%s: enter\n", __FUNCTION__ ); for (k = 0; k < 24; ++k) { memset(&tmp_se, 0, sizeof(tmp_se)); snprintf(adapter_name, sizeof (adapter_name), "\\\\.\\%c:", 'C' + k); tmp_se.name[0] = 'C' + k; fh = CreateFile(adapter_name, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (fh != INVALID_HANDLE_VALUE) { if (query_dev_property(fh, &tmp_se.qp_descriptor) < 0) fprintf(stderr, "%s: query_dev_property failed\n", __FUNCTION__ ); else tmp_se.qp_descriptor_valid = 1; if (query_dev_uid(fh, &tmp_se.qp_uid) < 0) { if (verbose > 2) fprintf(stderr, "%s: query_dev_uid failed\n", __FUNCTION__ ); } else tmp_se.qp_uid_valid = 1; if (('\0' == letter) || (letter == tmp_se.name[0])) check_devices(&tmp_se); CloseHandle(fh); } } return 0; } static int enum_pds(void) { int k; int hole_count = 0; HANDLE fh; DWORD err; char adapter_name[64]; char b[256]; struct storage_elem tmp_se; if (verbose > 2) fprintf(stderr, "%s: enter\n", __FUNCTION__ ); for (k = 0; k < MAX_PHYSICALDRIVE_NUM; ++k) { memset(&tmp_se, 0, sizeof(tmp_se)); snprintf(adapter_name, sizeof (adapter_name), "\\\\.\\PhysicalDrive%d", k); snprintf(tmp_se.name, sizeof(tmp_se.name), "PD%d", k); fh = CreateFile(adapter_name, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (fh != INVALID_HANDLE_VALUE) { if (query_dev_property(fh, &tmp_se.qp_descriptor) < 0) fprintf(stderr, "%s: query_dev_property failed\n", __FUNCTION__ ); else tmp_se.qp_descriptor_valid = 1; if (query_dev_uid(fh, &tmp_se.qp_uid) < 0) { if (verbose > 2) fprintf(stderr, "%s: query_dev_uid failed\n", __FUNCTION__ ); } else tmp_se.qp_uid_valid = 1; hole_count = 0; memcpy(&storage_arr[next_unused_elem++], &tmp_se, sizeof(tmp_se)); CloseHandle(fh); } else { if (verbose > 3) { err = GetLastError(); fprintf(stderr, "%s: CreateFile failed err=%lu\n\t%s", adapter_name, err, get_err_str(err, sizeof(b), b)); } if (++hole_count >= MAX_HOLE_COUNT) break; } } return 0; } static int enum_cdroms(void) { int k; int hole_count = 0; HANDLE fh; DWORD err; char adapter_name[64]; char b[256]; struct storage_elem tmp_se; if (verbose > 2) fprintf(stderr, "%s: enter\n", __FUNCTION__ ); for (k = 0; k < MAX_CDROM_NUM; ++k) { memset(&tmp_se, 0, sizeof(tmp_se)); snprintf(adapter_name, sizeof (adapter_name), "\\\\.\\CDROM%d", k); snprintf(tmp_se.name, sizeof(tmp_se.name), "CDROM%d", k); fh = CreateFile(adapter_name, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (fh != INVALID_HANDLE_VALUE) { if (query_dev_property(fh, &tmp_se.qp_descriptor) < 0) fprintf(stderr, "%s: query_dev_property failed\n", __FUNCTION__ ); else tmp_se.qp_descriptor_valid = 1; if (query_dev_uid(fh, &tmp_se.qp_uid) < 0) { if (verbose > 2) fprintf(stderr, "%s: query_dev_uid failed\n", __FUNCTION__ ); } else tmp_se.qp_uid_valid = 1; hole_count = 0; memcpy(&storage_arr[next_unused_elem++], &tmp_se, sizeof(tmp_se)); CloseHandle(fh); } else { if (verbose > 3) { err = GetLastError(); fprintf(stderr, "%s: CreateFile failed err=%lu\n\t%s", adapter_name, err, get_err_str(err, sizeof(b), b)); } if (++hole_count >= MAX_HOLE_COUNT) break; } } return 0; } static int enum_tapes(void) { int k; int hole_count = 0; HANDLE fh; DWORD err; char adapter_name[64]; char b[256]; struct storage_elem tmp_se; if (verbose > 2) fprintf(stderr, "%s: enter\n", __FUNCTION__ ); for (k = 0; k < MAX_TAPE_NUM; ++k) { memset(&tmp_se, 0, sizeof(tmp_se)); snprintf(adapter_name, sizeof (adapter_name), "\\\\.\\TAPE%d", k); snprintf(tmp_se.name, sizeof(tmp_se.name), "TAPE%d", k); fh = CreateFile(adapter_name, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (fh != INVALID_HANDLE_VALUE) { if (query_dev_property(fh, &tmp_se.qp_descriptor) < 0) fprintf(stderr, "%s: query_dev_property failed\n", __FUNCTION__ ); else tmp_se.qp_descriptor_valid = 1; if (query_dev_uid(fh, &tmp_se.qp_uid) < 0) { if (verbose > 2) fprintf(stderr, "%s: query_dev_uid failed\n", __FUNCTION__ ); } else tmp_se.qp_uid_valid = 1; hole_count = 0; memcpy(&storage_arr[next_unused_elem++], &tmp_se, sizeof(tmp_se)); CloseHandle(fh); } else { if (verbose > 3) { err = GetLastError(); fprintf(stderr, "%s: CreateFile failed err=%lu\n\t%s", adapter_name, err, get_err_str(err, sizeof(b), b)); } if (++hole_count >= MAX_HOLE_COUNT) break; } } return 0; } static int do_wscan(char letter, int show_bt, int scsi_scan) { int k, j, n; struct storage_elem * sp; if (scsi_scan < 2) { k = enum_pds(); if (k) return k; k = enum_cdroms(); if (k) return k; k = enum_tapes(); if (k) return k; k = enum_volumes(letter); if (k) return k; for (k = 0; k < next_unused_elem; ++k) { sp = storage_arr + k; if ('\0' == sp->name[0]) continue; printf("%-7s ", sp->name); n = strlen(sp->volume_letters); if (0 == n) printf(" "); else if (1 == n) printf("[%s] ", sp->volume_letters); else if (2 == n) printf("[%s] ", sp->volume_letters); else if (3 == n) printf("[%s] ", sp->volume_letters); else if (4 == n) printf("[%s] ", sp->volume_letters); else printf("[%4s+] ", sp->volume_letters); if (sp->qp_descriptor_valid) { if (show_bt) printf("<%s> ", get_bus_type(sp->qp_descriptor.desc.BusType)); j = sp->qp_descriptor.desc.VendorIdOffset; if (j > 0) printf("%s ", sp->qp_descriptor.raw + j); j = sp->qp_descriptor.desc.ProductIdOffset; if (j > 0) printf("%s ", sp->qp_descriptor.raw + j); j = sp->qp_descriptor.desc.ProductRevisionOffset; if (j > 0) printf("%s ", sp->qp_descriptor.raw + j); j = sp->qp_descriptor.desc.SerialNumberOffset; if (j > 0) printf("%s", sp->qp_descriptor.raw + j); printf("\n"); if (verbose > 2) dStrHex(sp->qp_descriptor.raw, 144, 0); } else printf("\n"); } } if (scsi_scan) { if (scsi_scan < 2) printf("\n"); enum_scsi_adapters(); } return 0; } int sg_do_wscan(char letter, int do_scan, int verb) { int ret, show_bt, scsi_scan; verbose = verb; show_bt = (do_scan > 1); scsi_scan = (do_scan > 2) ? (do_scan - 2) : 0; storage_arr = calloc(sizeof(struct storage_elem) * MAX_SCSI_ELEMS, 1); if (storage_arr) { ret = do_wscan(letter, show_bt, scsi_scan); free(storage_arr); } else { fprintf(stderr, "Failed to allocate storage_arr on heap\n"); ret = SG_LIB_SYNTAX_ERROR; } return ret; } #endif ddpt-0.92/debian/0000755000175000017500000000000011527261465012626 5ustar douggdouggddpt-0.92/debian/docs0000644000175000017500000000012111444165776013501 0ustar douggdouggAUTHORS COPYING CREDITS INSTALL NEWS README ChangeLog TODO doc/ddpt_examples.txt ddpt-0.92/debian/rules0000755000175000017500000000031611104200157013664 0ustar douggdougg#!/usr/bin/make -f include /usr/share/cdbs/1/rules/buildcore.mk include /usr/share/cdbs/1/class/autotools.mk include /usr/share/cdbs/1/rules/debhelper.mk #include /usr/share/cdbs/1/rules/simple-patchsys.mk ddpt-0.92/debian/copyright0000644000175000017500000000242011527261361014552 0ustar douggdouggThis package was debianized by Tue, 4 Nov 2008 23:59:59 -0500. It was downloaded from http://sg.danny.cz/sg/p/ddpt-0.91.tgz Copyright Holder: Douglas Gilbert License: Redistribution and use in source and binary forms, with or without modification, are permitted under the terms of the BSD License. THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software is copyright(c) 2008-2011 by Douglas Gilbert On Debian systems, the complete text of the BSD License can be found in `/usr/share/common-licenses/BSD'. ddpt-0.92/debian/control0000644000175000017500000000076311477517723014244 0ustar douggdouggSource: ddpt Section: admin Priority: optional Maintainer: Tomas Fasth Build-Depends: cdbs (>= 0.4.15), debhelper (>= 4.0.0), autotools-dev Standards-Version: 3.9.1 Package: ddpt Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} Description: Another dd variant. Copies files. Is specialized for cases where to source and/or destination is a storage device. Can drop down to the SCSI command level to issue READ and WRITE commands through a pass-through interface. ddpt-0.92/debian/changelog0000644000175000017500000000113511527261361014473 0ustar douggdouggddpt (0.92-0.1) unstable; urgency=low * ddpt -- Douglas Gilbert Thu, 17 Feb 2011 11:00:00 -0500 ddpt (0.91-1) unstable; urgency=low * New upstream release * Changed compat level from 4 to 8 * Updated Standards-Version to 3.9.1 -- Tomas Fasth Wed, 01 Dec 2010 00:51:01 +0000 ddpt (0.91-0.1) unstable; urgency=low * ddpt -- Douglas Gilbert Fri, 13 Aug 2010 18:00:00 -0400 ddpt (0.90-0.1) unstable; urgency=low * ddpt initial version -- Douglas Gilbert Sat, 08 May 2010 18:00:00 -0400 ddpt-0.92/debian/compat0000644000175000017500000000000211502217272014012 0ustar douggdougg7 ddpt-0.92/config.h.in0000644000175000017500000000332211511200143013402 0ustar douggdougg/* config.h.in. Generated from configure.ac by autoheader. */ /* Define to 1 if you have the `clock_gettime' function. */ #undef HAVE_CLOCK_GETTIME /* Define to 1 if you have the `fdatasync' function. */ #undef HAVE_FDATASYNC /* Define to 1 if you have the `fsync' function. */ #undef HAVE_FSYNC /* Define to 1 if you have the `gettimeofday' function. */ #undef HAVE_GETTIMEOFDAY /* Define to 1 if you have the `rt' library (-lrt). */ #undef HAVE_LIBRT /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_BSG_H /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_TYPES_H /* Define to 1 if you have the `posix_fadvise' function. */ #undef HAVE_POSIX_FADVISE /* ignore linux bsg */ #undef IGNORE_LINUX_BSG /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* ddpt Build Host */ #undef SG_LIB_BUILD_HOST /* ddpt on FreeBSD */ #undef SG_LIB_FREEBSD /* assume ddpt on linux */ #undef SG_LIB_LINUX /* also MinGW environment */ #undef SG_LIB_MINGW /* ddpt on Solaris */ #undef SG_LIB_SOLARIS /* ddpt on Win32 */ #undef SG_LIB_WIN32 /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* Version number of package */ #undef VERSION /* allow large buffers, aligned? */ #undef WIN32_SPT_DIRECT ddpt-0.92/autogen.sh0000755000175000017500000013014111173672404013401 0ustar douggdougg#!/bin/sh # a u t o g e n . s h # # Copyright (c) 2005-2007 United States Government as represented by # the U.S. Army Research Laboratory. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # # 3. The name of the author may not be used to endorse or promote # products derived from this software without specific prior written # permission. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # ### # # Script for automatically preparing the sources for compilation by # performing the myrid of necessary steps. The script attempts to # detect proper version support, and outputs warnings about particular # systems that have autotool peculiarities. # # Basically, if everything is set up and installed correctly, the # script will validate that minimum versions of the GNU Build System # tools are installed, account for several common configuration # issues, and then simply run autoreconf for you. # # If autoreconf fails, which can happen for many valid configurations, # this script proceeds to run manual preparation steps effectively # providing a POSIX shell script (mostly complete) reimplementation of # autoreconf. # # The AUTORECONF, AUTOCONF, AUTOMAKE, LIBTOOLIZE, ACLOCAL, AUTOHEADER # environment variables and corresponding _OPTIONS variables (e.g. # AUTORECONF_OPTIONS) may be used to override the default automatic # detection behaviors. Similarly the _VERSION variables will override # the minimum required version numbers. # # Examples: # # To obtain help on usage: # ./autogen.sh --help # # To obtain verbose output: # ./autogen.sh --verbose # # To skip autoreconf and prepare manually: # AUTORECONF=false ./autogen.sh # # To verbosely try running with an older (unsupported) autoconf: # AUTOCONF_VERSION=2.50 ./autogen.sh --verbose # # Author: Christopher Sean Morrison # ###################################################################### # set to minimum acceptible version of autoconf if [ "x$AUTOCONF_VERSION" = "x" ] ; then AUTOCONF_VERSION=2.52 fi # set to minimum acceptible version of automake if [ "x$AUTOMAKE_VERSION" = "x" ] ; then AUTOMAKE_VERSION=1.6.0 fi # set to minimum acceptible version of libtool if [ "x$LIBTOOL_VERSION" = "x" ] ; then LIBTOOL_VERSION=1.4.2 fi ################## # ident function # ################## ident ( ) { # extract copyright from header __copyright="`grep Copyright $AUTOGEN_SH | head -${HEAD_N}1 | awk '{print $4}'`" if [ "x$__copyright" = "x" ] ; then __copyright="`date +%Y`" fi # extract version from CVS Id string __id="$Id: autogen.sh,v 14.97 2007/06/18 22:25:02 brlcad Exp $" __version="`echo $__id | sed 's/.*\([0-9][0-9][0-9][0-9]\)[-\/]\([0-9][0-9]\)[-\/]\([0-9][0-9]\).*/\1\2\3/'`" if [ "x$__version" = "x" ] ; then __version="" fi echo "autogen.sh build preparation script by Christopher Sean Morrison" echo "revised 3-clause BSD-style license, copyright (c) $__copyright" echo "script version $__version, ISO/IEC 9945 POSIX shell script" } ################## # USAGE FUNCTION # ################## usage ( ) { echo "Usage: $AUTOGEN_SH [-h|--help] [-v|--verbose] [-q|--quiet] [--version]" echo " --help Help on $NAME_OF_AUTOGEN usage" echo " --verbose Verbose progress output" echo " --quiet Quiet suppressed progress output" echo " --version Only perform GNU Build System version checks" echo echo "Description: This script will validate that minimum versions of the" echo "GNU Build System tools are installed and then run autoreconf for you." echo "Should autoreconf fail, manual preparation steps will be run" echo "potentially accounting for several common preparation issues. The" echo "AUTORECONF, AUTOCONF, AUTOMAKE, LIBTOOLIZE, ACLOCAL, AUTOHEADER," echo "PROJECT, & CONFIGURE environment variables and corresponding _OPTIONS" echo "variables (e.g. AUTORECONF_OPTIONS) may be used to override the" echo "default automatic detection behavior." echo ident return 0 } ########################## # VERSION_ERROR FUNCTION # ########################## version_error ( ) { if [ "x$1" = "x" ] ; then echo "INTERNAL ERROR: version_error was not provided a version" exit 1 fi if [ "x$2" = "x" ] ; then echo "INTERNAL ERROR: version_error was not provided an application name" exit 1 fi $ECHO $ECHO "ERROR: To prepare the ${PROJECT} build system from scratch," $ECHO " at least version $1 of $2 must be installed." $ECHO $ECHO "$NAME_OF_AUTOGEN does not need to be run on the same machine that will" $ECHO "run configure or make. Either the GNU Autotools will need to be installed" $ECHO "or upgraded on this system, or $NAME_OF_AUTOGEN must be run on the source" $ECHO "code on another system and then transferred to here. -- Cheers!" $ECHO } ########################## # VERSION_CHECK FUNCTION # ########################## version_check ( ) { if [ "x$1" = "x" ] ; then echo "INTERNAL ERROR: version_check was not provided a minimum version" exit 1 fi _min="$1" if [ "x$2" = "x" ] ; then echo "INTERNAL ERROR: version check was not provided a comparison version" exit 1 fi _cur="$2" # needed to handle versions like 1.10 and 1.4-p6 _min="`echo ${_min}. | sed 's/[^0-9]/./g' | sed 's/\.\././g'`" _cur="`echo ${_cur}. | sed 's/[^0-9]/./g' | sed 's/\.\././g'`" _min_major="`echo $_min | cut -d. -f1`" _min_minor="`echo $_min | cut -d. -f2`" _min_patch="`echo $_min | cut -d. -f3`" _cur_major="`echo $_cur | cut -d. -f1`" _cur_minor="`echo $_cur | cut -d. -f2`" _cur_patch="`echo $_cur | cut -d. -f3`" if [ "x$_min_major" = "x" ] ; then _min_major=0 fi if [ "x$_min_minor" = "x" ] ; then _min_minor=0 fi if [ "x$_min_patch" = "x" ] ; then _min_patch=0 fi if [ "x$_cur_minor" = "x" ] ; then _cur_major=0 fi if [ "x$_cur_minor" = "x" ] ; then _cur_minor=0 fi if [ "x$_cur_patch" = "x" ] ; then _cur_patch=0 fi $VERBOSE_ECHO "Checking if ${_cur_major}.${_cur_minor}.${_cur_patch} is greater than ${_min_major}.${_min_minor}.${_min_patch}" if [ $_min_major -lt $_cur_major ] ; then return 0 elif [ $_min_major -eq $_cur_major ] ; then if [ $_min_minor -lt $_cur_minor ] ; then return 0 elif [ $_min_minor -eq $_cur_minor ] ; then if [ $_min_patch -lt $_cur_patch ] ; then return 0 elif [ $_min_patch -eq $_cur_patch ] ; then return 0 fi fi fi return 1 } ###################################### # LOCATE_CONFIGURE_TEMPLATE FUNCTION # ###################################### locate_configure_template ( ) { _pwd="`pwd`" if test -f "./configure.ac" ; then echo "./configure.ac" elif test -f "./configure.in" ; then echo "./configure.in" elif test -f "$_pwd/configure.ac" ; then echo "$_pwd/configure.ac" elif test -f "$_pwd/configure.in" ; then echo "$_pwd/configure.in" elif test -f "$PATH_TO_AUTOGEN/configure.ac" ; then echo "$PATH_TO_AUTOGEN/configure.ac" elif test -f "$PATH_TO_AUTOGEN/configure.in" ; then echo "$PATH_TO_AUTOGEN/configure.in" fi } ################## # argument check # ################## ARGS="$*" PATH_TO_AUTOGEN="`dirname $0`" NAME_OF_AUTOGEN="`basename $0`" AUTOGEN_SH="$PATH_TO_AUTOGEN/$NAME_OF_AUTOGEN" LIBTOOL_M4="${PATH_TO_AUTOGEN}/misc/libtool.m4" if [ "x$HELP" = "x" ] ; then HELP=no fi if [ "x$QUIET" = "x" ] ; then QUIET=no fi if [ "x$VERBOSE" = "x" ] ; then VERBOSE=no fi if [ "x$VERSION_ONLY" = "x" ] ; then VERSION_ONLY=no fi if [ "x$AUTORECONF_OPTIONS" = "x" ] ; then AUTORECONF_OPTIONS="-i -f" fi if [ "x$AUTOCONF_OPTIONS" = "x" ] ; then AUTOCONF_OPTIONS="-f" fi if [ "x$AUTOMAKE_OPTIONS" = "x" ] ; then AUTOMAKE_OPTIONS="-a -c -f" fi ALT_AUTOMAKE_OPTIONS="-a -c" if [ "x$LIBTOOLIZE_OPTIONS" = "x" ] ; then LIBTOOLIZE_OPTIONS="--automake -c -f" fi ALT_LIBTOOLIZE_OPTIONS="--automake --copy --force" if [ "x$ACLOCAL_OPTIONS" = "x" ] ; then ACLOCAL_OPTIONS="" fi if [ "x$AUTOHEADER_OPTIONS" = "x" ] ; then AUTOHEADER_OPTIONS="" fi for arg in $ARGS ; do case "x$arg" in x--help) HELP=yes ;; x-[hH]) HELP=yes ;; x--quiet) QUIET=yes ;; x-[qQ]) QUIET=yes ;; x--verbose) VERBOSE=yes ;; x-[vV]) VERBOSE=yes ;; x--version) VERSION_ONLY=yes ;; *) echo "Unknown option: $arg" echo usage exit 1 ;; esac done ##################### # environment check # ##################### # sanity check before recursions potentially begin if [ ! -f "$AUTOGEN_SH" ] ; then echo "INTERNAL ERROR: $AUTOGEN_SH does not exist" if [ ! "x$0" = "x$AUTOGEN_SH" ] ; then echo "INTERNAL ERROR: dirname/basename inconsistency: $0 != $AUTOGEN_SH" fi exit 1 fi # force locale setting to C so things like date output as expected LC_ALL=C # commands that this script expects for __cmd in echo head tail pwd ; do echo "test" | $__cmd > /dev/null 2>&1 if [ $? != 0 ] ; then echo "INTERNAL ERROR: '${__cmd}' command is required" exit 2 fi done echo "test" | grep "test" > /dev/null 2>&1 if test ! x$? = x0 ; then echo "INTERNAL ERROR: grep command is required" exit 1 fi echo "test" | sed "s/test/test/" > /dev/null 2>&1 if test ! x$? = x0 ; then echo "INTERNAL ERROR: sed command is required" exit 1 fi # determine the behavior of echo case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in *c*,-n*) ECHO_N= ECHO_C=' ' ECHO_T=' ' ;; *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; *) ECHO_N= ECHO_C='\c' ECHO_T= ;; esac # determine the behavior of head case "x`echo 'head' | head -n 1 2>&1`" in *xhead*) HEAD_N="n " ;; *) HEAD_N="" ;; esac # determine the behavior of tail case "x`echo 'tail' | tail -n 1 2>&1`" in *xtail*) TAIL_N="n " ;; *) TAIL_N="" ;; esac VERBOSE_ECHO=: ECHO=: if [ "x$QUIET" = "xyes" ] ; then if [ "x$VERBOSE" = "xyes" ] ; then echo "Verbose output quelled by quiet option. Further output disabled." fi else ECHO=echo if [ "x$VERBOSE" = "xyes" ] ; then echo "Verbose output enabled" VERBOSE_ECHO=echo fi fi # allow a recursive run to disable further recursions if [ "x$RUN_RECURSIVE" = "x" ] ; then RUN_RECURSIVE=yes fi ################################################ # check for help arg and bypass version checks # ################################################ if [ "x`echo $ARGS | sed 's/.*[hH][eE][lL][pP].*/help/'`" = "xhelp" ] ; then HELP=yes fi if [ "x$HELP" = "xyes" ] ; then usage $ECHO "---" $ECHO "Help was requested. No preparation or configuration will be performed." exit 0 fi ####################### # set up signal traps # ####################### untrap_abnormal ( ) { for sig in 1 2 13 15; do trap - $sig done } # do this cleanup whenever we exit. trap ' # start from the root if test -d "$START_PATH" ; then cd "$START_PATH" fi # restore/delete backup files if test "x$PFC_INIT" = "x1" ; then recursive_restore fi ' 0 # trap SIGHUP (1), SIGINT (2), SIGPIPE (13), SIGTERM (15) for sig in 1 2 13 15; do trap ' $ECHO "" $ECHO "Aborting $NAME_OF_AUTOGEN: caught signal '$sig'" # start from the root if test -d "$START_PATH" ; then cd "$START_PATH" fi # clean up on abnormal exit $VERBOSE_ECHO "rm -rf autom4te.cache" rm -rf autom4te.cache if test -f "acinclude.m4.$$.backup" ; then $VERBOSE_ECHO "cat acinclude.m4.$$.backup > acinclude.m4" chmod u+w acinclude.m4 cat acinclude.m4.$$.backup > acinclude.m4 $VERBOSE_ECHO "rm -f acinclude.m4.$$.backup" rm -f acinclude.m4.$$.backup fi { (exit 1); exit 1; } ' $sig done ############################# # look for a configure file # ############################# if [ "x$CONFIGURE" = "x" ] ; then CONFIGURE="`locate_configure_template`" if [ ! "x$CONFIGURE" = "x" ] ; then $VERBOSE_ECHO "Found a configure template: $CONFIGURE" fi else $ECHO "Using CONFIGURE environment variable override: $CONFIGURE" fi if [ "x$CONFIGURE" = "x" ] ; then if [ "x$VERSION_ONLY" = "xyes" ] ; then CONFIGURE=/dev/null else $ECHO $ECHO "A configure.ac or configure.in file could not be located implying" $ECHO "that the GNU Build System is at least not used in this directory. In" $ECHO "any case, there is nothing to do here without one of those files." $ECHO $ECHO "ERROR: No configure.in or configure.ac file found in `pwd`" exit 1 fi fi #################### # get project name # #################### if [ "x$PROJECT" = "x" ] ; then PROJECT="`grep AC_INIT $CONFIGURE | grep -v '.*#.*AC_INIT' | tail -${TAIL_N}1 | sed 's/^[ ]*AC_INIT(\([^,)]*\).*/\1/' | sed 's/.*\[\(.*\)\].*/\1/'`" if [ "x$PROJECT" = "xAC_INIT" ] ; then # projects might be using the older/deprecated arg-less AC_INIT .. look for AM_INIT_AUTOMAKE instead PROJECT="`grep AM_INIT_AUTOMAKE $CONFIGURE | grep -v '.*#.*AM_INIT_AUTOMAKE' | tail -${TAIL_N}1 | sed 's/^[ ]*AM_INIT_AUTOMAKE(\([^,)]*\).*/\1/' | sed 's/.*\[\(.*\)\].*/\1/'`" fi if [ "x$PROJECT" = "xAM_INIT_AUTOMAKE" ] ; then PROJECT="project" fi if [ "x$PROJECT" = "x" ] ; then PROJECT="project" fi else $ECHO "Using PROJECT environment variable override: $PROJECT" fi $ECHO "Preparing the $PROJECT build system...please wait" $ECHO ######################## # check for autoreconf # ######################## HAVE_AUTORECONF=no if [ "x$AUTORECONF" = "x" ] ; then for AUTORECONF in autoreconf ; do $VERBOSE_ECHO "Checking autoreconf version: $AUTORECONF --version" $AUTORECONF --version > /dev/null 2>&1 if [ $? = 0 ] ; then HAVE_AUTORECONF=yes break fi done else HAVE_AUTORECONF=yes $ECHO "Using AUTORECONF environment variable override: $AUTORECONF" fi ########################## # autoconf version check # ########################## _acfound=no if [ "x$AUTOCONF" = "x" ] ; then for AUTOCONF in autoconf ; do $VERBOSE_ECHO "Checking autoconf version: $AUTOCONF --version" $AUTOCONF --version > /dev/null 2>&1 if [ $? = 0 ] ; then _acfound=yes break fi done else _acfound=yes $ECHO "Using AUTOCONF environment variable override: $AUTOCONF" fi _report_error=no if [ ! "x$_acfound" = "xyes" ] ; then $ECHO "ERROR: Unable to locate GNU Autoconf." _report_error=yes else _version="`$AUTOCONF --version | head -${HEAD_N}1 | sed 's/[^0-9]*\([0-9\.][0-9\.]*\)/\1/'`" if [ "x$_version" = "x" ] ; then _version="0.0.0" fi $ECHO "Found GNU Autoconf version $_version" version_check "$AUTOCONF_VERSION" "$_version" if [ $? -ne 0 ] ; then _report_error=yes fi fi if [ "x$_report_error" = "xyes" ] ; then version_error "$AUTOCONF_VERSION" "GNU Autoconf" exit 1 fi ########################## # automake version check # ########################## _amfound=no if [ "x$AUTOMAKE" = "x" ] ; then for AUTOMAKE in automake ; do $VERBOSE_ECHO "Checking automake version: $AUTOMAKE --version" $AUTOMAKE --version > /dev/null 2>&1 if [ $? = 0 ] ; then _amfound=yes break fi done else _amfound=yes $ECHO "Using AUTOMAKE environment variable override: $AUTOMAKE" fi _report_error=no if [ ! "x$_amfound" = "xyes" ] ; then $ECHO $ECHO "ERROR: Unable to locate GNU Automake." _report_error=yes else _version="`$AUTOMAKE --version | head -${HEAD_N}1 | sed 's/[^0-9]*\([0-9\.][0-9\.]*\)/\1/'`" if [ "x$_version" = "x" ] ; then _version="0.0.0" fi $ECHO "Found GNU Automake version $_version" version_check "$AUTOMAKE_VERSION" "$_version" if [ $? -ne 0 ] ; then _report_error=yes fi fi if [ "x$_report_error" = "xyes" ] ; then version_error "$AUTOMAKE_VERSION" "GNU Automake" exit 1 fi ######################## # check for libtoolize # ######################## HAVE_LIBTOOLIZE=yes HAVE_ALT_LIBTOOLIZE=no _ltfound=no if [ "x$LIBTOOLIZE" = "x" ] ; then LIBTOOLIZE=libtoolize $VERBOSE_ECHO "Checking libtoolize version: $LIBTOOLIZE --version" $LIBTOOLIZE --version > /dev/null 2>&1 if [ ! $? = 0 ] ; then HAVE_LIBTOOLIZE=no $ECHO if [ "x$HAVE_AUTORECONF" = "xno" ] ; then $ECHO "Warning: libtoolize does not appear to be available." else $ECHO "Warning: libtoolize does not appear to be available. This means that" $ECHO "the automatic build preparation via autoreconf will probably not work." $ECHO "Preparing the build by running each step individually, however, should" $ECHO "work and will be done automatically for you if autoreconf fails." fi # look for some alternates for tool in glibtoolize libtoolize15 libtoolize14 libtoolize13 ; do $VERBOSE_ECHO "Checking libtoolize alternate: $tool --version" _glibtoolize="`$tool --version > /dev/null 2>&1`" if [ $? = 0 ] ; then $VERBOSE_ECHO "Found $tool --version" _glti="`which $tool`" if [ "x$_glti" = "x" ] ; then $VERBOSE_ECHO "Cannot find $tool with which" continue; fi if test ! -f "$_glti" ; then $VERBOSE_ECHO "Cannot use $tool, $_glti is not a file" continue; fi _gltidir="`dirname $_glti`" if [ "x$_gltidir" = "x" ] ; then $VERBOSE_ECHO "Cannot find $tool path with dirname of $_glti" continue; fi if test ! -d "$_gltidir" ; then $VERBOSE_ECHO "Cannot use $tool, $_gltidir is not a directory" continue; fi HAVE_ALT_LIBTOOLIZE=yes LIBTOOLIZE="$tool" $ECHO $ECHO "Fortunately, $tool was found which means that your system may simply" $ECHO "have a non-standard or incomplete GNU Autotools install. If you have" $ECHO "sufficient system access, it may be possible to quell this warning by" $ECHO "running:" $ECHO sudo -V > /dev/null 2>&1 if [ $? = 0 ] ; then $ECHO " sudo ln -s $_glti $_gltidir/libtoolize" $ECHO else $ECHO " ln -s $_glti $_gltidir/libtoolize" $ECHO $ECHO "Run that as root or with proper permissions to the $_gltidir directory" $ECHO fi _ltfound=yes break fi done else _ltfound=yes fi else _ltfound=yes $ECHO "Using LIBTOOLIZE environment variable override: $LIBTOOLIZE" fi ############################ # libtoolize version check # ############################ _report_error=no if [ ! "x$_ltfound" = "xyes" ] ; then $ECHO $ECHO "ERROR: Unable to locate GNU Libtool." _report_error=yes else _version="`$LIBTOOLIZE --version | head -${HEAD_N}1 | sed 's/[^0-9]*\([0-9\.][0-9\.]*\)/\1/'`" if [ "x$_version" = "x" ] ; then _version="0.0.0" fi $ECHO "Found GNU Libtool version $_version" version_check "$LIBTOOL_VERSION" "$_version" if [ $? -ne 0 ] ; then _report_error=yes fi fi if [ "x$_report_error" = "xyes" ] ; then version_error "$LIBTOOL_VERSION" "GNU Libtool" exit 1 fi ##################### # check for aclocal # ##################### if [ "x$ACLOCAL" = "x" ] ; then for ACLOCAL in aclocal ; do $VERBOSE_ECHO "Checking aclocal version: $ACLOCAL --version" $ACLOCAL --version > /dev/null 2>&1 if [ $? = 0 ] ; then break fi done else $ECHO "Using ACLOCAL environment variable override: $ACLOCAL" fi ######################## # check for autoheader # ######################## if [ "x$AUTOHEADER" = "x" ] ; then for AUTOHEADER in autoheader ; do $VERBOSE_ECHO "Checking autoheader version: $AUTOHEADER --version" $AUTOHEADER --version > /dev/null 2>&1 if [ $? = 0 ] ; then break fi done else $ECHO "Using AUTOHEADER environment variable override: $AUTOHEADER" fi ######################### # check if version only # ######################### $VERBOSE_ECHO "Checking whether to only output version information" if [ "x$VERSION_ONLY" = "xyes" ] ; then $ECHO ident $ECHO "---" $ECHO "Version requested. No preparation or configuration will be performed." exit 0 fi ################################# # PROTECT_FROM_CLOBBER FUNCTION # ################################# protect_from_clobber ( ) { PFC_INIT=1 # protect COPYING & INSTALL from overwrite by automake. the # automake force option will (inappropriately) ignore the existing # contents of a COPYING and/or INSTALL files (depending on the # version) instead of just forcing *missing* files like it does # for AUTHORS, NEWS, and README. this is broken but extremely # prevalent behavior, so we protect against it by keeping a backup # of the file that can later be restored. if test -f COPYING ; then if test -f COPYING.$$.protect_from_automake.backup ; then $VERBOSE_ECHO "Already backed up COPYING in `pwd`" else $VERBOSE_ECHO "Backing up COPYING in `pwd`" $VERBOSE_ECHO "cp -p COPYING COPYING.$$.protect_from_automake.backup" cp -p COPYING COPYING.$$.protect_from_automake.backup fi fi if test -f INSTALL ; then if test -f INSTALL.$$.protect_from_automake.backup ; then $VERBOSE_ECHO "Already backed up INSTALL in `pwd`" else $VERBOSE_ECHO "Backing up INSTALL in `pwd`" $VERBOSE_ECHO "cp -p INSTALL INSTALL.$$.protect_from_automake.backup" cp -p INSTALL INSTALL.$$.protect_from_automake.backup fi fi } ############################## # RECURSIVE_PROTECT FUNCTION # ############################## recursive_protect ( ) { # for projects using recursive configure, run the build # preparation steps for the subdirectories. this function assumes # START_PATH was set to pwd before recursion begins so that # relative paths work. # git 'r done, protect COPYING and INSTALL from being clobbered protect_from_clobber if test -d autom4te.cache ; then $VERBOSE_ECHO "Found an autom4te.cache directory, deleting it" $VERBOSE_ECHO "rm -rf autom4te.cache" rm -rf autom4te.cache fi # find configure template _configure="`locate_configure_template`" if [ "x$_configure" = "x" ] ; then return fi # $VERBOSE_ECHO "Looking for configure template found `pwd`/$_configure" # look for subdirs # $VERBOSE_ECHO "Looking for subdirs in `pwd`" _det_config_subdirs="`grep AC_CONFIG_SUBDIRS $_configure | grep -v '.*#.*AC_CONFIG_SUBDIRS' | sed 's/^[ ]*AC_CONFIG_SUBDIRS(\(.*\)).*/\1/' | sed 's/.*\[\(.*\)\].*/\1/'`" CHECK_DIRS="" for dir in $_det_config_subdirs ; do if test -d "`pwd`/$dir" ; then CHECK_DIRS="$CHECK_DIRS \"`pwd`/$dir\"" fi done # process subdirs if [ ! "x$CHECK_DIRS" = "x" ] ; then $VERBOSE_ECHO "Recursively scanning the following directories:" $VERBOSE_ECHO " $CHECK_DIRS" for dir in $CHECK_DIRS ; do $VERBOSE_ECHO "Protecting files from automake in $dir" cd "$START_PATH" eval "cd $dir" # recursively git 'r done recursive_protect done fi } # end of recursive_protect ############################# # RESTORE_CLOBBERED FUNCION # ############################# restore_clobbered ( ) { # The automake (and autoreconf by extension) -f/--force-missing # option may overwrite COPYING and INSTALL even if they do exist. # Here we restore the files if necessary. spacer=no # COPYING if test -f COPYING.$$.protect_from_automake.backup ; then if test -f COPYING ; then # compare entire content, restore if needed if test "x`cat COPYING`" != "x`cat COPYING.$$.protect_from_automake.backup`" ; then if test "x$spacer" = "xno" ; then $VERBOSE_ECHO spacer=yes fi # restore the backup $VERBOSE_ECHO "Restoring COPYING from backup (automake -f likely clobbered it)" $VERBOSE_ECHO "rm -f COPYING" rm -f COPYING $VERBOSE_ECHO "mv COPYING.$$.protect_from_automake.backup COPYING" mv COPYING.$$.protect_from_automake.backup COPYING fi # check contents elif test -f COPYING.$$.protect_from_automake.backup ; then $VERBOSE_ECHO "mv COPYING.$$.protect_from_automake.backup COPYING" mv COPYING.$$.protect_from_automake.backup COPYING fi # -f COPYING # just in case $VERBOSE_ECHO "rm -f COPYING.$$.protect_from_automake.backup" rm -f COPYING.$$.protect_from_automake.backup fi # -f COPYING.$$.protect_from_automake.backup # INSTALL if test -f INSTALL.$$.protect_from_automake.backup ; then if test -f INSTALL ; then # compare entire content, restore if needed if test "x`cat INSTALL`" != "x`cat INSTALL.$$.protect_from_automake.backup`" ; then if test "x$spacer" = "xno" ; then $VERBOSE_ECHO spacer=yes fi # restore the backup $VERBOSE_ECHO "Restoring INSTALL from backup (automake -f likely clobbered it)" $VERBOSE_ECHO "rm -f INSTALL" rm -f INSTALL $VERBOSE_ECHO "mv INSTALL.$$.protect_from_automake.backup INSTALL" mv INSTALL.$$.protect_from_automake.backup INSTALL fi # check contents elif test -f INSTALL.$$.protect_from_automake.backup ; then $VERBOSE_ECHO "mv INSTALL.$$.protect_from_automake.backup INSTALL" mv INSTALL.$$.protect_from_automake.backup INSTALL fi # -f INSTALL # just in case $VERBOSE_ECHO "rm -f INSTALL.$$.protect_from_automake.backup" rm -f INSTALL.$$.protect_from_automake.backup fi # -f INSTALL.$$.protect_from_automake.backup CONFIGURE="`locate_configure_template`" if [ "x$CONFIGURE" = "x" ] ; then return fi _aux_dir="`grep AC_CONFIG_AUX_DIR $CONFIGURE | grep -v '.*#.*AC_CONFIG_AUX_DIR' | tail -${TAIL_N}1 | sed 's/^[ ]*AC_CONFIG_AUX_DIR(\(.*\)).*/\1/' | sed 's/.*\[\(.*\)\].*/\1/'`" if test ! -d "$_aux_dir" ; then _aux_dir=. fi for file in config.guess config.sub ltmain.sh ; do if test -f "${_aux_dir}/${file}" ; then $VERBOSE_ECHO "rm -f \"${_aux_dir}/${file}.backup\"" rm -f "${_aux_dir}/${file}.backup" fi done } # end of restore_clobbered ############################## # RECURSIVE_RESTORE FUNCTION # ############################## recursive_restore ( ) { # restore COPYING and INSTALL from backup if they were clobbered # for each directory recursively. # git 'r undone restore_clobbered # find configure template _configure="`locate_configure_template`" if [ "x$_configure" = "x" ] ; then return fi # look for subdirs _det_config_subdirs="`grep AC_CONFIG_SUBDIRS $_configure | grep -v '.*#.*AC_CONFIG_SUBDIRS' | sed 's/^[ ]*AC_CONFIG_SUBDIRS(\(.*\)).*/\1/' | sed 's/.*\[\(.*\)\].*/\1/'`" CHECK_DIRS="" for dir in $_det_config_subdirs ; do if test -d "`pwd`/$dir" ; then CHECK_DIRS="$CHECK_DIRS \"`pwd`/$dir\"" fi done # process subdirs if [ ! "x$CHECK_DIRS" = "x" ] ; then $VERBOSE_ECHO "Recursively scanning the following directories:" $VERBOSE_ECHO " $CHECK_DIRS" for dir in $CHECK_DIRS ; do $VERBOSE_ECHO "Checking files for automake damage in $dir" cd "$START_PATH" eval "cd $dir" # recursively git 'r undone recursive_restore done fi } # end of recursive_restore ####################### # INITIALIZE FUNCTION # ####################### initialize ( ) { # this routine performs a variety of directory-specific # initializations. some are sanity checks, some are preventive, # and some are necessary setup detection. # # this function sets: # CONFIGURE # SEARCH_DIRS # CONFIG_SUBDIRS ################################## # check for a configure template # ################################## CONFIGURE="`locate_configure_template`" if [ "x$CONFIGURE" = "x" ] ; then $ECHO $ECHO "A configure.ac or configure.in file could not be located implying" $ECHO "that the GNU Build System is at least not used in this directory. In" $ECHO "any case, there is nothing to do here without one of those files." $ECHO $ECHO "ERROR: No configure.in or configure.ac file found in `pwd`" exit 1 fi ##################### # detect an aux dir # ##################### _aux_dir="`grep AC_CONFIG_AUX_DIR $CONFIGURE | grep -v '.*#.*AC_CONFIG_AUX_DIR' | tail -${TAIL_N}1 | sed 's/^[ ]*AC_CONFIG_AUX_DIR(\(.*\)).*/\1/' | sed 's/.*\[\(.*\)\].*/\1/'`" if test ! -d "$_aux_dir" ; then _aux_dir=. else $VERBOSE_ECHO "Detected auxillary directory: $_aux_dir" fi ################################ # detect a recursive configure # ################################ CONFIG_SUBDIRS="" _det_config_subdirs="`grep AC_CONFIG_SUBDIRS $CONFIGURE | grep -v '.*#.*AC_CONFIG_SUBDIRS' | sed 's/^[ ]*AC_CONFIG_SUBDIRS(\(.*\)).*/\1/' | sed 's/.*\[\(.*\)\].*/\1/'`" for dir in $_det_config_subdirs ; do if test -d "`pwd`/$dir" ; then $VERBOSE_ECHO "Detected recursive configure directory: `pwd`/$dir" CONFIG_SUBDIRS="$CONFIG_SUBDIRS `pwd`/$dir" fi done ########################################## # make sure certain required files exist # ########################################## for file in AUTHORS COPYING ChangeLog INSTALL NEWS README ; do if test ! -f $file ; then $VERBOSE_ECHO "Touching ${file} since it does not exist" touch $file fi done ################################################## # make sure certain generated files do not exist # ################################################## for file in config.guess config.sub ltmain.sh ; do if test -f "${_aux_dir}/${file}" ; then $VERBOSE_ECHO "mv -f \"${_aux_dir}/${file}\" \"${_aux_dir}/${file}.backup\"" mv -f "${_aux_dir}/${file}" "${_aux_dir}/${file}.backup" fi done ############################ # search alternate m4 dirs # ############################ SEARCH_DIRS="" for dir in m4 ; do if [ -d $dir ] ; then $VERBOSE_ECHO "Found extra aclocal search directory: $dir" SEARCH_DIRS="$SEARCH_DIRS -I $dir" fi done ###################################### # remove any previous build products # ###################################### if test -d autom4te.cache ; then $VERBOSE_ECHO "Found an autom4te.cache directory, deleting it" $VERBOSE_ECHO "rm -rf autom4te.cache" rm -rf autom4te.cache fi # tcl/tk (and probably others) have a customized aclocal.m4, so can't delete it # if test -f aclocal.m4 ; then # $VERBOSE_ECHO "Found an aclocal.m4 file, deleting it" # $VERBOSE_ECHO "rm -f aclocal.m4" # rm -f aclocal.m4 # fi } # end of initialize() ############## # initialize # ############## # stash path START_PATH="`pwd`" # Before running autoreconf or manual steps, some prep detection work # is necessary or useful. Only needs to occur once per directory, but # does need to traverse the entire subconfigure hierarchy to protect # files from being clobbered even by autoreconf. recursive_protect # start from where we started cd "$START_PATH" # get ready to process initialize ############################################ # prepare build via autoreconf or manually # ############################################ reconfigure_manually=no if [ "x$HAVE_AUTORECONF" = "xyes" ] ; then $ECHO $ECHO $ECHO_N "Automatically preparing build ... $ECHO_C" $VERBOSE_ECHO "$AUTORECONF $SEARCH_DIRS $AUTORECONF_OPTIONS" autoreconf_output="`$AUTORECONF $SEARCH_DIRS $AUTORECONF_OPTIONS 2>&1`" ret=$? $VERBOSE_ECHO "$autoreconf_output" if [ ! $ret = 0 ] ; then if [ "x$HAVE_ALT_LIBTOOLIZE" = "xyes" ] ; then if [ ! "x`echo \"$autoreconf_output\" | grep libtoolize | grep \"No such file or directory\"`" = "x" ] ; then $ECHO $ECHO "Warning: autoreconf failed but due to what is usually a common libtool" $ECHO "misconfiguration issue. This problem is encountered on systems that" $ECHO "have installed libtoolize under a different name without providing a" $ECHO "symbolic link or without setting the LIBTOOLIZE environment variable." $ECHO $ECHO "Restarting the preparation steps with LIBTOOLIZE set to $LIBTOOLIZE" export LIBTOOLIZE RUN_RECURSIVE=no export RUN_RECURSIVE untrap_abnormal $VERBOSE_ECHO sh $AUTOGEN_SH "$1" "$2" "$3" "$4" "$5" "$6" "$7" "$8" "$9" sh "$AUTOGEN_SH" "$1" "$2" "$3" "$4" "$5" "$6" "$7" "$8" "$9" exit $? fi fi $ECHO "Warning: $AUTORECONF failed" if test -f ltmain.sh ; then $ECHO "libtoolize being run by autoreconf is not creating ltmain.sh in the auxillary directory like it should" fi $ECHO "Attempting to run the preparation steps individually" reconfigure_manually=yes fi else reconfigure_manually=yes fi ############################ # LIBTOOL_FAILURE FUNCTION # ############################ libtool_failure ( ) { # libtool is rather error-prone in comparison to the other # autotools and this routine attempts to compensate for some # common failures. the output after a libtoolize failure is # parsed for an error related to AC_PROG_LIBTOOL and if found, we # attempt to inject a project-provided libtool.m4 file. _autoconf_output="$1" if [ "x$RUN_RECURSIVE" = "xno" ] ; then # we already tried the libtool.m4, don't try again return 1 fi if test -f "$LIBTOOL_M4" ; then found_libtool="`$ECHO $_autoconf_output | grep AC_PROG_LIBTOOL`" if test ! "x$found_libtool" = "x" ; then if test -f acinclude.m4 ; then rm -f acinclude.m4.$$.backup $VERBOSE_ECHO "cat acinclude.m4 > acinclude.m4.$$.backup" cat acinclude.m4 > acinclude.m4.$$.backup fi $VERBOSE_ECHO "cat \"$LIBTOOL_M4\" >> acinclude.m4" chmod u+w acinclude.m4 cat "$LIBTOOL_M4" >> acinclude.m4 # don't keep doing this RUN_RECURSIVE=no export RUN_RECURSIVE untrap_abnormal $ECHO $ECHO "Restarting the preparation steps with libtool macros in acinclude.m4" $VERBOSE_ECHO sh $AUTOGEN_SH "$1" "$2" "$3" "$4" "$5" "$6" "$7" "$8" "$9" sh "$AUTOGEN_SH" "$1" "$2" "$3" "$4" "$5" "$6" "$7" "$8" "$9" exit $? fi fi } ########################### # MANUAL_AUTOGEN FUNCTION # ########################### manual_autogen ( ) { ################################################## # Manual preparation steps taken are as follows: # # aclocal [-I m4] # # libtoolize --automake -c -f # # aclocal [-I m4] # # autoconf -f # # autoheader # # automake -a -c -f # ################################################## ########### # aclocal # ########### $VERBOSE_ECHO "$ACLOCAL $SEARCH_DIRS $ACLOCAL_OPTIONS" aclocal_output="`$ACLOCAL $SEARCH_DIRS $ACLOCAL_OPTIONS 2>&1`" ret=$? $VERBOSE_ECHO "$aclocal_output" if [ ! $ret = 0 ] ; then $ECHO "ERROR: $ACLOCAL failed" && exit 2 ; fi ############## # libtoolize # ############## need_libtoolize=no for feature in AC_PROG_LIBTOOL LT_INIT ; do $VERBOSE_ECHO "Searching for $feature in $CONFIGURE" found="`grep \"^$feature.*\" $CONFIGURE`" if [ ! "x$found" = "x" ] ; then need_libtoolize=yes break fi done if [ "x$need_libtoolize" = "xyes" ] ; then if [ "x$HAVE_LIBTOOLIZE" = "xyes" ] ; then $VERBOSE_ECHO "$LIBTOOLIZE $LIBTOOLIZE_OPTIONS" libtoolize_output="`$LIBTOOLIZE $LIBTOOLIZE_OPTIONS 2>&1`" ret=$? $VERBOSE_ECHO "$libtoolize_output" if [ ! $ret = 0 ] ; then $ECHO "ERROR: $LIBTOOLIZE failed" && exit 2 ; fi else if [ "x$HAVE_ALT_LIBTOOLIZE" = "xyes" ] ; then $VERBOSE_ECHO "$LIBTOOLIZE $ALT_LIBTOOLIZE_OPTIONS" libtoolize_output="`$LIBTOOLIZE $ALT_LIBTOOLIZE_OPTIONS 2>&1`" ret=$? $VERBOSE_ECHO "$libtoolize_output" if [ ! $ret = 0 ] ; then $ECHO "ERROR: $LIBTOOLIZE failed" && exit 2 ; fi fi fi ########### # aclocal # ########### # re-run again as instructed by libtoolize $VERBOSE_ECHO "$ACLOCAL $SEARCH_DIRS $ACLOCAL_OPTIONS" aclocal_output="`$ACLOCAL $SEARCH_DIRS $ACLOCAL_OPTIONS 2>&1`" ret=$? $VERBOSE_ECHO "$aclocal_output" # libtoolize might put ltmain.sh in the wrong place if test -f ltmain.sh ; then if test ! -f "${_aux_dir}/ltmain.sh" ; then $ECHO $ECHO "Warning: $LIBTOOLIZE is creating ltmain.sh in the wrong directory" $ECHO $ECHO "Fortunately, the problem can be worked around by simply copying the" $ECHO "file to the appropriate location (${_aux_dir}/). This has been done for you." $ECHO $VERBOSE_ECHO "cp -p ltmain.sh \"${_aux_dir}/ltmain.sh\"" cp -p ltmain.sh "${_aux_dir}/ltmain.sh" $ECHO $ECHO_N "Continuing build preparation ... $ECHO_C" fi fi # ltmain.sh fi # need_libtoolize ############ # autoconf # ############ $VERBOSE_ECHO $VERBOSE_ECHO "$AUTOCONF $AUTOCONF_OPTIONS" autoconf_output="`$AUTOCONF $AUTOCONF_OPTIONS 2>&1`" ret=$? $VERBOSE_ECHO "$autoconf_output" if [ ! $ret = 0 ] ; then # retry without the -f and check for usage of macros that are too new ac2_59_macros="AC_C_RESTRICT AC_INCLUDES_DEFAULT AC_LANG_ASSERT AC_LANG_WERROR AS_SET_CATFILE" ac2_55_macros="AC_COMPILER_IFELSE AC_FUNC_MBRTOWC AC_HEADER_STDBOOL AC_LANG_CONFTEST AC_LANG_SOURCE AC_LANG_PROGRAM AC_LANG_CALL AC_LANG_FUNC_TRY_LINK AC_MSG_FAILURE AC_PREPROC_IFELSE" ac2_54_macros="AC_C_BACKSLASH_A AC_CONFIG_LIBOBJ_DIR AC_GNU_SOURCE AC_PROG_EGREP AC_PROG_FGREP AC_REPLACE_FNMATCH AC_FUNC_FNMATCH_GNU AC_FUNC_REALLOC AC_TYPE_MBSTATE_T" macros_to_search="" ac_major="`echo ${AUTOCONF_VERSION}. | cut -d. -f1 | sed 's/[^0-9]//g'`" ac_minor="`echo ${AUTOCONF_VERSION}. | cut -d. -f2 | sed 's/[^0-9]//g'`" if [ $ac_major -lt 2 ] ; then macros_to_search="$ac2_59_macros $ac2_55_macros $ac2_54_macros" else if [ $ac_minor -lt 54 ] ; then macros_to_search="$ac2_59_macros $ac2_55_macros $ac2_54_macros" elif [ $ac_minor -lt 55 ] ; then macros_to_search="$ac2_59_macros $ac2_55_macros" elif [ $ac_minor -lt 59 ] ; then macros_to_search="$ac2_59_macros" fi fi configure_ac_macros=__none__ for feature in $macros_to_search ; do $VERBOSE_ECHO "Searching for $feature in $CONFIGURE" found="`grep \"^$feature.*\" $CONFIGURE`" if [ ! "x$found" = "x" ] ; then if [ "x$configure_ac_macros" = "x__none__" ] ; then configure_ac_macros="$feature" else configure_ac_macros="$feature $configure_ac_macros" fi fi done if [ ! "x$configure_ac_macros" = "x__none__" ] ; then $ECHO $ECHO "Warning: Unsupported macros were found in $CONFIGURE" $ECHO $ECHO "The `echo $CONFIGURE | basename` file was scanned in order to determine if any" $ECHO "unsupported macros are used that exceed the minimum version" $ECHO "settings specified within this file. As such, the following macros" $ECHO "should be removed from configure.ac or the version numbers in this" $ECHO "file should be increased:" $ECHO $ECHO "$configure_ac_macros" $ECHO $ECHO $ECHO_N "Ignorantly continuing build preparation ... $ECHO_C" fi ################### # autoconf, retry # ################### $VERBOSE_ECHO $VERBOSE_ECHO "$AUTOCONF" autoconf_output="`$AUTOCONF 2>&1`" ret=$? $VERBOSE_ECHO "$autoconf_output" if [ ! $ret = 0 ] ; then # test if libtool is busted libtool_failure "$autoconf_output" # let the user know what went wrong cat <. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Alexandre Oliva . case $1 in '') echo "$0: No command. Try \`$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: depcomp [--help] [--version] PROGRAM [ARGS] Run PROGRAMS ARGS to compile a file, generating dependencies as side-effects. Environment variables: depmode Dependency tracking mode. source Source file read by `PROGRAMS ARGS'. object Object file output by `PROGRAMS ARGS'. DEPDIR directory where to store dependencies. depfile Dependency file to output. tmpdepfile Temporary file to use when outputing dependencies. libtool Whether libtool is used (yes/no). Report bugs to . EOF exit $? ;; -v | --v*) echo "depcomp $scriptversion" exit $? ;; esac if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 fi # Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. depfile=${depfile-`echo "$object" | sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case # here, because this file can only contain one case statement. if test "$depmode" = hp; then # HP compiler uses -M and no extra arg. gccflag=-M depmode=gcc fi if test "$depmode" = dashXmstdout; then # This is just like dashmstdout with a different argument. dashmflag=-xM depmode=dashmstdout fi cygpath_u="cygpath -u -f -" if test "$depmode" = msvcmsys; then # This is just like msvisualcpp but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u="sed s,\\\\\\\\,/,g" depmode=msvisualcpp fi case "$depmode" in gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. ## Unfortunately, FreeBSD c89 acceptance of flags depends upon ## the command line argument order; so add the flags where they ## appear in depend2.am. Note that the slowdown incurred here ## affects only configure: in makefiles, %FASTDEP% shortcuts this. for arg do case $arg in -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; *) set fnord "$@" "$arg" ;; esac shift # fnord shift # $arg done "$@" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ## -MM, not -M (despite what the docs say). ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then gccflag=-MD, fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ## The second -e expression handles DOS-style file names with drive letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the `deleted header file' problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. tr ' ' ' ' < "$tmpdepfile" | ## Some versions of gcc put a space before the `:'. On the theory ## that the space means something, we add a space to the output as ## well. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; sgi) if test "$libtool" = yes; then "$@" "-Wp,-MDupdate,$tmpdepfile" else "$@" -MDupdate "$tmpdepfile" fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; # the IRIX cc adds comments like `#:fec' to the end of the # dependency line. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ tr ' ' ' ' >> "$depfile" echo >> "$depfile" # The second pass generates a dummy entry for each header file. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> "$depfile" else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. In older versions, this file always lives in the # current directory. Also, the AIX compiler puts `$object:' at the # start of each line; $object doesn't have directory information. # Version 6 uses the directory in both cases. dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` test "x$dir" = "x$object" && dir= base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then tmpdepfile1=$dir$base.u tmpdepfile2=$base.u tmpdepfile3=$dir.libs/$base.u "$@" -Wc,-M else tmpdepfile1=$dir$base.u tmpdepfile2=$dir$base.u tmpdepfile3=$dir$base.u "$@" -M fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then # Each line is of the form `foo.o: dependent.h'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" # That's a tab and a space in the []. sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; icc) # Intel's C compiler understands `-MD -MF file'. However on # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c # ICC 7.0 will fill foo.d with something like # foo.o: sub/foo.c # foo.o: sub/foo.h # which is wrong. We want: # sub/foo.o: sub/foo.c # sub/foo.o: sub/foo.h # sub/foo.c: # sub/foo.h: # ICC 7.1 will output # foo.o: sub/foo.c sub/foo.h # and will wrap long lines using \ : # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... "$@" -MD -MF "$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each line is of the form `foo.o: dependent.h', # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this invocation # correctly. Breaking it into two sed invocations is a workaround. sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp2) # The "hp" stanza above does not work with aCC (C++) and HP's ia64 # compilers, which have integrated preprocessors. The correct option # to use with these is +Maked; it writes dependencies to a file named # 'foo.d', which lands next to the object file, wherever that # happens to be. # Much of this is similar to the tru64 case; see comments there. dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` test "x$dir" = "x$object" && dir= base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then tmpdepfile1=$dir$base.d tmpdepfile2=$dir.libs/$base.d "$@" -Wc,+Maked else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d "$@" +Maked fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" # Add `dependent.h:' lines. sed -ne '2,${ s/^ *// s/ \\*$// s/$/:/ p }' "$tmpdepfile" >> "$depfile" else echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" "$tmpdepfile2" ;; tru64) # The Tru64 compiler uses -MD to generate dependencies as a side # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put # dependencies in `foo.d' instead, so we check for that too. # Subdirectories are respected. dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` test "x$dir" = "x$object" && dir= base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then # With Tru64 cc, shared objects can also be used to make a # static library. This mechanism is used in libtool 1.4 series to # handle both shared and static libraries in a single compilation. # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. # # With libtool 1.5 this exception was removed, and libtool now # generates 2 separate objects for the 2 libraries. These two # compilations output dependencies in $dir.libs/$base.o.d and # in $dir$base.o.d. We have to check for both files, because # one of the two compilations can be disabled. We should prefer # $dir$base.o.d over $dir.libs/$base.o.d because the latter is # automatically cleaned when .libs/ is deleted, while ignoring # the former would cause a distcleancheck panic. tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 tmpdepfile2=$dir$base.o.d # libtool 1.5 tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 "$@" -Wc,-MD else tmpdepfile1=$dir$base.o.d tmpdepfile2=$dir$base.d tmpdepfile3=$dir$base.d tmpdepfile4=$dir$base.d "$@" -MD fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" # That's a tab and a space in the []. sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" else echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; #nosideeffect) # This comment above is used by automake to tell side-effect # dependency tracking mechanisms from slower ones. dashmstdout) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout, regardless of -o. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove `-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done test -z "$dashmflag" && dashmflag=-M # Require at least two characters before searching for `:' # in the target name. This is to cope with DOS-style filenames: # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. "$@" $dashmflag | sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" tr ' ' ' ' < "$tmpdepfile" | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; dashXmstdout) # This case only exists to satisfy depend.m4. It is never actually # run, as this mode is specially recognized in the preamble. exit 1 ;; makedepend) "$@" || exit $? # Remove any Libtool call if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # X makedepend shift cleared=no eat=no for arg do case $cleared in no) set ""; shift cleared=yes ;; esac if test $eat = yes; then eat=no continue fi case "$arg" in -D*|-I*) set fnord "$@" "$arg"; shift ;; # Strip any option that makedepend may not understand. Remove # the object too, otherwise makedepend will parse it as a source file. -arch) eat=yes ;; -*|$object) ;; *) set fnord "$@" "$arg"; shift ;; esac done obj_suffix=`echo "$object" | sed 's/^.*\././'` touch "$tmpdepfile" ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" sed '1,2d' "$tmpdepfile" | tr ' ' ' ' | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; cpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove `-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done "$@" -E | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; msvisualcpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi IFS=" " for arg do case "$arg" in -o) shift ;; $object) shift ;; "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") set fnord "$@" shift shift ;; *) set fnord "$@" "$arg" shift shift ;; esac done "$@" -E 2>/dev/null | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" echo " " >> "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; msvcmsys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; none) exec "$@" ;; *) echo "Unknown depmode $depmode" 1>&2 exit 1 ;; esac exit 0 # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: ddpt-0.92/NEWS0000644000175000017500000000004511446031070012065 0ustar douggdouggSee the ChangeLog and README* files. ddpt-0.92/config.guess0000755000175000017500000012763711511200143013717 0ustar douggdougg#! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 # Free Software Foundation, Inc. timestamp='2009-12-30' # This file 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 of the License, 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., 51 Franklin Street - Fifth Floor, Boston, MA # 02110-1301, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Per Bothner. Please send patches (context # diff format) to and include a ChangeLog # entry. # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and # exits with 0. Otherwise, it exits with 1. # # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ; set_cc_for_build= ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently, or will in the future. case "${UNAME_MACHINE_ARCH}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "${UNAME_VERSION}" in Debian*) release='-gnu' ;; *) release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; *:SolidBSD:*:*) echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} exit ;; macppc:MirBSD:*:*) echo powerpc-unknown-mirbsd${UNAME_RELEASE} exit ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE="alpha" ;; "EV4.5 (21064)") UNAME_MACHINE="alpha" ;; "LCA4 (21066/21068)") UNAME_MACHINE="alpha" ;; "EV5 (21164)") UNAME_MACHINE="alphaev5" ;; "EV5.6 (21164A)") UNAME_MACHINE="alphaev56" ;; "EV5.6 (21164PC)") UNAME_MACHINE="alphapca56" ;; "EV5.7 (21164PC)") UNAME_MACHINE="alphapca57" ;; "EV6 (21264)") UNAME_MACHINE="alphaev6" ;; "EV6.7 (21264A)") UNAME_MACHINE="alphaev67" ;; "EV6.8CB (21264C)") UNAME_MACHINE="alphaev68" ;; "EV6.8AL (21264B)") UNAME_MACHINE="alphaev68" ;; "EV6.8CX (21264D)") UNAME_MACHINE="alphaev68" ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE="alphaev69" ;; "EV7 (21364)") UNAME_MACHINE="alphaev7" ;; "EV7.9 (21364A)") UNAME_MACHINE="alphaev79" ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` exit ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition exit ;; *:z/VM:*:*) echo s390-ibm-zvmoe exit ;; *:OS400:*:*) echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit ;; arm:riscos:*:*|arm:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) echo i386-pc-auroraux${UNAME_RELEASE} exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) eval $set_cc_for_build SUN_ARCH="i386" # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH="x86_64" fi fi echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`$dummy $dummyarg` && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos${UNAME_RELEASE} exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` then echo "$SYSTEM_NAME" else echo rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit ;; *:AIX:*:[456]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in 32) HP_ARCH="hppa2.0n" ;; 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 esac ;; esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ ${HP_ARCH} = "hppa2.0w" ] then eval $set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then HP_ARCH="hppa2.0w" else HP_ARCH="hppa64" fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) case ${UNAME_MACHINE} in pc98) echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; amd64) echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; *:Interix*:*) case ${UNAME_MACHINE} in x86) echo i586-pc-interix${UNAME_RELEASE} exit ;; authenticamd | genuineintel | EM64T) echo x86_64-unknown-interix${UNAME_RELEASE} exit ;; IA64) echo ia64-unknown-interix${UNAME_RELEASE} exit ;; esac ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; 8664:Windows_NT:*) echo x86_64-pc-mks exit ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i586-pc-interix exit ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; *:GNU:*:*) # the GNU system echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} exit ;; arm*:Linux:*:*) eval $set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then echo ${UNAME_MACHINE}-unknown-linux-gnu else echo ${UNAME_MACHINE}-unknown-linux-gnueabi fi exit ;; avr32*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; cris:Linux:*:*) echo cris-axis-linux-gnu exit ;; crisv32:Linux:*:*) echo crisv32-axis-linux-gnu exit ;; frv:Linux:*:*) echo frv-unknown-linux-gnu exit ;; i*86:Linux:*:*) LIBC=gnu eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __dietlibc__ LIBC=dietlibc #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` echo "${UNAME_MACHINE}-pc-linux-${LIBC}" exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; mips:Linux:*:* | mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef ${UNAME_MACHINE} #undef ${UNAME_MACHINE}el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=${UNAME_MACHINE}el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=${UNAME_MACHINE} #else CPU= #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } ;; or32:Linux:*:*) echo or32-unknown-linux-gnu exit ;; padre:Linux:*:*) echo sparc-unknown-linux-gnu exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-gnu exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-gnu ;; PA8*) echo hppa2.0-unknown-linux-gnu ;; *) echo hppa-unknown-linux-gnu ;; esac exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-gnu exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-gnu exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-gnu exit ;; x86_64:Linux:*:*) echo x86_64-unknown-linux-gnu exit ;; xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop exit ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos exit ;; i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configury will decide that # this is a cross-build. echo i586-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; paragon:*:*:*) echo i860-intel-osf1 exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. echo ${UNAME_MACHINE}-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. echo i586-pc-haiku exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit ;; SX-7:SUPER-UX:*:*) echo sx7-nec-superux${UNAME_RELEASE} exit ;; SX-8:SUPER-UX:*:*) echo sx8-nec-superux${UNAME_RELEASE} exit ;; SX-8R:SUPER-UX:*:*) echo sx8r-nec-superux${UNAME_RELEASE} exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown case $UNAME_PROCESSOR in i386) eval $set_cc_for_build if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then UNAME_PROCESSOR="x86_64" fi fi ;; unknown) UNAME_PROCESSOR=powerpc ;; esac echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = "x86"; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NSE-?:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; NSR-?:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = "386"; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit ;; *:ITS:*:*) echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; esac ;; *:XENIX:*:SysV) echo i386-pc-xenix exit ;; i*86:skyos:*:*) echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' exit ;; i*86:rdos:*:*) echo ${UNAME_MACHINE}-pc-rdos exit ;; i*86:AROS:*:*) echo ${UNAME_MACHINE}-pc-aros exit ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 eval $set_cc_for_build cat >$dummy.c < # include #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (__arm) && defined (__acorn) && defined (__unix) printf ("arm-acorn-riscix\n"); exit (0); #endif #if defined (hp300) && !defined (hpux) printf ("m68k-hp-bsd\n"); exit (0); #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) # if !defined (ultrix) # include # if defined (BSD) # if BSD == 43 printf ("vax-dec-bsd4.3\n"); exit (0); # else # if BSD == 199006 printf ("vax-dec-bsd4.3reno\n"); exit (0); # else printf ("vax-dec-bsd\n"); exit (0); # endif # endif # else printf ("vax-dec-bsd\n"); exit (0); # endif # else printf ("vax-dec-ultrix\n"); exit (0); # endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } # Convex versions that predate uname can use getsysinfo(1) if [ -x /usr/convex/getsysinfo ] then case `getsysinfo -f cpu_type` in c1*) echo c1-convex-bsd exit ;; c2*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; c34*) echo c34-convex-bsd exit ;; c38*) echo c38-convex-bsd exit ;; c4*) echo c4-convex-bsd exit ;; esac fi cat >&2 < in order to provide the needed information to handle your system. config.guess timestamp = $timestamp uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: ddpt-0.92/TODO0000644000175000017500000000036411440271346012070 0ustar douggdouggSome suggestions: - look into supporting the SCSI EXTENDED COPY command. Syntax should be interesting [20090320] - cope with MEDIUM/HARDWARE ERROR when no valid INFO field given and bpt>1 . Broken devices are out there [20100903] ddpt-0.92/missing0000755000175000017500000002623311446031366013004 0ustar douggdougg#! /bin/sh # Common stub for a few missing GNU programs while installing. scriptversion=2009-04-28.21; # UTC # Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006, # 2008, 2009 Free Software Foundation, Inc. # Originally by Fran,cois Pinard , 1996. # 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, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try \`$0 --help' for more information" exit 1 fi run=: sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' sed_minuso='s/.* -o \([^ ]*\).*/\1/p' # In the cases where this matters, `missing' is being run in the # srcdir already. if test -f configure.ac; then configure_ac=configure.ac else configure_ac=configure.in fi msg="missing on your system" case $1 in --run) # Try to run requested program, and just exit if it succeeds. run= shift "$@" && exit 0 # Exit code 63 means version mismatch. This often happens # when the user try to use an ancient version of a tool on # a file that requires a minimum version. In this case we # we should proceed has if the program had been absent, or # if --run hadn't been passed. if test $? = 63; then run=: msg="probably too old" fi ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an error status if there is no known handling for PROGRAM. Options: -h, --help display this help and exit -v, --version output version information and exit --run try to run the given command, and emulate it if it fails Supported PROGRAM values: aclocal touch file \`aclocal.m4' autoconf touch file \`configure' autoheader touch file \`config.h.in' autom4te touch the output file, or create a stub one automake touch all \`Makefile.in' files bison create \`y.tab.[ch]', if possible, from existing .[ch] flex create \`lex.yy.c', if possible, from existing .c help2man touch the output file lex create \`lex.yy.c', if possible, from existing .c makeinfo touch the output file tar try tar, gnutar, gtar, then tar without non-portable flags yacc create \`y.tab.[ch]', if possible, from existing .[ch] Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and \`g' are ignored when checking the name. Send bug reports to ." exit $? ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing $scriptversion (GNU Automake)" exit $? ;; -*) echo 1>&2 "$0: Unknown \`$1' option" echo 1>&2 "Try \`$0 --help' for more information" exit 1 ;; esac # normalize program name to check for. program=`echo "$1" | sed ' s/^gnu-//; t s/^gnu//; t s/^g//; t'` # Now exit if we have it, but it failed. Also exit now if we # don't have it and --version was passed (most likely to detect # the program). This is about non-GNU programs, so use $1 not # $program. case $1 in lex*|yacc*) # Not GNU programs, they don't have --version. ;; tar*) if test -n "$run"; then echo 1>&2 "ERROR: \`tar' requires --run" exit 1 elif test "x$2" = "x--version" || test "x$2" = "x--help"; then exit 1 fi ;; *) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 elif test "x$2" = "x--version" || test "x$2" = "x--help"; then # Could not run --version or --help. This is probably someone # running `$TOOL --version' or `$TOOL --help' to check whether # $TOOL exists and not knowing $TOOL uses missing. exit 1 fi ;; esac # If it does not exist, or fails to run (possibly an outdated version), # try to emulate it. case $program in aclocal*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." touch aclocal.m4 ;; autoconf*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." touch configure ;; autoheader*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`acconfig.h' or \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` test -z "$files" && files="config.h" touch_files= for f in $files; do case $f in *:*) touch_files="$touch_files "`echo "$f" | sed -e 's/^[^:]*://' -e 's/:.*//'`;; *) touch_files="$touch_files $f.in";; esac done touch $touch_files ;; automake*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." find . -type f -name Makefile.am -print | sed 's/\.am$/.in/' | while read f; do touch "$f"; done ;; autom4te*) echo 1>&2 "\ WARNING: \`$1' is needed, but is $msg. You might have modified some files without having the proper tools for further handling them. You can get \`$1' as part of \`Autoconf' from any GNU archive site." file=`echo "$*" | sed -n "$sed_output"` test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` if test -f "$file"; then touch $file else test -z "$file" || exec >$file echo "#! /bin/sh" echo "# Created by GNU Automake missing as a replacement of" echo "# $ $@" echo "exit 0" chmod +x $file exit 1 fi ;; bison*|yacc*) echo 1>&2 "\ WARNING: \`$1' $msg. You should only need it if you modified a \`.y' file. You may need the \`Bison' package in order for those modifications to take effect. You can get \`Bison' from any GNU archive site." rm -f y.tab.c y.tab.h if test $# -ne 1; then eval LASTARG="\${$#}" case $LASTARG in *.y) SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` if test -f "$SRCFILE"; then cp "$SRCFILE" y.tab.c fi SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` if test -f "$SRCFILE"; then cp "$SRCFILE" y.tab.h fi ;; esac fi if test ! -f y.tab.h; then echo >y.tab.h fi if test ! -f y.tab.c; then echo 'main() { return 0; }' >y.tab.c fi ;; lex*|flex*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a \`.l' file. You may need the \`Flex' package in order for those modifications to take effect. You can get \`Flex' from any GNU archive site." rm -f lex.yy.c if test $# -ne 1; then eval LASTARG="\${$#}" case $LASTARG in *.l) SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` if test -f "$SRCFILE"; then cp "$SRCFILE" lex.yy.c fi ;; esac fi if test ! -f lex.yy.c; then echo 'main() { return 0; }' >lex.yy.c fi ;; help2man*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a dependency of a manual page. You may need the \`Help2man' package in order for those modifications to take effect. You can get \`Help2man' from any GNU archive site." file=`echo "$*" | sed -n "$sed_output"` test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` if test -f "$file"; then touch $file else test -z "$file" || exec >$file echo ".ab help2man is required to generate this page" exit $? fi ;; makeinfo*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a \`.texi' or \`.texinfo' file, or any other file indirectly affecting the aspect of the manual. The spurious call might also be the consequence of using a buggy \`make' (AIX, DU, IRIX). You might want to install the \`Texinfo' package or the \`GNU make' package. Grab either from any GNU archive site." # The file to touch is that specified with -o ... file=`echo "$*" | sed -n "$sed_output"` test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` if test -z "$file"; then # ... or it is the one specified with @setfilename ... infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` file=`sed -n ' /^@setfilename/{ s/.* \([^ ]*\) *$/\1/ p q }' $infile` # ... or it is derived from the source name (dir/f.texi becomes f.info) test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info fi # If the file does not exist, the user really needs makeinfo; # let's fail without touching anything. test -f $file || exit 1 touch $file ;; tar*) shift # We have already tried tar in the generic part. # Look for gnutar/gtar before invocation to avoid ugly error # messages. if (gnutar --version > /dev/null 2>&1); then gnutar "$@" && exit 0 fi if (gtar --version > /dev/null 2>&1); then gtar "$@" && exit 0 fi firstarg="$1" if shift; then case $firstarg in *o*) firstarg=`echo "$firstarg" | sed s/o//` tar "$firstarg" "$@" && exit 0 ;; esac case $firstarg in *h*) firstarg=`echo "$firstarg" | sed s/h//` tar "$firstarg" "$@" && exit 0 ;; esac fi echo 1>&2 "\ WARNING: I can't seem to be able to run \`tar' with the given arguments. You may want to install GNU tar or Free paxutils, or check the command line arguments." exit 1 ;; *) echo 1>&2 "\ WARNING: \`$1' is needed, and is $msg. You might have modified some files without having the proper tools for further handling them. Check the \`README' file, it often tells you about the needed prerequisites for installing this package. You may also peek at any GNU archive site, in case some other package would contain this missing \`$1' program." exit 1 ;; esac exit 0 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: ddpt-0.92/README.win320000644000175000017500000000771111527261361013226 0ustar douggdouggThis port supports Windows NT, 2000, 2003++, XP, Vista and Windows 7 (i.e. not 95, 98, ME or earlier). It uses the Microsoft SCSI Pass Through "Direct" (SPTD). The source can be built in a cygwin environment and can run in a cygwin bash shell. It can also run in a DOS shell if the cygwin1.dll is put in an appropriate place. Alternatively the source can be built with the MinGW compiler using its MSYS shell. This removes the dependency on the cygwin1.dll file. The ddpt executable built by the MinGW compiler can also be run in a DOS (also known as the "Command prompt") shell. In Windows 7 ddpt typically needs to be run with administrator permissions. The device naming schemes attempt to follow what DOS does, with a few short cuts. If volume "D:" is an ATAPI DVD drive then the actual file opened is "\\.\D:". All device nodes of interest to ddpt have a leading "\\.\" so if the user doesn't supply it, ddpt will. Thus 'ddpt if=d: bs=512 count=8' should work. Note that volume names map to Windows partitions so there can be multiple volume names per disk. SCSI devices (or those that use a SCSI command set) can also be accessed via their "class" driver. These have names like "PhysicalDrive", "CDROM" and "TAPE" where is a number starting at 0. Since "PhysicalDrive" is tedious to type, a shortened form of "PD" is accepted. Finally there is a lower level "SCSI:" interface that addresses a SCSI adapter. The device needs further sub-addressing in the form of a bus number (also called a PathId), a target identifier and a lun (logical unit number). ddpt uses this notation: "SCSI:,,". The trailing "," may be omitted in which case a lun of 0 is assumed. Once a device has been "claimed" by an upper level "class" driver the OS will not allow it to be accessed via the "SCSI:" interface. Hence this is only needed for special devices (e.g. with processor or SES peripheral device type) that are not claimed by the class drivers. The Windows version of ddpt supports a '--wscan' (or '-w') option. It shows the mapping between a class driver device name (e.g. PD1) and its associated volume name(s). Here are some examples: $ ddpt -w PD0 [C] FUJITSU MHY2160BH 0000 PD1 [DF] WD 2500BEV External 1.05 WD-WXE90 CDROM0 [E] MATSHITA DVD/CDRW UJDA775 CB03 Now request bus types as well. $ ddpt -ww PD0 [C] FUJITSU MHY2160BH 0000 PD1 [DF] WD 2500BEV External 1.05 WD-WXE90 CDROM0 [E] MATSHITA DVD/CDRW UJDA775 CB03 Now request a SCSI adapter scan as well. $ ddpt -www PD0 [C] FUJITSU MHY2160BH 0000 PD1 [DF] WD 2500BEV External 1.05 WD-WXE90 CDROM0 [E] MATSHITA DVD/CDRW UJDA775 CB03 SCSI0:0,0,0 claimed=1 pdt=0h FUJITSU MHY2160BH 0000 SCSI1:0,0,0 claimed=1 pdt=5h MATSHITA DVD/CDRW UJDA775 CB03 And finally here is a more interesting example showing disks with no Windows (2000) volumes, a tape drive and a weird unclaimed SCSI pseudo device with BCC (Bridge Controller Commands) peripheral device type. $ ddpt -www PD0 [C] ST380011A 8.01 PD1 SEAGATE ST373455SS 2189 PD2 ATA ST3160812AS D PD3 SEAGATE ST336754SS 0003 CDROM0 [F] HL-DT-ST DVDRAM GSA-4163B A103 TAPE0 SONY SDT-7000 0192 SCSI0:0,0,0 claimed=1 pdt=0h dubious ST380011 A 8.01 SCSI1:0,0,0 claimed=1 pdt=5h HL-DT-ST DVDRAM GSA-4163B A103 SCSI2:0,6,0 claimed=1 pdt=1h SONY SDT-7000 0192 SCSI5:0,17,0 claimed=1 pdt=0h SEAGATE ST373455SS 2189 SCSI5:0,19,0 claimed=1 pdt=0h ATA ST3160812AS D SCSI5:0,21,0 claimed=1 pdt=0h SEAGATE ST336754SS 0003 SCSI5:0,112,0 claimed=0 pdt=10h LSI PSEUDO DEVICE 2.34 Douglas Gilbert 17th February 2011 ddpt-0.92/install-sh0000755000175000017500000003253711446031366013415 0ustar douggdougg#!/bin/sh # install - install a program, script, or datafile scriptversion=2009-04-28.21; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. nl=' ' IFS=" "" $nl" # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit=${DOITPROG-} if test -z "$doit"; then doit_exec=exec else doit_exec=$doit fi # Put in absolute file names if you don't have them in your path; # or use environment vars. chgrpprog=${CHGRPPROG-chgrp} chmodprog=${CHMODPROG-chmod} chownprog=${CHOWNPROG-chown} cmpprog=${CMPPROG-cmp} cpprog=${CPPROG-cp} mkdirprog=${MKDIRPROG-mkdir} mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} posix_glob='?' initialize_posix_glob=' test "$posix_glob" != "?" || { if (set -f) 2>/dev/null; then posix_glob= else posix_glob=: fi } ' posix_mkdir= # Desired mode of installed file. mode=0755 chgrpcmd= chmodcmd=$chmodprog chowncmd= mvcmd=$mvprog rmcmd="$rmprog -f" stripcmd= src= dst= dir_arg= dst_arg= copy_on_change=false no_target_directory= usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: --help display this help and exit. --version display version info and exit. -c (ignored) -C install only if different (preserve the last data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -s $stripprog installed files. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test $# -ne 0; do case $1 in -c) ;; -C) copy_on_change=true;; -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 case $mode in *' '* | *' '* | *' '* | *'*'* | *'?'* | *'['*) echo "$0: invalid mode: $mode" >&2 exit 1;; esac shift;; -o) chowncmd="$chownprog $2" shift;; -s) stripcmd=$stripprog;; -t) dst_arg=$2 shift;; -T) no_target_directory=true;; --version) echo "$0 $scriptversion"; exit $?;; --) shift break;; -*) echo "$0: invalid option: $1" >&2 exit 1;; *) break;; esac shift done if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dst_arg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dst_arg" shift # fnord fi shift # arg dst_arg=$arg done fi if test $# -eq 0; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call `install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then trap '(exit $?); exit' 1 2 13 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. case $mode in # Optimize common cases. *644) cp_umask=133;; *755) cp_umask=22;; *[0-7]) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac fi for src do # Protect names starting with `-'. case $src in -*) src=./$src;; esac if test -n "$dir_arg"; then dst=$src dstdir=$dst test -d "$dstdir" dstdir_status=$? else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dst_arg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dst_arg # Protect names starting with `-'. case $dst in -*) dst=./$dst;; esac # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then if test -n "$no_target_directory"; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst dst=$dstdir/`basename "$src"` dstdir_status=0 else # Prefer dirname, but fall back on a substitute if dirname fails. dstdir=` (dirname "$dst") 2>/dev/null || expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$dst" : 'X\(//\)[^/]' \| \ X"$dst" : 'X\(//\)$' \| \ X"$dst" : 'X\(/\)' \| . 2>/dev/null || echo X"$dst" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q' ` test -d "$dstdir" dstdir_status=$? fi fi obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') # Create intermediate dirs using mode 755 as modified by the umask. # This is like FreeBSD 'install' as of 1997-10-28. umask=`umask` case $stripcmd.$umask in # Optimize common cases. *[2367][2367]) mkdir_umask=$umask;; .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; *[0-7]) mkdir_umask=`expr $umask + 22 \ - $umask % 100 % 40 + $umask % 20 \ - $umask % 10 % 4 + $umask % 2 `;; *) mkdir_umask=$umask,go-w;; esac # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then mkdir_mode=-m$mode else mkdir_mode= fi posix_mkdir=false case $umask in *[123567][0-7][0-7]) # POSIX mkdir -p sets u+wx bits regardless of umask, which # is incompatible with FreeBSD 'install' when (umask & 300) != 0. ;; *) tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 if (umask $mkdir_umask && exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writeable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. ls_ld_tmpdir=`ls -ld "$tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && $mkdirprog -m$different_mode -p -- "$tmpdir" && { ls_ld_tmpdir_1=`ls -ld "$tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi rmdir "$tmpdir/d" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null fi trap '' 0;; esac;; esac if $posix_mkdir && ( umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else # The umask is ridiculous, or mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. case $dstdir in /*) prefix='/';; -*) prefix='./';; *) prefix='';; esac eval "$initialize_posix_glob" oIFS=$IFS IFS=/ $posix_glob set -f set fnord $dstdir shift $posix_glob set +f IFS=$oIFS prefixes= for d do test -z "$d" && continue prefix=$prefix$d if test -d "$prefix"; then prefixes= else if $posix_mkdir; then (umask=$mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 else case $prefix in *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; *) qprefix=$prefix;; esac prefixes="$prefixes '$qprefix'" fi fi prefix=$prefix/ done if test -n "$prefixes"; then # Don't fail if two instances are running concurrently. (umask $mkdir_umask && eval "\$doit_exec \$mkdirprog $prefixes") || test -d "$dstdir" || exit 1 obsolete_mkdir_used=true fi fi fi if test -n "$dir_arg"; then { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 else # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ rmtmp=$dstdir/_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && eval "$initialize_posix_glob" && $posix_glob set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && $posix_glob set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then rm -f "$dsttmp" else # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. { # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { test ! -f "$dst" || $doit $rmcmd -f "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 } } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 trap '' 0 fi done # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: ddpt-0.92/README.solaris0000644000175000017500000000412611361107544013733 0ustar douggdouggIn Solaris, SCSI device names below the '/dev' directory have a form like: c5t4d3s2 where the number following "c" is the controller (HBA) number, the number following "t" is the target number (from the SCSI parallel interface days) and the number following "d" is the LUN. Following the "s" is the slice number which is related to a partition and by convention "s2" is the whole disk. OpenSolaris also has a c5t4d3p2 form where the number following the "p" is the partition number apart from "p0" which is the whole disk. So a whole disk may be referred to as either: - c5t4d3 - c5t4d3s2 - c5t4d3p0 And these device names are duplicated in the /dev/dsk and /dev/rdsk directories. The former is the block device name and the latter is for "raw" (or char device) access. For performance and flexibility it is better for ddpt to use the raw device names (e.g. /dev/rdsk/c5t4d3p0). A safe way to check things is: ddpt if=/dev/rdsk/c5t4d3p0 bs=512 count=0 verbose=4 If it did read anything (it won't due to the "count=0") the normal Unix read() call would be used. To do the same thing at the SCSI pass-through level: ddpt if=/dev/rdsk/c5t4d3p0 iflag=pt bs=512 count=0 verbose=4 The latter won't work on the /dev/dsk/c5t4d3p0 variant device name resulting in an inappropriate ioctl for device error. The device names within the /dev directory are typically symbolic links to much longer topological names in the /device directory. In Solaris cd/dvd/bd players seem to be treated as disks and so are found in the /dev/rdsk directory. There is also a sgen (SCSI generic) driver which by default does not attach to any device. See the /kernel/drv/sgen.conf file to control what is attached. Any attached device will have a device name of the form /dev/scsi/c5t4d3 . Listing available SCSI devices in Solaris seems to be a challenge. "Use the 'format' command" advice works but seems a very dangerous way to list devices. [It does prompt again before doing any damage.] 'devfsadm -Cv' cleans out the clutter in the /dev/rdsk directory, only leaving what is "live". The "cfgadm -v" command looks promising. 8th April 2010 ddpt-0.92/README0000644000175000017500000001123611527261361012262 0ustar douggdouggIntroduction ------------ ddpt is a utility for copying files like its namesake the Unix dd command. ddpt is specialized for files that are actually block devices. And if those block devices understand SCSI commands then the copy can be done by using either SCSI READ or WRITE commands (or both). This latter facility is done using a pass-through interface that bypasses the normal operating system block handling. This can give very fine-grained control over the copy process. This utility was originally written for Linux. It has been ported to FreeBSD and Windows. Relationship to sg3_utils ------------------------- The sg3_utils (version 1.27) package contains several utilities that mimic the standard Unix dd command. Currently those utilities are sg_dd, sgm_dd and sgp_dd. Even though most of the other utilities in the sg3_utils package are ported to other operating systems, sg_dd and friends are not ported since they are too tightly bound to Linux and some of the idiosyncrasies of its SCSI generic (sg) driver and the associated SG_IO ioctl. So the ddpt utility drops some Linux specific features while adding some more general features (e.g. write sparing). An attempt has also been made to simplify the command line syntax which is still based on the distinctive dd command command line syntax. Note that the dd command line syntax is unlike any other Unix command (probably imported from some IBM OS many years ago). This package shares code with sg3_utils (version 1.27). With the subversion revision control system this is done by having ddpt's "include/" and "lib/" sub-directories pointing to the correspondingly named directories in the sg3_utils package using the "svn:externals" property. These two "external" directories include more files than ddpt uses. The excess files include "lib/Makefile.am" and "lib/Makefile.in". The "Makefile.am" in ddpt's "src/" directory does the main part of the build. When the tarball is generated for this utility, various files are "exported" out of the subversion repository and "svn:externals" redirection is no longer visible (but the unused files are visible). Currently the shared code is statically linked into ddpt. It is the intention of the author to make a common library called libsgutils.so in a separate package that both ddpt and sg3_utils will depend on at some point in the future. Documentation ------------- The utility outputs a usage message when the "--help" (or '-?') option is given. Many syntax errors also result in the usage message being printed. There is also a man page which is in section 8 (administration and privileged commands). It can be accessed with "man ddpt" once this package is installed. Prior to installation the man page can be viewed from this package's main directory with "man doc/ddpt.8". There is a web page at http://sg.danny.cz/sg/ddpt.html and a copy of that html file is placed in the "doc" directory. Build infrastructure -------------------- This packages uses the automake and autoconf tools. The generating files (scripts) are configure.ac, Makefile.am, doc/Makefile.am, src/Makefile.am and autogen.sh . The autogen.sh script only needs to be executed if one of the other generating files in the above list is changed. There is a rpm "spec" file in the main directory: ddpt.spec . There are Debian build files in the "debian" directory and a script called build_debian.sh in the main directory. Amongst other things debian builds are sensitive to the value in the debian/compat file. If it contains "7" then it works on lenny and gives warning on squeeze (but fails on the earlier etch). License ------- This utility is covered by a FreeBSD license. The intention of the author is that both open source and commercial entities can re-use this code. Naturally attribution and improvement/bug feedback are encouraged. Notes ----- Generic information about building this package (i.e. './configure ; make; make install') can be found in the INSTALL file. The contents of COPYING is a FreeBSD license (rather than the GPL v2 found in the usual template). Linux port ---------- The utility can be used on any storage device. To use the "pt" interface the device needs to support the SG_IO ioctl. In the Linux 2.4 series that is only the scsi generic (i.e. /dev/sg* ) device nodes. In the Linux 2.6 series the supported device nodes have expanded to all other SCSI device nodes (e.g. /dev/sd* and /dev/sr*) plus block devices such as /dev/hdc when the associated device is a DVD drive. The man page and sg.danny.cz/sg/ddpt.html web page examples use Linux device node names. FreeBSD port ------------ See README.freebsd Solaris port ------------ See README.solaris Win32 port ---------- See README.win32 Douglas Gilbert 17th February 2011 ddpt-0.92/build_debian.sh0000755000175000017500000000055711104200157014331 0ustar douggdougg#!/bin/sh echo "chmod +x debian/rules" chmod +x debian/rules # in some environments the '-rfakeroot' can cause a failure (e.g. when # building as root). If so, remove that argument from the following: echo "dpkg-buildpackage -b -rfakeroot" dpkg-buildpackage -b -rfakeroot # If the above succeeds then the ".deb" binary package is placed in the # parent directory. ddpt-0.92/COPYING0000644000175000017500000000263711527261361012442 0ustar douggdouggCopyright (c) 2008-2011 Douglas Gilbert. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ddpt-0.92/configure.ac0000644000175000017500000000507211526513027013667 0ustar douggdouggAC_INIT(ddpt, 0.92, dgilbert@interlog.com) AM_INIT_AUTOMAKE AM_MAINTAINER_MODE AM_CONFIG_HEADER(config.h) AC_PROG_CC # AC_PROG_CXX AC_PROG_INSTALL # check for headers AC_HEADER_STDC AC_CHECK_HEADERS([linux/types.h linux/bsg.h], [], [], [[#ifdef HAVE_LINUX_TYPES_H # include #endif ]]) AC_CHECK_FUNCS(posix_fadvise) AC_CHECK_FUNCS(fsync) AC_CHECK_FUNCS(fdatasync) AC_CHECK_LIB(rt, clock_gettime, AC_SUBST([rt_libs], ['-lrt']), AC_SUBST([rt_libs], [''])) AC_CHECK_LIB(rt, clock_gettime) AC_CHECK_FUNCS(clock_gettime) AC_CHECK_FUNCS(gettimeofday) AC_CANONICAL_HOST AC_DEFINE_UNQUOTED(SG_LIB_BUILD_HOST, "${host}", [ddpt Build Host]) case "${host}" in *-*-linux-gnu*) AC_SUBST([os_deps], ['sg_pt_linux.o']) AC_DEFINE_UNQUOTED(SG_LIB_LINUX, 1, [ddpt on linux]) AC_SUBST([os_libs], ['']) ;; *-*-linux*) AC_SUBST([os_deps], ['sg_pt_linux.o']) AC_DEFINE_UNQUOTED(SG_LIB_LINUX, 1, [ddpt on linux]) AC_SUBST([os_libs], ['']) ;; *-*-freebsd*|*-*-kfreebsd*-gnu*) AC_SUBST([os_deps], ['sg_pt_freebsd.o']) AC_DEFINE_UNQUOTED(SG_LIB_FREEBSD, 1, [ddpt on FreeBSD]) AC_SUBST([os_libs], ['-lcam']);; *-*-solaris*) AC_SUBST([os_deps], ['sg_pt_solaris.o']) AC_DEFINE_UNQUOTED(SG_LIB_SOLARIS, 1, [ddpt on Solaris]) AC_SUBST([os_libs], ['']);; *-*-cygwin*) AC_SUBST([os_deps], ['sg_pt_win32.o']) AC_DEFINE_UNQUOTED(SG_LIB_WIN32, 1, [ddpt on Win32]) AC_DEFINE_UNQUOTED(WIN32_SPT_DIRECT, 1, [allow large buffers, aligned?]) AC_SUBST([os_libs], ['']) ;; *-*-mingw*) AC_SUBST([os_deps], ['sg_pt_win32.o']) AC_DEFINE_UNQUOTED(SG_LIB_WIN32, 1, [ddpt on Win32]) AC_DEFINE_UNQUOTED(WIN32_SPT_DIRECT, 1, [allow large buffers, aligned?]) AC_DEFINE_UNQUOTED(SG_LIB_MINGW, 1, [also MinGW environment]) AC_SUBST([os_libs], ['']) ;; *) AC_SUBST([os_deps], ['sg_pt_linux.o']) AC_DEFINE_UNQUOTED(SG_LIB_LINUX, 1, [assume ddpt on linux]) AC_SUBST([os_libs], ['']) ;; esac AC_ARG_ENABLE([no-linux-bsg], AC_HELP_STRING([--enable-no-linux-bsg], [ignore linux bsg (sgv4) if present]), AC_DEFINE_UNQUOTED(IGNORE_LINUX_BSG, 1, [ignore linux bsg], ) ) AC_CHECK_LIB(sgutils2, sg_ll_inquiry, [SGUTILS_LIBS="-lsgutils2"; have_sgutils=yes], have_sgutils=no) AC_SUBST(SGUTILS_LIBS) AM_CONDITIONAL(HAVE_SGUTILS, test x"$have_sgutils" = xyes) # AC_PROG_LIBTOOL AC_OUTPUT(Makefile src/Makefile doc/Makefile) ddpt-0.92/Makefile.in0000644000175000017500000005273611526513027013457 0ustar douggdougg# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, # Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = . DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in $(srcdir)/config.h.in \ $(top_srcdir)/configure AUTHORS COPYING ChangeLog INSTALL NEWS \ TODO config.guess config.sub depcomp install-sh missing ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-dvi-recursive install-exec-recursive \ install-html-recursive install-info-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ distdir dist dist-all distcheck ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ { test ! -d "$(distdir)" \ || { find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -fr "$(distdir)"; }; } am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best distuninstallcheck_listfiles = find . -type f -print distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ SET_MAKE = @SET_MAKE@ SGUTILS_LIBS = @SGUTILS_LIBS@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ os_deps = @os_deps@ os_libs = @os_libs@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ rt_libs = @rt_libs@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = src doc EXTRA_DIST = autogen.sh all: config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: am--refresh: @: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \ $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) $(am__cd) $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): config.h: stamp-h1 @if test ! -f $@; then \ rm -f stamp-h1; \ $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \ else :; fi stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status @rm -f stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status config.h $(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) rm -f stamp-h1 touch $@ distclean-hdr: -rm -f config.h stamp-h1 # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" $(RECURSIVE_CLEAN_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done -test -n "$(am__skip_mode_fix)" \ || find "$(distdir)" -type d ! -perm -755 \ -exec chmod u+rwx,go+rx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 $(am__remove_distdir) dist-lzma: distdir tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma $(am__remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz $(am__remove_distdir) dist-tarZ: distdir tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__remove_distdir) dist-shar: distdir shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__remove_distdir) dist dist-all: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lzma*) \ lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\ *.tar.xz*) \ xz -dc $(distdir).tar.xz | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir); chmod a+w $(distdir) mkdir $(distdir)/_build mkdir $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build \ && ../configure --srcdir=.. --prefix="$$dc_install_base" \ $(DISTCHECK_CONFIGURE_FLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 $(am__remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: @$(am__cd) '$(distuninstallcheck_dir)' \ && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am check: check-recursive all-am: Makefile config.h installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -f Makefile distclean-am: clean-am distclean-generic distclean-hdr distclean-local \ distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all \ ctags-recursive install-am install-strip tags-recursive .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am am--refresh check check-am clean clean-generic \ ctags ctags-recursive dist dist-all dist-bzip2 dist-gzip \ dist-lzma dist-shar dist-tarZ dist-xz dist-zip distcheck \ distclean distclean-generic distclean-hdr distclean-local \ distclean-tags distcleancheck distdir distuninstallcheck dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs installdirs-am \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic pdf pdf-am ps ps-am tags tags-recursive \ uninstall uninstall-am distclean-local: rm -rf autom4te.cache # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: ddpt-0.92/AUTHORS0000644000175000017500000000005711104213063012434 0ustar douggdouggDouglas Gilbert ddpt-0.92/INSTALL0000644000175000017500000002245011130302611012413 0ustar douggdouggInstallation Instructions ************************* Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. This file is free documentation; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. Basic Installation ================== Briefly, the shell commands `./configure; make; make install' should configure, build, and install this package. The following more-detailed instructions are generic; see the `README' file for instructions specific to this package. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a `Makefile' in each directory of the package. It may also create one or more `.h' files containing system-dependent definitions. Finally, it creates a shell script `config.status' that you can run in the future to recreate the current configuration, and a file `config.log' containing compiler output (useful mainly for debugging `configure'). It can also use an optional file (typically called `config.cache' and enabled with `--cache-file=config.cache' or simply `-C') that saves the results of its tests to speed up reconfiguring. Caching is disabled by default to prevent problems with accidental use of stale cache files. If you need to do unusual things to compile the package, please try to figure out how `configure' could check whether to do them, and mail diffs or instructions to the address given in the `README' so they can be considered for the next release. If you are using the cache, and at some point `config.cache' contains results you don't want to keep, you may remove or edit it. The file `configure.ac' (or `configure.in') is used to create `configure' by a program called `autoconf'. You need `configure.ac' if you want to change it or regenerate `configure' using a newer version of `autoconf'. The simplest way to compile this package is: 1. `cd' to the directory containing the package's source code and type `./configure' to configure the package for your system. Running `configure' might take a while. While running, it prints some messages telling which features it is checking for. 2. Type `make' to compile the package. 3. Optionally, type `make check' to run any self-tests that come with the package. 4. Type `make install' to install the programs and any data files and documentation. 5. You can remove the program binaries and object files from the source code directory by typing `make clean'. To also remove the files that `configure' created (so you can compile the package for a different kind of computer), type `make distclean'. There is also a `make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution. 6. Often, you can also type `make uninstall' to remove the installed files again. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the `configure' script does not know about. Run `./configure --help' for details on some of the pertinent environment variables. You can give `configure' initial values for configuration parameters by setting variables in the command line or in the environment. Here is an example: ./configure CC=c99 CFLAGS=-g LIBS=-lposix *Note Defining Variables::, for more details. Compiling For Multiple Architectures ==================================== You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you can use GNU `make'. `cd' to the directory where you want the object files and executables to go and run the `configure' script. `configure' automatically checks for the source code in the directory that `configure' is in and in `..'. With a non-GNU `make', it is safer to compile the package for one architecture at a time in the source code directory. After you have installed the package for one architecture, use `make distclean' before reconfiguring for another architecture. Installation Names ================== By default, `make install' installs the package's commands under `/usr/local/bin', include files under `/usr/local/include', etc. You can specify an installation prefix other than `/usr/local' by giving `configure' the option `--prefix=PREFIX'. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you pass the option `--exec-prefix=PREFIX' to `configure', the package uses PREFIX as the prefix for installing programs and libraries. Documentation and other data files still use the regular prefix. In addition, if you use an unusual directory layout you can give options like `--bindir=DIR' to specify different values for particular kinds of files. Run `configure --help' for a list of the directories you can set and what kinds of files go in them. If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving `configure' the option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. Optional Features ================= Some packages pay attention to `--enable-FEATURE' options to `configure', where FEATURE indicates an optional part of the package. They may also pay attention to `--with-PACKAGE' options, where PACKAGE is something like `gnu-as' or `x' (for the X Window System). The `README' should mention any `--enable-' and `--with-' options that the package recognizes. For packages that use the X Window System, `configure' can usually find the X include and library files automatically, but if it doesn't, you can use the `configure' options `--x-includes=DIR' and `--x-libraries=DIR' to specify their locations. Specifying the System Type ========================== There may be some features `configure' cannot figure out automatically, but needs to determine by the type of machine the package will run on. Usually, assuming the package is built to be run on the _same_ architectures, `configure' can figure that out, but if it prints a message saying it cannot guess the machine type, give it the `--build=TYPE' option. TYPE can either be a short name for the system type, such as `sun4', or a canonical name which has the form: CPU-COMPANY-SYSTEM where SYSTEM can have one of these forms: OS KERNEL-OS See the file `config.sub' for the possible values of each field. If `config.sub' isn't included in this package, then this package doesn't need to know the machine type. If you are _building_ compiler tools for cross-compiling, you should use the option `--target=TYPE' to select the type of system they will produce code for. If you want to _use_ a cross compiler, that generates code for a platform different from the build platform, you should specify the "host" platform (i.e., that on which the generated programs will eventually be run) with `--host=TYPE'. Sharing Defaults ================ If you want to set default values for `configure' scripts to share, you can create a site shell script called `config.site' that gives default values for variables like `CC', `cache_file', and `prefix'. `configure' looks for `PREFIX/share/config.site' if it exists, then `PREFIX/etc/config.site' if it exists. Or, you can set the `CONFIG_SITE' environment variable to the location of the site script. A warning: not all `configure' scripts look for a site script. Defining Variables ================== Variables not defined in a site shell script can be set in the environment passed to `configure'. However, some packages may run configure again during the build, and the customized values of these variables may be lost. In order to avoid this problem, you should set them in the `configure' command line, using `VAR=value'. For example: ./configure CC=/usr/local2/bin/gcc causes the specified `gcc' to be used as the C compiler (unless it is overridden in the site shell script). Unfortunately, this technique does not work for `CONFIG_SHELL' due to an Autoconf bug. Until the bug is fixed you can use this workaround: CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash `configure' Invocation ====================== `configure' recognizes the following options to control how it operates. `--help' `-h' Print a summary of the options to `configure', and exit. `--version' `-V' Print the version of Autoconf used to generate the `configure' script, and exit. `--cache-file=FILE' Enable the cache: use and save the results of the tests in FILE, traditionally `config.cache'. FILE defaults to `/dev/null' to disable caching. `--config-cache' `-C' Alias for `--cache-file=config.cache'. `--quiet' `--silent' `-q' Do not print messages saying which checks are being made. To suppress all normal output, redirect it to `/dev/null' (any error messages will still be shown). `--srcdir=DIR' Look for the package's source code in directory DIR. Usually `configure' can determine that directory automatically. `configure' also accepts some other, not widely useful, options. Run `configure --help' for more details. ddpt-0.92/ChangeLog0000644000175000017500000000733111527261361013155 0ustar douggdouggThe version number is hard-coded into src/ddpt.c (in a C string); the rpm spec file: ddpt.spec ; the debian/changelog file; and the configure.ac file (in the AC_INIT item). Changelog for ddpt-0.92 [20110217] [svn: r157] - when pt used on block device and discrepancy between size of block device and read capacity size, require force flag - add coe support for input block devices and regular files - support conv=fdatasync, conv=fsync, oflag=fdatasync and oflag=fsync; called at end of copy - allow partial writes of trailing bytes when output is regular file or fifo (stdout), ignore if block or pt device - fix stdin, stdout and fifo handling problems - if iflag=sparse and of=/dev/null (or not given) warn but set oflag=sparse and continue - treat unrecovered errors as partial (as dd does) - win32: add '--wscan' option to scan for devices and volumes - select SPT direct pt interface - add estimate of remaining time in progress signal handler - accept but ignore cbs= option - error reporting clean up - add AM_MAINTAINER_MODE to configure.ac to lessen build issues Changelog for ddpt-0.91 [20100920] [svn: r121] - rework copy loop. - extend bpt=BPT to bpt=BPR[,OBPC] spare+sparse granularity - change BPT default to vary from 8192 to 1 depending on IBS - add oflag=resume logic - change oflag=sparse to extend regular OFILE with a final block write, if required - add oflag=strunc to also do sparse writes but to extend regular OFILE with ftruncate, if required - change 'bs=' option to set IBS and OBS; 'ibs=' and 'obs=' can coexist but not with 'bs='. [Closer to dd semantics] - conv=noerror,null,resume,sparing,sparse,sync now permitted - add oflag=trunc and conv=trunc (default: overwrite) - quietly ignored if resume, needed due to sequence - add oflag=trim for TRIM/UNMAP on pt OFILEs - add iflag=self or oflag=self for self-trim - add oflag=nowrite to bypass writes+truncates (does trims) - add iflag=errblk to write bad LBAs to file - if sense data deficient, write a LBA range to file - add iflag=norcap or oflag=norcap to bypass the SCSI READ CAPACITY command on pt devices - discrepancies between ibs or obs and READ CAPACITY supplied block lengths abort the copy. This can be overridden by iflag=force or oflag=force on pt devices - optical memory devices (pdt=7) added to cd/dvd readers (pdt=5) that don't need sense valid=1 to accept info field (when > 0) - rework short read logic for block and regular files - treat linux bsg devices as implicit pt devices Changelog for ddpt-0.90 [20100508] [svn: r85] - copied from sg_dd utility in sg3_utils package - change name from sgdd to ddpt (package and utility name) - ibs and obs can differ when ((ibs * bpt) % obs) == 0) - change 'sg_io' flag to 'pt' (for pass-through) - change 'dsync' flag to 'sync'; 'ssync' flag for SCSI SYNCHRONIZE CACHE command; add 'nocache' flag - 'if=IFILE' must be given, to read from stdin use 'if=-' - 'of=OFILE' changed to default to /dev/null (was stdout) - if 'nocache' flag call posix_fadvise(SEQUENTIAL) on input fd and posix_fadvise(DONTNEED) during copy - add 'fua_nv' flag - when multiple unrecovered errors report lowest and highest LBA - call sg_set_binary_mode() on fds (for windows) - resubmit pass-through reads and writes if interrupted - drop Linux raw file support - drop READ LONG logic (coe=2 and coe=3) - add write sparing support (oflag=sparing) - add linux bsg support - sg_pt_win32: define WIN32_SPT_DIRECT via config.h - calculate COUNT for regular files when required - accept 'count=-1' to mean calculate COUNT - accept '-V' as synonym for '--version' - point svn:externals to rev 334 of sg3_utils ddpt-0.92/ddpt.spec0000644000175000017500000000310511527261361013205 0ustar douggdougg%define name ddpt %define version 0.92 %define release 1 Summary: Copy files (like dd) especially SCSI/storage devices Name: %{name} Version: %{version} Release: %{release} License: FreeBSD Group: Utilities/System URL: http://sg.danny.cz/sg/ddpt.html Source0: http://sg.danny.cz/sg/p/%{name}-%{version}.tgz BuildRoot: %{_tmppath}/%{name}-%{version}-root Packager: Douglas Gilbert %description ddpt is yet another variant of the Unix dd command used to copy files. This variant is specialized for moving data to, from or between storage devices. If requested SCSI commands can be sent to read or write data. Such commands are sent via a pass-through interface. Note that recent (S)ATA disks can often be driven by SCSI commands due to SCSI to ATA translation (SAT) implemented in the kernel. %prep %setup -q %build %configure %install if [ "$RPM_BUILD_ROOT" != "/" ]; then rm -rf $RPM_BUILD_ROOT fi make install \ DESTDIR=$RPM_BUILD_ROOT %clean if [ "$RPM_BUILD_ROOT" != "/" ]; then rm -rf $RPM_BUILD_ROOT fi %files %defattr(-,root,root) %doc ChangeLog INSTALL README CREDITS AUTHORS COPYING %attr(0755,root,root) %{_bindir}/* # >> should that be %attr(0755,root,root) %{_sbindir}/* ?? %{_mandir}/man8/* %changelog * Thu Feb 17 2011 - dgilbert at interlog dot com - warn about pt on block partitions, coe on reg,blk in * ddpt-0.92 * Fri Aug 13 2010 - dgilbert at interlog dot com - extend bpt=BPT to bpt=BPT[,OBPC], resume and trim flags * ddpt-0.91 * Sat May 08 2010 - dgilbert at interlog dot com - initial version * ddpt-0.90 ddpt-0.92/Makefile.am0000644000175000017500000000012311100510330013403 0ustar douggdouggSUBDIRS = src doc EXTRA_DIST=autogen.sh distclean-local: rm -rf autom4te.cache ddpt-0.92/doc/0000755000175000017500000000000011527261465012151 5ustar douggdouggddpt-0.92/doc/ddpt_examples.txt0000644000175000017500000002460411517666045015553 0ustar douggdougg# ddpt examples # ============= # Lines that start with "#", like this one, are comments. # Lines that start with "$" are commands entered by the user. Some # long commands are split over several lines with a trailing "\" # on all but the last line of the command. # Other non-blank lines are command output. Command output is shown # in only some cases. # dd "standard" regular file to regular file copy. 'stat -c %s ' # is a way of getting a file's length, in bytes. $ stat -c %s src 6915 $ dd if=src of=dst 13+1 records in 13+1 records out 6915 bytes (6.9 kB) copied, 0.000128857 s, 53.7 MB/s # Now lets look at the ddpt equivalent. So we try the same options but # the ddst file exists and it is relatively large. $ stat -c %s ddst 524800 $ ddpt if=src of=ddst Assume block size of 512 bytes for both input and output 13+1 records in 13+1 records out time to transfer data: 0.000121 secs at 59.24 MB/sec $ stat -c %s dst 524800 # ddpt does not truncate ddst, it overwrites it. So if ddst's file length # is longer than src's file length then the output file needs to be # truncated: $ ddpt if=src of=ddst oflag=trunc Assume block size of 512 bytes for both input and output 13+1 records in 13+1 records out time to transfer data: 0.000243 secs at 29.50 MB/sec $ stat -c %s ddst 6915 # So now src is the same length as dst and ddst. And they all contain the # same data. The ddpt benefit of not truncating the output file by default # is with write sparing and the resume capability. # Both dd and ddpt default to a block size of 512 bytes (bs=512) as they # are designed to move disk data which up until recent times typically # had a block size of 512 bytes. However for copying regular (normal) # files bs=1 would be a clearer choice. dd is relatively inefficient when # bs=1 but ddpt should be faster. So we can do this: $ ddpt if=src bs=1 of=ddst oflag=trunc 6915+0 records in 6915+0 records out time to transfer data: 0.000134 secs at 51.60 MB/sec # Notice that "records in" and "records out" are byte counts since "bs=1" # if the src file is large then $ dd if=src of=dst # can be quite inefficient because dd reads BS (argument to "bs=") or # IBS bytes at a time, then writes them to dst and continues until # all of src has been read (or the COUNT is exhausted). So something # like this is often suggested: $ dd if=src of=dst bs=64k # ddpt reads BPT*IBS bytes at a time from src before writing them to # ddst. The default value of BPT varies depending on IBS; for IBS=512 # BPT defaults to 128. So for 512 byte blocks ddpt reads in chunks of # 64 KB. Hence this invocation of ddpt remains quite efficient: $ ddpt if=src ibs=512 of=ddst oflag=trunc obs=1 # The advantage of keeping the IBS value low (and specifically equal to # the logical block size for block devices) is that the SKIP and COUNT # arguments are in units of IBS bytes: $ ddpt if=/dev/sda skip=0x4215cc bs=512 of=ddst.img count=1234560 # There is no need to worry about short reads on a block device # so giving BS sets both IBS and OBS to the same value. So now # SKIP and COUNT are in 512 byte units (so SKIP is a Logical Block # Address (LBA)). Notice that SKIP is given in hexadecimal (dd only # accepts decimal arguments). Since the "bpt=" option is not given # BPT defaults to 128 and each read into the copy buffer is # 128*512 = 64 KB. The dd equivalent: $ dd if=/dev/sda skip=4330956 bs=512 of=dst.img count=1234560 # will be slow since dd will read 512 bytes, write 512 bytes at a time. # Changing to "bs=64k" looks like it will help but now SKIP and COUNT # need to be divided by 128. However the SKIP value is not divisible by # 128. An efficient solution is not pretty. # When block sizes differ between the input and output devices, ddpt may # zero pad the last copy segment so an integral number of OBS sized blocks # are written. With this example the output (sent to stderr) is shown: $ ddpt if=/dev/sda ibs=512 of=/dev/sdc obs=4096 count=9 9+0 records in 2+0 records out time to transfer data: 0.000045 secs at 102.40 MB/sec # The COUNT implies a copy of 9*512 = 4608 bytes. That spills into the # second record (block) of /dev/sdc because its logical block size is 4096 # bytes. ddpt pads with zeros which is what the last 3542 bytes of the # second block of /dev/sdc will contain after the copy. # Sparse writes can be used to count the number of blocks that contain # all zeros. sda1 is a half full 73 GB partition (on a SSD) and we check # for zero blocks 40 GB from its start and for a length of 5 GB: $ ddpt if=/dev/sda1 skip=80m bs=512 oflag=sparse count=10m Output file not specified so no copy, just reading input 10485760+0 records in 0+0 records out 5672704 bypassed records out time to read data: 20.583461 secs at 260.83 MB/sec # Actually a copy buffer (64 KB) at a time is being checked for all # zeros so that count understates the true value. By setting OBPC to # 1, each block will be checked at a (slight) cost in execution time: $ ddpt if=/dev/sda1 skip=80m bs=512 oflag=sparse count=10m bpt=128,1 Output file not specified so no copy, just reading input 10485760+0 records in 0+0 records out 6317217 bypassed records out time to read data: 20.575803 secs at 260.92 MB/sec # Zero filled blocks are listed as "bypassed records out" (even though # nothing is actually written). When the granularity of the check for # zeros is 64 KB then 5672704 zero blocks are found. When the granularity # of the check is reduced to 512 bytes then 6317217 zero blocks are found. # As an example of write sparing, assume the regular file t exists # and tt doesn't. Lets say the length of t is 524897 bytes: $ ddpt if=t bs=512 of=tt oflag=sparing 1025+1 records in 1025+1 records out 0 bypassed records out time to transfer data: 0.001061 secs at 495.11 MB/sec # Now repeating the operation with oflag=sparing still set: $ ddpt if=t bs=512 of=tt oflag=sparing 1025+1 records in 0+0 records out 1025+1 bypassed records out time to transfer data: 0.001680 secs at 312.69 MB/sec # Since t and tt should now contain the same data write sparing # has been able to bypass all writes to tt. # # The "time to transfer" line in the output can be removed by # the addition of the status=noxfer option: $ ddpt if=t bs=512 of=tt oflag=sparing status=noxfer 1025+1 records in 0+0 records out 1025+1 bypassed records out # Imaging disks and partitions to a regular file can take a long # time. Sometimes the copy must be interrupted or there is # some failure (say power) which stops the copy. In such cases # oflag=resume may be helpful. In the case shown below a small # partition is being copied to a regular file and it is # interrupted with ^C from the keyboard: $ ddpt if=/dev/sda2 of=sda2.bin bs=512 ^CInterrupted by signal SIGINT, remaining block count=1409601 662784+0 records in 662784+0 records out time to transfer data: 5.226487 secs at 64.93 MB/sec To resume, invoke with same arguments plus oflag=resume # Taking the advice from the last line: $ ddpt if=/dev/sda2 of=sda2.bin bs=512 oflag=resume resume adjusting skip=662784, seek=662784, and count=1409601 1409601+0 records in 1409601+0 records out time to transfer data: 10.543506 secs at 68.45 MB/sec # By checking the size of sda2.bin the resume logic has adjusted # the skip, seek and count options to complete the rest of the # copy. If the copy was finished then making the same invocation # is harmless: $ ddpt if=/dev/sda2 of=sda2.bin bs=512 oflag=resume resume finds copy complete, exiting # And if sda2.bin was empty on did not exist then a full copy # would occur. # ddpt supports a trim operation on the output file when it is # accessed via the pt interface. Some SSDs support the trim # operation (also known as unmap) with "deterministic read # zero after trim". ddpt treats a trim like sparse, however # instead of bypassing a segment of zeros a trim command is sent. # In SCSI parlance trim is a WRITE SAME with the UNMAP bit set. $ ddpt if=/dev/sdb1 bs=512 of=/dev/sg1 seek=73899000 oflag=trim 18314037+0 records in 16970165+0 records out 1343872 trimmed records out time to transfer data: 174.057264 secs at 53.87 MB/sec # To trim (zero) a large portion of a SSD use /dev/zero as the # input file. This will zero from logical block 73899000 until # the end of /dev/sg1 which is a SSD: $ ddpt if=/dev/zero bs=512 of=/dev/sg1 seek=73899000 oflag=trim Progress report: remaining block count=38895160 43507456+0 records in 0+0 records out 43507328 trimmed records out time to transfer data so far: 405.905942 secs at 54.88 MB/sec continuing ... 82402488+0 records in 0+0 records out 82402488 trimmed records out time to transfer data: 768.067647 secs at 54.93 MB/sec # Notice the "Progress report:" line and the indented lines # following it. What happened here was a SIGUSR1 signal was sent # to the process running ddpt with a 'kill -s SIGUSR1 ' # command. The of a running ddpt can be found with the 'ps ax' # command. The progress report finished with "continuing ..." # line. The un-indented lines at the end of the output were # placed there at the completion of the ddpt copy. # self trim describes the technique of reading a block device # (accessed via a pt interface) and checking for segments of # zeros (64 KB of zeros in the first case). Segments full of # zeros are "trimmed". # In Linux /dev/sg* and /dev/bsg/* are pt devices. $ ddpt if=/dev/sg0 bs=512 skip=130045952 iflag=self,trim # The bpt option can be used to both increase the size of the # copy segment and reduce granularity on trim check to 1 output # block (i.e. 512 bytes at a time). This may result in a lot more # small "trim" commands being issued. $ ddpt if=/dev/sg0 bs=512 skip=130045952 iflag=self,trim bpt=1024,1 # the self flag does some option juggling and transforms the previous # invocation into: $ ddpt if=/dev/sg0 bs=512 skip=130045952 of=/dev/sg0 seek=130045952 \ oflag=trim,nowrite bpt=1024,1 # which is now a "copy" back to the same file. Nasty things happen if # SKIP and SEEK are not the same. Best to stick with the simpler # "iflag=self,trim" form and avoid the pitfalls of replicated arguments. # If some command line arithmetic is required (e.g. with the skip, seek # and/or count arguments) then the bash shell offers the "$(( ))" syntax. # It is basically integer arithmetic, probably up to 64 bits precision, # with hex number accepted (leading 0x) but without multiplier suffixes # (e.g. $((1M + 1)) is not accepted). See the "ARITHMETIC EVALUATION" # section in the bash man page. $ ddpt if=/dev/sg1 skip=$((0xfff + 1)) count=1 # Douglas Gilbert 20110121 ddpt-0.92/doc/Makefile.in0000644000175000017500000003035711526513027014217 0ustar douggdougg# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, # Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = doc DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = SOURCES = DIST_SOURCES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' man8dir = $(mandir)/man8 am__installdirs = "$(DESTDIR)$(man8dir)" NROFF = nroff MANS = $(man_MANS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ SET_MAKE = @SET_MAKE@ SGUTILS_LIBS = @SGUTILS_LIBS@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ os_deps = @os_deps@ os_libs = @os_libs@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ rt_libs = @rt_libs@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ man_MANS = ddpt.8 all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu doc/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-man8: $(man_MANS) @$(NORMAL_INSTALL) test -z "$(man8dir)" || $(MKDIR_P) "$(DESTDIR)$(man8dir)" @list=''; test -n "$(man8dir)" || exit 0; \ { for i in $$list; do echo "$$i"; done; \ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.8[a-z]*$$/p'; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \ done; } uninstall-man8: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man8dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.8[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ test -z "$$files" || { \ echo " ( cd '$(DESTDIR)$(man8dir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(man8dir)" && rm -f $$files; } tags: TAGS TAGS: ctags: CTAGS CTAGS: distdir: $(DISTFILES) @list='$(MANS)'; if test -n "$$list"; then \ list=`for p in $$list; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \ if test -n "$$list" && \ grep 'ab help2man is required to generate this page' $$list >/dev/null; then \ echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \ grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \ echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \ echo " typically \`make maintainer-clean' will remove them" >&2; \ exit 1; \ else :; fi; \ else :; fi @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(MANS) installdirs: for dir in "$(DESTDIR)$(man8dir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-man install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-man8 install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-man uninstall-man: uninstall-man8 .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic distclean \ distclean-generic distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-man8 install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic pdf pdf-am ps ps-am uninstall \ uninstall-am uninstall-man uninstall-man8 # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: ddpt-0.92/doc/ddpt.80000644000175000017500000012465511527261361013205 0ustar douggdougg.TH DDPT "8" "February 2011" "ddpt\-0.92" DDPT .SH NAME ddpt \- copies data between files and storage devices. Support for devices that understand the SCSI command set. .SH SYNOPSIS .B ddpt [\fIbpt=BPT[,OBPC]\fR] [\fIbs=BS\fR] [\fIcdbsz=\fR6|10|12|16] [\fIcoe=\fR0|1] [\fIcoe_limit=CL\fR] [\fIconv=CONVS\fR] [\fIcount=COUNT\fR] [\fIibs=IBS\fR] \fIif=IFILE\fR [\fIiflag=FLAGS\fR] [\fIobs=OBS\fR] [\fIof=OFILE\fR] [\fIof2=OFILE2\fR] [\fIoflag=FLAGS\fR] [\fIretries=RETR\fR] [\fIseek=SEEK\fR] [\fIskip=SKIP\fR] [\fIstatus=STAT\fR] [\fIverbose=VERB\fR] [\fI\-\-help\fR] [\fI\-\-verbose\fR] [\fI\-\-version\fR] [\fI\-\-wscan\fR] .PP For comparison here is the synopsis for GNU's dd command: .PP .B dd [\fIbs=BS\fR] [\fIcbs=CBS\fR] [\fIconv=CONVS\fR] [\fIcount=COUNT\fR] [\fIibs=IBS\fR] [\fIif=IFILE\fR] [\fIiflag=FLAGS\fR] [\fIobs=OBS\fR] [\fIof=OFILE\fR] [\fIoflag=FLAGS\fR] [\fIseek=SEEK\fR] [\fIskip=SKIP\fR] [\fIstatus=STAT\fR] [\fI\-\-help\fR] [\fI\-\-version\fR] .SH DESCRIPTION .\" Add any additional description here .PP Copy data between files or read data from a file. Specialized for "files" that are storage devices, especially those that can use the SCSI command sets (e.g. SATA and SAS disks, plus DVD drives). Can issue SCSI commands in pass\-through ("pt") mode. Similar syntax and semantics to the Unix .B dd(1) command. .PP For comparison, the SYNOPSIS section above shows both the .B ddpt command line options followed by GNU's .B dd(1) command line options. Broadly speaking ddpt can be considered a super-set of dd. See the section on DD DIFFERENCES for significant differences between ddpt and dd. .PP ddpt does a segmented copy, first reading in \fIBPT*IBS\fR bytes from \fIIFILE\fR (or less if near the end of the copy) into a copy buffer. In the absence of the various options and conditions that bypass the write operation, the copy buffer is then written out to \fIOFILE\fR. The copy process continues working its way along \fIIFILE\fR and \fIOFILE\fR until either \fICOUNT\fR is exhausted, an end of file is detected, or an error occurs. If \fIIBS\fR and \fIOBS\fR are different, ddpt restricts the value of \fIOBS\fR such that the copy buffer is an integral number output blocks (i.e. (((\fIIBS*BPT\fR) % \fIOBS\fR) == 0) ). In the following descriptions, "segment" refers to all or part of a copy buffer. .PP The term "pt device" is used for a pass\-through device to which SCSI commands like READ(10) and WRITE(10) may be sent. A pt device may only be able to process SCSI commands in which case the "pt" flag is assumed. The ability to recognize such a pt only device may vary depending on the operating system (e.g. in Linux '/dev/sg2' is recognized). However if a device can process either normal UNIX read()/write() calls or pass\-through SCSI commands then the default is to use UNIX read()/write() calls. That default can be overridden by using the "pt" flag (e.g. "if=/dev/sdc iflag=pt"). When pt access is specified any partition information is .B ignored. So "if=/dev/sdc2 iflag=pt skip=3" will start at logical block address 3 of '/dev/sdc'. As a protection measure in version 0.92 ddpt will only accept that if the force flag is given in addition to pt. .SH OPTIONS .TP \fBbpt\fR=\fIBPT[,OBPC]\fR where \fIBPT\fR is Blocks Per Transfer. The copy is made up of multiple transfers, each first reading \fIBPT\fR input blocks (i.e. \fIBPT*IBS\fR bytes) from \fIIFILE\fR into the copy buffer and then from that copy buffer writing \fIBPT*IBS/OBS\fR output blocks to \fIOFILE\fR. This continues until the copy is finished, with the last transfer being potentially shorter. The default \fIBPT\fR value varies depending on \fIIBS\fR. When \fIIBS\fR < 8, \fIBPT\fR is 8192; when \fIIBS\fR < 64, \fIBPT\fR is 1024; when \fIIBS\fR < 1024, \fIBPT\fR is 128; when \fIIBS\fR < 8192, \fIBPT\fR is 16; when \fIIBS\fR < 32768, \fIBPT\fR is 4; else \fIBPT\fR defaults to 1. If \fIBPT\fR is given as 0 it is treated as the default value. For "bs=512", \fIBPT\fR defaults to 128 so that 64 KiB (or less) is read from \fIIFILE\fR into the copy buffer. .br The optional \fIOBPC\fR (Output Blocks Per Check) argument controls controls the granularity of sparse writes, write sparing and trim checks. The default granularity is the size of the copy buffer (i.e. \fIBPT*IBS\fR bytes). That can be reduced by specifying \fIOBPC\fR. The finest granularity is when \fIOBPC\fR is 1 which implies the unit of each check is \fIOBS\fR bytes. When \fIOBPC\fR is 0, or not given, the default granularity is used. Large \fIOBPC\fR values are rounded down so that \fIOBPC*OBS\fR does not exceed the size of the copy buffer. .TP \fBbs\fR=\fIBS\fR where \fIBS\fR is the \fIIFILE\fR and \fIOFILE\fR block size in bytes. Conflicts with either "ibs=" or "obs=" options. The value of \fIBS\fR is placed in \fIIBS\fR and \fIOBS\fR. If \fIIFILE\fR or \fIOFILE\fR is a "pt" device then \fIBS\fR .B must be the logical block size of the device. See the DD DIFFERENCES section below. Default is 512 which to date has been correct for hard disks. Other logical block sizes are 2048 bytes for DVDs and 4096 bytes for the coming generation of hard disks. .TP \fBcdbsz\fR=6 | 10 | 12 | 16 size of SCSI READ and/or WRITE commands issued on pt devices. Default is 10 byte SCSI command blocks (unless calculations indicate that a 4 byte block number may be exceeded or \fIBPT\fR is greater than 16 bits (65535), in which case it defaults to 16 byte SCSI commands). .TP \fBcoe\fR=0 | 1 set to 1 for continue on error. Applies to errors on input and output pt devices plus input from block devices or regular files. Errors on other files will stop ddpt. Default is 0 which implies stop on any error. See the 'coe' flag for more information. .TP \fBcoe_limit\fR=\fICL\fR where \fICL\fR is the maximum number of consecutive bad blocks stepped over (due to "coe=1") on reads before the copy terminates. The default is 0 which is interpreted as no limit. This option is meant to stop the copy soon after unrecorded media is detected while still offering "continue on error" capability. .TP \fBconv\fR=\fICONVS\fR see the CONVERSIONS section below. .TP \fBcount\fR=\fICOUNT\fR copy \fICOUNT\fR input blocks from \fIIFILE\fR to \fIOFILE\fR. If this option is not given (or \fICOUNT\fR is '\-1') then the \fICOUNT\fR may be deduced from either \fIIFILE\fR or \fIOFILE\fR. See the COUNT section below. .TP \fBibs\fR=\fIIBS\fR where \fIIBS\fR is the \fIIFILE\fR block size in bytes. The default value is \fIBS\fR or its default (512). Conflicts the "bs=" option (e.g. giving both "bs=512 ibs=512" is considered a syntax error). .TP \fBif\fR=\fIIFILE\fR read from \fIIFILE\fR. This option must be given (i.e. it is mandatory). If \fIIFILE\fR is '\-' then stdin is read. Starts reading at the beginning of \fIIFILE\fR unless \fISKIP\fR is given. .TP \fBiflag\fR=\fIFLAGS\fR where \fIFLAGS\fR is a comma separated list of one or more flags outlined in the FLAGS section below. These flags are associated with \fIIFILE\fR and are ignored when \fIIFILE\fR is stdin. .TP \fBobs\fR=\fIOBS\fR where \fIOBS\fR is the \fIOFILE\fR block size in bytes. The default value is \fIBS\fR or its default (512). Conflicts the "bs=" option (e.g. giving both "bs=512 obs=512" is considered a syntax error). If \fIOBS\fR is given then it has the following restriction: the integer expression (((\fIIBS\fR * \fIBPT\fR) % \fIOBS\fR) == 0) must be true. Stated another way: the copy buffer size must be an integral multiple of \fIOBS\fR. If \fIof2=OFILE2\fR is given then \fIOBS\fR is its block size as well. .TP \fBof\fR=\fIOFILE\fR write to \fIOFILE\fR. The default value is /dev/null . If \fIOFILE\fR is '\-' then writes to stdout. If \fIOFILE\fR is /dev/null then no actual writes are performed. If \fIOFILE\fR is '.' (period) then it is treated the same way as /dev/null . If \fIOFILE\fR exists then it is _not_ truncated unless "oflag=trunc" is given. See section on DD DIFFERENCES. .TP \fBof2\fR=\fIOFILE2\fR write output to \fIOFILE2\fR. The default action is not to do this additional write (i.e. when this option is not given). \fIOFILE2\fR is assumed to be a regular file or a fifo (i.e. a named pipe). \fIOFILE2\fR is opened for writing and is created if necessary. If \fIOFILE2\fR is a fifo (named pipe) then some other command should be consuming that data (e.g. 'md5sum OFILE2'), otherwise this utility will block. The write to \fIOFILE2\fR occurs before the write to \fIOFILE\fR and prior to sparse writing and write sparing logic. So everything read is written to \fIOFILE2\fR. .TP \fBoflag\fR=\fIFLAGS\fR where \fIFLAGS\fR is a comma separated list of one or more flags outlined in the FLAGS section. These flags are associated with \fIOFILE\fR and are ignored when \fIOFILE\fR is /dev/null, '.' (period), or stdout. .TP \fBretries\fR=\fIRETR\fR sometimes retries at the host are useful, for example when there is a transport error. When \fIRETR\fR is greater than zero then SCSI READs and WRITEs are retried on error, \fIRETR\fR times. Default value is zero. Only applies to errors on pt devices. .TP \fBseek\fR=\fISEEK\fR start writing \fISEEK\fR blocks (each of \fIOBS\fR bytes) from the start of \fIOFILE\fR. Default is block 0 (i.e. start of file). The \fISEEK\fR value may exceed the number of \fIOBS\fR\-sized blocks in \fIOFILE\fR. .TP \fBskip\fR=\fISKIP\fR start reading \fISKIP\fR blocks (each of \fIIBS\fR bytes) from the start of \fIIFILE\fR. Default is block 0 (i.e. start of file). The \fISKIP\fR value must be less than or equal to the number of \fIIBS\fR\-sized blocks in \fIIFILE\fR. .TP \fBstatus\fR=\fISTAT\fR the \fISTAT\fR value of 'noxfer' suppresses the throughput speed and the copy time output at the end of the copy. The "status=noxfer" option was recently introduced to GNU's dd command. The default action of ddpt is to show the throughput (in megabytes per second) and the time taken to do the copy after the "records in" and "records out" lines at the end of the copy. As a convenience the value 'null' is accepted for \fISTAT\fR and does nothing. .TP \fBverbose\fR=\fIVERB\fR as \fIVERB\fR increases so does the amount of debug output sent to stderr. Default value is zero which yields the minimum amount of debug output. A value of 1 reports extra information that is not repetitive. A value 2 reports cdbs and responses for SCSI commands that are not repetitive (i.e. other that READ and WRITE). Error processing is not considered repetitive. Values of 3 and 4 yield output for all SCSI commands, plus Unix read() and write() calls, so there can be a lot of output. If \fIVERB\fR is "\-1" then output otherwise sent to stderr is redirected to /dev/null . .TP \fB\-h\fR, \fB\-\-help\fR outputs usage message and exits. .TP \fB\-v\fR, \fB\-\-verbose\fR equivalent of \fIverbose=1\fR. If \fI\-\-verbose\fR appears twice then that is equivalent to \fIverbose=2\fR. Also \fI\-vv\fR is equivalent to \fIverbose=2\fR. .TP \fB\-V\fR, \fB\-\-version\fR outputs version number information and exits. .TP \fB\-w\fR, \fB\-\-wscan\fR this option is available in Windows only. It lists storage device names and the corresponding volumes, if any. When used twice it adds the "bus type" of the closest transport (e.g. a SATA disk in a USB connected enclosure has bus type Usb). When used three times a SCSI adapter scan is added. When used four times only a SCSI adapter scan is shown. See EXAMPLES section below and the README.win32 file. .SH COUNT When the \fIcount=COUNT\fR option is not given (or \fICOUNT\fR is '\-1') then an attempt is made to deduce \fICOUNT\fR as follows. .PP When both or either \fIIFILE\fR and \fIOFILE\fR are block devices, then the minimum size, expressed in units of input blocks, is used. When both or either \fIIFILE\fR and \fIOFILE\fR are pass\-through devices, then the minimum size, expressed in units of input blocks, is used. .PP If a regular file is used as input, its size, expressed in units of input blocks (and rounded up if necessary) is used. Note that the rounding up of the deduced \fICOUNT\fR may result in a partial read of the last input block and a corresponding partial write to \fIOFILE\fR if it is a regular file. .PP The size of pt devices is deduced from the SCSI READ CAPACITY command. Block device sizes (or their partition sizes) are obtained from the operating system, if available. .PP If \fIskip=SKIP\fR or \fIskip=SEEK\fR are given and the \fICOUNT\fR is deduced (i.e. not explicitly given) then that size is scaled back so that the copy will not overrun the file or device. .PP If \fICOUNT\fR is not given and \fIIFILE\fR is a fifo (and stdin is treated as a fifo) then \fIIFILE\fR is read until an EOF is detected. If \fICOUNT\fR is not given and \fIIFILE\fR is a /dev/zero (or equivalent) then zeros are read until an error occurs (e.g. file system full). .PP If \fICOUNT\fR is not given and cannot be deduced then an error message is issued and no copy takes place. .SH CONVERSIONS One or more conversions can be given to the "conv=" option. If more than one is given, they should be comma separated. ddpt does not perform the traditional dd conversions (e.g. ASCII to EBCDIC). Recently added conversions overlap somewhat with the flags so some conversions are now supported by ddpt. .TP fdatasync equivalent to "oflag=fdatasync". Flushes data associated with the \fIOFILE\fR to storage at the end of the copy. This conversion is for compatibility with GNU's dd. .TP fsync equivalent to "oflag=fsync". Flushes data and meta-data associated with the \fIOFILE\fR to storage at the end of the copy. This conversion is for compatibility with GNU's dd. .TP noerror this conversion is very close to "iflag=coe" and is treated as such. See the "coe" flag. Note that an error on \fIOFILE\fR will stop the copy. .TP null has no affect, just a placeholder. .TP resume See "resume" in the FLAGS sections for more information. .TP sparing See "sparing" in the FLAGS sections for more information. .TP sparse FreeBSD supports "conv=sparse" so the same syntax is supported in ddpt. See "sparse" in the FLAGS sections for more information. .TP sync is ignored by ddpt. With dd it means supply zero fill (rather than skip) and is typically used like this "conv=noerror,sync" to have the same functionality as ddpt's "iflag=coe". .TP trunc if \fIOFILE\fR is a regular file then truncate it prior to starting the copy. See "trunc" in the FLAGS section. .SH FLAGS A list of flags and their meanings follow. The flag name is followed by one or two indications in square brackets. The first indication is either "[i]", "[o]" or "[io]" indicating this flag is active for the \fIIFILE\fR, \fIOFILE\fR or both the \fIIFILE\fR and the \fIOFILE\fR. The second indication contains some combination of "reg", "blk" or "pt" indicating whether the flag applies to a regular file, a block device (accessed via Unix read() and write() commands) or a pass\-through device respectively. .TP append [o] [reg] causes the O_APPEND flag to be added to the open of \fIOFILE\fR. For regular files this will lead to data appended to the end of any existing data. Conflicts the \fIseek=SEEK\fR option. The default action of this utility is to overwrite any existing data from the beginning of \fIOFILE\fR or, if \fISEEK\fR is given, starting at block \fISEEK\fR. Note that attempting to 'append' to a device file (e.g. a disk) will usually be ignored or may cause an error to be reported. .TP .I coe [io] [pt], [i] [reg,blk] continue on error. 'iflag=coe oflag=coe' and 'coe=1' are equivalent. Errors occurring on output regular or block files will stop ddpt. Error messages are sent to stderr. This flag is similar to 'conv=noerror,sync' in the .B dd(1) utility. Unrecovered errors are counted and output in the summary at the end of the copy. .IP This paragraph is about coe on pt devices. A medium, hardware or blank check error while reading will re\-read blocks prior to the bad block, then try to recover the bad block, supplying zeros if that fails, and finally reread the blocks after the bad block. A medium, hardware or blank check error while writing is noted and ignored. SCSI disks may automatically try and remap faulty sectors (see the AWRE and ARRE in the read write error recovery mode page (the sdparm utility can access these attributes)). If bad LBAs are reported by the pass\-through then the LBA of the lowest and highest bad block is also output. .IP This paragraph is about coe on input regular files and block devices. When a EIO or EREMOTEIO error is detected on a normal segment read then the segment is re\-read one block (i.e. \fIIBS\fR bytes) at a time. Any block that yields a EIO or EREMOTEIO error is replaced by zeros. Any other error, a short read or an end of file will terminate the copy, usually after the data that has been read is written to the output file. .TP direct [io] [reg,blk] causes the O_DIRECT flag to be added to the open of \fIIFILE\fR and/or \fIOFILE\fR. This flag requires some memory alignment on IO. Hence user memory buffers are aligned to the page size. May have no effect on pt devices. This flag will bypass caching/buffering normally done by block layer. Beware of data coherency issues if the same locations have been recently accessed via the block layer in its normal mode (i.e. non\-direct). See open(2) man page. .TP dpo [io] [pt] set the DPO bit (disable page out) in SCSI READ and WRITE commands. Not supported for 6 byte cdb variants of READ and WRITE. Indicates that data is unlikely to be required to stay in device (e.g. disk) cache. May speed media copy and/or cause a media copy to have less impact on other device users. .TP errblk [i] [pt] [experimental] attempts to create or append to a file called "errblk.txt" in the current directory the logical block addresses of blocks that cannot be read. The first (appended) line is "# start ". That is followed by the LBAs in hex (and prefixed with "0x") of any block that cannot be read, one LBA per line. If the sense data does not correctly identify the LBA of the first error in the range it was asked to read then a LBA range is output in the form of the lowest and the highest LBA in the range separated by a "\-". At the end of the copy a line with "# stop " is appended to "errblk.txt". Typically used with "coe". .TP excl [io] [reg,blk] causes the O_EXCL flag to be added to the open of \fIIFILE\fR and/or \fIOFILE\fR. See open(2) man page. .TP fdatasync [o] [reg,blk] Flushes data associated with the \fIOFILE\fR to storage at the end of the copy. .TP flock [io] [reg,blk,pt] after opening the associated file (i.e. \fIIFILE\fR and/or \fIOFILE\fR) an attempt is made to get an advisory exclusive lock with the flock() system call. The flock arguments are "FLOCK_EX | FLOCK_NB" which will cause the lock to be taken if available else a "temporarily unavailable" error is generated. An exit status of 90 is produced in the latter case and no copy is done. See flock(2) man page. .TP force [io] [pt] override difference between given block size and the block size found by the SCSI READ CAPACITY command. Use the given block size. Without this flag the copy would not be performed. pt access to what appears to be a block partition is aborted in version 0.92; that can be overridden by the force flag. For related reasons the 'norcap' flag requires this flag when applied to a block device accessed via pt. .TP fsync [o] [reg,blk] Flushes data and metadata (describing the file) associated with the \fIOFILE\fR to storage at the end of the copy. .TP fua [io] [pt] causes the FUA (force unit access) bit to be set in SCSI READ and/or WRITE commands. The 6 byte variants of the SCSI READ and WRITE commands do not support the FUA bit. .TP fua_nv [io] [pt] causes the FUA_NV (force unit access non\-volatile cache) bit to be set in SCSI READ and/or WRITE commands. This only has an effect with pt devices. The 6 byte variants of the SCSI READ and WRITE commands do not support the FUA_NV bit. .TP nocache [io] [reg,blk] use posix_fadvise() to advise corresponding file there is no need to fill the file buffer with recently read or written blocks. If used with "iflag=" it will increase the read ahead on \fIIFILE\fR. .TP norcap [io] [pt] do not perform SCSI READ CAPACITY command on the corresponding pt device. If used on block device accessed via pt then 'force' flag is also required. This is to warn about using pt access on what may be a block device partition. .TP nowrite [o] [reg,blk,pt] bypass writes to \fIOFILE\fR. The "records out" count is not incremented. \fIOFILE\fR is still opened but "oflag=trunc" if given is ignored. Also the ftruncate call associated with the sparse flag is ignored (i.e. bypassed). Commands such as trim and SCSI SYNCHRONIZE CACHE are still sent. .TP null [io] has no affect, just a placeholder. .TP pt [io] [blk,pt] causes a device to be accessed in "pt" mode. In "pt" mode SCSI READ and WRITE commands are sent to access blocks rather than standard UNIX read() and write() commands. The "pt" mode may be implicit if the device is only capable of passing through SCSI commands (e.g. the /dev/sg devices in Linux). This flag is needed for device nodes that can be accessed both via standard UNIX read() and write() commands as well as SCSI commands. Such devices default standard UNIX read() and write() commands in the absence of this flag. .TP resume [o] [reg] when a copy is interrupted (e.g. with Control\-C from the keyboard) then using the same invocation again with the addition of "oflag=resume" will attempt to restart the copy from the point of the interrupt (or just before that point). It is harmless to use "oflag=resume" when \fIOFILE\fR doesn't exist or is zero length. If the length of \fIOFILE\fR is greater than or equal to the length implied by a ddpt invocation that includes "oflag=resume" then no further data is copied. .TP self [io] [pt] used together with trim flag to do a self trim (trim of segments of a pt device that contain all zeros). If \fIOFILE\fR is not given, then it is set to the same as \fIIFILE\fR. If \fISEEK\fR is not given it set to the same value as \fISKIP\fR (possibly adjusted if \fIIBS\fR and \fIOBS\fR are different). Implicitly sets "nowrite" flag. .TP sparing [o] [reg,blk,pt] during the copy each \fIIBS\fR * \fIBPT\fR byte segment is read from \fIIFILE\fR into a buffer. Then, instead of writing that buffer to \fIOFILE\fR, the corresponding segment is read from \fIOFILE\fR into another buffer. If the two buffers are different, the former buffer is written to the \fIOFILE\fR. If the two buffers compare equal then the write to \fIOFILE\fR is not performed. Write sparing is useful when a write operation is significantly slower than a read. Under some conditions flash memory devices have slow writes plus an upper limit on the number of times the same cell can be rewritten. The granularity of the comparison can be reduced from the default \fIIBS\fR * \fIBPT\fR byte segment with the the \fIOBPC\fR value given to the "bpt=" option. The finest granularity is when \fIOBPC\fR is 1 which implies \fIOBS\fR bytes. .TP sparse [o] [reg,blk,pt] after each \fIIBS\fR * \fIBPT\fR byte segment is read from \fIIFILE\fR, it is checked to see if it is all zeros. If so, that segment is not written to \fIOFILE\fR. See the section on SPARSE WRITES below. The granularity of the zero comparison can be reduced from the default \fIIBS\fR * \fIBPT\fR byte segment with the \fIOBPC\fR value given to the "bpt=" option. .TP ssync [o] [pt] if \fIOFILE\fR is in "pt" mode then the SCSI SYNCHRONIZE CACHE command is sent to \fIOFILE\fR at the end of the copy. .TP strunc [o] [reg] perform a sparse copy with a ftruncate system call to extend the length of the \fIOFILE\fR if required. See the sparse flag and the section on SPARSE WRITES below. .TP sync [io] [reg,blk] causes the O_SYNC flag to be added to the open of \fIIFILE\fR and/or \fIOFILE\fR. See open(2) man page. .TP trim [io] [pt] [experimental] similar logic to the "sparse" option. However instead of skipping segments that are full of zeros a "trim" command is sent to \fIOFILE\fR. Usually set as an oflag argument but for self trim can be used as an iflag argument (e.g. "iflag=self,trim"). Depending on the usage this may require the device to support "deterministic read zero after trim". See the TRIM, UNMAP AND WRITE SAME section below. .TP trunc [o] [reg] if \fIOFILE\fR is a regular file then it is truncated prior to starting the copy. If \fISEEK\fR is not given or 0 then \fIOFILE\fR is truncated to zero length; when \fISEEK\fR is larger than zero the truncation takes place at file byte pointer \fISEEK*OBS\fR. Ignored if "oflag=append". Conflicts with "oflag=sparing". .SH SPARSE WRITES Bypassing writes of blocks full of zeros can save a lot of IO. However with regular files, bypassed writes at the end of the copy can lead to an \fIOFILE\fR which is shorter than it would have been without sparse writes. This can lead to integrity checking programs like md5sum and sha1sum generating different values. .PP This utility has two ways of handling this file length problem: writing the last block (even if it is full of zeros) or using the ftruncate system call. A third approach is to ignore the problem (i.e. leaving \fIOFILE\fR shorter). The ftruncate approach is used when "oflag=strunc" while the last block is written when "oflag=sparse". To ignore the file length issue use "oflag=sparse,sparse". Note that if \fIOFILE\fR's length is already correct or longer than required, no action is taken. .PP The support for sparse writing of regular files may depend on the OS, the file system and the settings of \fIOFILE\fR. POSIX makes few guarantees when the ftruncate system call is used to extend a file's length, as may occur when "oflag=strunc". Further, primitive file systems like VFAT may not accept sparse writes or simulate the effect by writing blocks of zeros. The latter approach will defeat any sparse writing performance gain. .SH TRIM, UNMAP AND WRITE SAME This is a new storage feature often associated with Solid State Disks (SSDs) or disk arrays with "thin provisioning". In the ATA command set (ACS\-2) the relevant command is DATA SET MANAGEMENT with the TRIM bit set. In the SCSI command set (SBC\-3) it is either the UNMAP or WRITE SAME command. Note there is no TRIM command however the term is frequently used in the technical press. .PP Trim is a way of telling a storage device that blocks are no longer needed. Keeping the pool of unwritten blocks large is important for the write performance of SSDs and the thrifty use of real storage in thin provisioned arrays. Currently file systems in recent OSes may issue trims associated with file deletes. The trim option in ddpt may be useful when a partition or a whole SSD is to be "deleted". Note that ddpt is bypassing file systems in that it only offers trim on pass\-through (pt) devices. .PP This utility issues SCSI commands to pt devices and for "trim" currently issues a SCSI WRITE SAME(16) command with the UNMAP bit set. If the pt device is a SSD with a ATA interface then recent versions of Linux will translate the SCSI WRITE SAME to the ATA DATA SET MANAGEMENT command with the TRIM bit set. The maximum size of each "trim" command sent is the size of the copy buffer (i.e. \fIIBS\fR * \fIBPT\fR bytes). And that maximum can be reduced with the \fIOBPC\fR argument of the "bpt=" option. .PP The trim can be used various ways. One way is a copy where the copy buffer (or some part of it) is checked for zeros as is done by the sparse oflag. When a zero segment is found, a trim "command" is sent to the \fIOFILE\fR. For example: .PP ddpt if=dsk.img bs=512 of=/dev/sdc oflag=pt,trim .PP The copy buffer is 64 KiB (since \fIBPT\fR and \fIOBPC\fR default to 128 when "bs=512") and it is checked for all zeros. If it is all zeros then a trim command is sent to the corresponding location of /dev/sdc which is accessed via the pt interface. If it is not all zeros then a SCSI WRITE command is sent. Another way is to trim all or part of a disk. To trim a whole disk (i.e. deleting all its data): .PP ddpt if=/dev/zero bs=512 of=/dev/sdc oflag=pt,trim .PP A third way is to "self\-trim" which is to only trim those parts of a disk that contain segments full of zeros: .PP ddpt if=/dev/sdc skip=0x2300 bs=512 iflag=pt,self,trim count=0x1234f0 .PP The "self" oflag automatically sets up the output side of the copy to send trim commands (if required) back the the same device (i.e. /dev/sdc). If this example was self\-trimming a partition then the partition would start at LBA 0x2300 and be 0x1234f0 blocks long. .PP Some random product examples: the Intel X25\-M G2 SSDs have trim with recent firmware and they do deterministic read zero after trim. The Seagate Pulsar SSD has an ATA interface which supports the deterministic reads of zero after the DATA SET MANAGEMENT command with the TRIM option. .SH DD DIFFERENCES dd defaults "if=" and "of=" to stdin and stdout respectively. This follows Unix filter conventions. However since dd and ddpt are often used to read binary data for timing purposes, having to supply "of=/dev/null" can be easily forgotten. Without it dd will potentially spew binary data on the console. So ddpt has changed its defaults: the "if=\fIIFILE\fR" is now mandatory and to read from stdin "if=\-" can be used; "of=\fIOFILE\fR" remains optional but its default changes to "/dev/null" (or "NUL" in Windows). To send output to stdout ddpt accepts "of=\-". .PP dd truncates \fIOFILE\fR unless "conv=notrunc" is given. When dd truncates, it truncates to zero length unless \fISEEK\fR is greater than zero. ddpt does not truncate \fIOFILE\fR by default. If \fIOFILE\fR exists it will be overwritten. The overwrite starts at block zero unless \fISEEK\fR or "oflag=append" is given. If \fIOFILE\fR is a regular file then "oflag=trunc" (or "conv=trunc") will truncate \fIOFILE\fR prior to the copy. .PP Numeric arguments to ddpt can be given in hexadecimal, either with a leading "0x" or "0X" or with a trailing "h". Note that dd accepts "0x123" but interprets it as "0 * 123" (i.e. zero). ddpt will also interpret "x" as multiplies unless the left operand is zero (e.g. "0x123"). So both dd and ddpt will interpret "skip=2x123" as "skip=246". .PP Terabyte size disks make it impractical to copy all the data into a buffer before writing it out. Therefore both dd and ddpt read a relatively small amount of data into a copy (or transfer) buffer then write it out to the destination, repeating this process until the \fICOUNT\fR is exhausted. .PP A major difference in ddpt is the addition of \fIBPT\fR to control the size of the copy buffer. With dd, \fIIBS\fR is the size of the copy buffer and the unit of \fISKIP\fR and \fICOUNT\fR. With ddpt, \fIIBS\fR * \fIBPT\fR is the size of the copy buffer and \fIIBS\fR is the unit of \fISKIP\fR and \fICOUNT\fR. This allows ddpt to have its \fIIBS\fR set to the logical block size of \fIIFILE\fR without unduly restricting the size of the copy buffer. And setting \fIIBS\fR (and \fIOBS\fR for \fIOFILE\fR) accurately is required when the pass\-through interface is used since with the SCSI READ and WRITE commands the logical block size is implicit. .PP The way dd handles its copy buffer (outlined in SUSv4 description of dd) is relatively complex, especially when \fIIBS\fR and \fIOBS\fR are different sizes. The restriction that ddpt places on \fIIBS\fR and \fIOBS\fR ( i.e. (((\fIIBS*BPT\fR) % \fIOBS\fR) == 0) ) means that a single copy buffer can be used since its size is a multiple of both \fIIBS\fR and \fIOBS\fR. Being able to precisely define the copy buffer size in ddpt makes sparse writing, write sparing and trim operations simpler to define and the user to control. .PP ddpt does not support dd's "cbs=" option (conversion block size). If the "cbs=" option is given to ddpt then it is ignored. .SH NOTES A partial write is a write to the \fIOFILE\fR of less than \fIOBS\fR bytes. This typically occurs at the end of a copy. dd can do partial writes. ddpt does partial writes to regular files and fifos (including stdout). However ddpt ignores partial writes when \fIOFILE\fR is a block device or a pt device. When ddpt ignores a partial write, it sends a warning to the console (stderr). .PP At the end of the copy two lines are output to the console: .br + records in .br + records out .PP The "records in" line is the number of full input blocks (each of \fIIBS\fR bytes) that have been read plus the number of partial blocks ( usually less than \fIIBS\fR bytes) that have been read. Following the lead of dd when 'iflag=coe' is active a block that cannot be read (and has zeros substituted for its output) is regarded as a partial read. The "records out" line is the number of full output blocks (each of \fIOBS\fR bytes) that have been written plus the number of partial blocks (usually less than \fIOBS\fR bytes) that have been written. .PP Block devices (e.g. /dev/sda and /dev/hda) can be given for \fIIFILE\fR. If neither 'iflag=direct' nor 'iflag=pt' is given then normal block IO involving buffering and caching is performed. If 'iflag=direct' is given then the buffering and caching is bypassed (this is applicable to both SCSI devices and ATA disks). When 'iflag=pt' is given SCSI commands are sent to the device which bypasses most of the actions performed by the block layer. The same applies for block devices given for \fIOFILE\fR. .PP \fIBPT\fR, \fIBS\fR, \fICOUNT\fR, \fIIBS\fR, \fIOBPC\fR, \fIOBS\fR, \fISKIP\fR and \fISEEK\fR may include one of these multiplicative suffixes: c C *1; w W *2; b B *512; k K KiB *1,024; KB *1,000; m M MiB *1,048,576; MB *1,000,000 . This pattern continues for "G", "T" and "P". The latter two suffixes can only be used for \fICOUNT\fR, \fISKIP\fR and \fISEEK\fR. Also a suffix of the form "x" multiplies the leading number by ; however the combinations "0x" and "0X" are treated differently, see the next paragraph. These multiplicative suffixes are compatible with GNU's dd command (since 2002) which claims compliance with the SI and with IEC 60027\-2 standards. .PP Alternatively numerical values can be given in hexadecimal preceded by either "0x" or "0X" (or with a trailing "h" or "H"). When hex numbers are given, multipliers cannot be used. .PP The \fICOUNT\fR, \fISKIP\fR and \fISEEK\fR arguments can take 64 bit values (i.e. very big numbers). Other numerical values are limited to what can fit in a signed 32 bit number. .PP All informative, warning and error output is sent to stderr so that dd's output file can be stdout and remain unpolluted. If no options are given, then the usage message is output and nothing else happens. .PP Disk partition information can often be found with .B fdisk(8) [the "\-ul" argument is useful in this respect]. Also .B parted(8) can be used like this: 'parted /dev/sda unit s print' . .PP For pt devices this utility issues SCSI READ and WRITE (SBC) commands which are appropriate for disks and reading from CD/DVD/BD drives. Those commands are not formatted correctly for tape devices so ddpt should not be used on tape devices. If the largest block address of the requested transfer exceeds a 32 bit block number (i.e 0xffffffff) then a warning is issued and the sg device is accessed via SCSI READ(16) and WRITE(16) commands. .PP .B The attributes of a block device (e.g. partitions) are ignored when the .B pt flag is used. Hence the whole device is read (rather than just the second partition) by this invocation: .PP ddpt if=/dev/sdb2 iflag=pt of=t bs=512 .PP Assuming /dev/sdb and /dev/sg2 refer to the same device, then after the following two invocations, the contents of the files "t", "tt" and "ttt" should be same: .PP ddpt if=/dev/sdb of=tt bs=512 .PP ddpt if=/dev/sg2 of=ttt bs=512 .SH EXAMPLES The examples in this page use Linux device names. For suitable device names in other supported Operating Systems see this web page: http://sg.danny.cz/sg/device_name.html . The sg3_utils(8) man page in the sg3_utils package also covers device naming. .PP ddpt usage looks quite similar to dd: .PP ddpt if=/dev/sg0 of=t bs=512 count=1MB .PP This will copy 1 million 512 byte blocks from the device associated with /dev/sg0 (which should have 512 byte blocks) to a file called t. Assuming /dev/sda and /dev/sg0 are the same device then the above is equivalent to: .PP dd if=/dev/sda iflag=direct of=t bs=512 count=1000000 .PP although dd's speed may improve if bs was larger and count was suitably reduced. The use of the 'iflag=direct' option bypasses the buffering and caching that is usually done on a block device. .PP The dd command's bs argument can be thought of as roughly equivalent to ddpt's bs*bpt . dd almost assumes buffering on a block device and will work as long as bs is a multiple of the actual logical block size. Since ddpt can work at a lower level in some cases the bs argument must be a disk's actual logical block size. Thus the bpt argument was introduced to make the copy more efficient. So these two invocations are roughly equivalent: .PP dd if=/dev/sda of=t bs=8k count=64 .br ddpt if=/dev/sda of=t bs=512 bpt=16 count=1k .PP In both cases the total number of bytes moved is bs*count . And that will be done by reading 8k (8192 bytes) into a buffer then writing out that buffer to the file t. The read write sequence continues until the count is complete or an error occurs. .PP The 'of2=' option can save time when the input would otherwise need to be read twice. For example, to copy data and take a md5sum of it without needing to re\-read the data: .PP mkfifo fif .br md5sum fif & .br ddpt if=/dev/sg3 iflag=coe of=sg3.img oflag=sparse of2=fif bs=512 .PP This will image /dev/sg3 (e.g. an unmounted disk) and place the contents in the (sparse) file sg3.img . Without re\-reading the data it will also perform a md5sum calculation on the image. .PP Now we use sparse writing logic to get some idea of how many blocks on a disk are full of zeros. After a SCSI FORMAT or an ATA SECURITY ERASE command a disk may be all zeros. .PP ddpt if=/dev/sdc bs=512 oflag=sparse .PP Since no "of=" option is given, output goes to /dev/null so nothing is actually written so the "records out" will be zero. However there will be a count of "records in" and "bypassed records out". If /dev/sdc is full of zeros then "records in" and "bypassed records out" will be the same. Since the "bpt=" option is not given it defaults to "bpt=128,128" so the copy buffer will be 64 KiB and the sparse check for zeros will be done with 64 KiB (128 block) granularity. .PP For examples of the trim and self,trim options see the section above on TRIM, UNMAP AND WRITE SAME. .PP Following is an example run on a Windows OS using the '\-\-wscan' option which shows the available device names (e.g. PD1) and the associated volume name(s): .PP ddpt -w .br PD0 [C] FUJITSU MHY2160BH 0000 .br PD1 [DF] WD 2500BEV External 1.05 WD-WXE90 .br CDROM0 [E] MATSHITA DVD/CDRW UJDA775 CB03 .PP So, for example, volumes D: and F: reside on PhysicalDisk1 (abbreviated to "PD1") which is manufactured by WD (Western Digital). .PP Further examples can be found on this web page: http://sg.danny.cz/sg/ddpt.html . There is a text file called ddpt_examples.txt in the "doc" directory of this package's distribution tarball. .SH SIGNALS The signal handling has been borrowed from dd: SIGINT, SIGQUIT and SIGPIPE output the number of remaining blocks to be transferred and the records in + out counts; then they have their default action. SIGUSR1 causes the same information to be output and the copy continues. All output caused by signals is sent to stderr. .SH EXIT STATUS To aid scripts that call ddpt, the exit status is set to indicate success (0) or failure (1 or more). Note that some of the lower values correspond to the SCSI sense key values. The exit status values are: .TP .B 0 success .TP .B 1 syntax error. Either illegal command line options, options with bad arguments or a combination of options that is not permitted. .TP .B 2 the device reports that it is not ready for the operation requested. The device may be in the process of becoming ready (e.g. spinning up but not at speed) so the utility may work after a wait. .TP .B 3 the device reports a medium or hardware error (or a blank check). For example an attempt to read a corrupted block on a disk will yield this value. .TP .B 5 the device reports an "illegal request" with an additional sense code other than "invalid operation code". This is often a supported command with a field set requesting an unsupported capability. .TP .B 6 the device reports a "unit attention" condition. This usually indicates that something unrelated to the requested command has occurred (e.g. a device reset) potentially before the current SCSI command was sent. The requested command has not been executed by the device. Note that unit attention conditions are usually only reported once by a device. .TP .B 9 the device reports an illegal request with an additional sense code of "invalid operation code" which means that it doesn't support the requested command. .TP .B 11 the device reports an aborted command. In some cases aborted commands can be retried immediately (e.g. if the transport aborted the command due to congestion). .TP .B 15 the utility is unable to open, close or use the given \fIIFILE\fR or \fIOFILE\fR. The given file name could be incorrect or there may be permission problems. Adding the \fI\-v\fR option may give more information. .TP .B 20 the device reports it has a check condition but "no sense". It is unlikely that this value will occur as an exit status. .TP .B 21 the device reports a "recovered error". The requested command was successful. Most likely a utility will report a recovered error to stderr and continue, probably leaving the utility with an exit status of 0 . .TP .B 33 the command sent to device has timed out. This occurs in Linux only; in other ports a command timeout will appear as a transport (or OS) error. .TP .B 90 the flock flag has been given on a device and some other process holds the advisory exclusive lock. .TP .B 97 the response to a SCSI command failed sanity checks. .TP .B 98 the device reports it has a check condition but the error doesn't fit into any of the above categories. .TP .B 99 any errors that can't be categorized into values 1 to 98 may yield this value. This includes transport and operating system errors after the command has been sent to the device. .SH AUTHORS Written by Doug Gilbert .SH "REPORTING BUGS" Report bugs to . .SH COPYRIGHT Copyright \(co 2008\-2011 Douglas Gilbert .br This software is distributed under the GPL version 2. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. .SH "SEE ALSO" There is a web page discussing ddpt at http://sg.danny.cz/sg/ddpt.html .PP The lmbench package contains .B lmdd which is also interesting. For moving data to and from tapes see .B dt which is found at http://www.scsifaq.org/RMiller_Tools/index.html .PP To change mode parameters that effect a SCSI device's caching and error recovery see .B sdparm(sdparm) .PP To scan and repair disk partitions see TestDisk (testdisk). .PP Additional references: .B dd(1), ddrescue(GNU), open(2), flock(2), sg_dd,sg3_utils(sg3_utils) ddpt-0.92/doc/Makefile.am0000644000175000017500000000002411353754242014176 0ustar douggdougg man_MANS = ddpt.8