⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 growisofs.c

📁 linux平台下的dvd刻录软件
💻 C
📖 第 1 页 / 共 5 页
字号:
#define VOLDESC_OFF	16#define DVD_BLOCK	(32*1024)static unsigned int from_733 (unsigned char *s){ unsigned int ret=0;    ret |= s[0];    ret |= s[1]<<8;    ret |= s[2]<<16;    ret |= s[3]<<24;  return ret;}static void to_733 (unsigned char *s,unsigned int val){   s[0] = (val)     & 0xFF;    s[1] = (val>>8)  & 0xFF;    s[2] = (val>>16) & 0xFF;    s[3] = (val>>24) & 0xFF;    s[4] = (val>>24) & 0xFF;    s[5] = (val>>16) & 0xFF;    s[6] = (val>>8)  & 0xFF;    s[7] = (val)     & 0xFF;}static pwrite64_t pwrite64_method = pwrite64;/* * Page-aligned 2*DVD_BLOCK=64KB large buffer, second 32KB contain * "next" session volume descriptors that were written in the beginning * of current recording... */static char *the_buffer;/* * id_fd is passed to mkisofs, out_fd - to pwrite and ioctl_fd - to ioctl. */static int    in_fd=-1,out_fd=-1;#ifndef INVALID_HANDLE#define INVALID_HANDLE ((void *)-1)#endifstatic void   *ioctl_handle=INVALID_HANDLE;#define ioctl_fd ((long)ioctl_handle)static int	poor_man=-1, zero_image=0, quiet=1,		overburn=0, no_tty_check=0, dry_run=0, dao_size=0,		no_4gb_check=0, layer_break=0;int    dvd_compat=0, test_write=0, no_reload=0, mmc_profile=0, wrvfy=0;double speed_factor=0.0;char  *ioctl_device;int    _argc;char **_argv;#if defined(__linux)#include <linux/cdrom.h>#include <sys/ioctl.h>#include <linux/raw.h>#include <sys/prctl.h>#include <sys/syscall.h>#ifndef _LINUX_WAIT_H#define _LINUX_WAIT_H	/* linux headers are impaired */#endif#include <linux/capability.h>char *find_raw_device(struct stat64 *sb){ int   i,rawctl;  dev_t dev_major,dev_minor;  char  *ret=NULL;  struct raw_config_request req;  static char rawdevname[24] = "";    if (!S_ISBLK(sb->st_mode)) return NULL;    dev_major = major (sb->st_rdev);    dev_minor = minor (sb->st_rdev);    if ((rawctl=open ("/dev/rawctl",O_RDONLY)) < 0) return NULL;    for (i=1;i<256;i++)    {	req.raw_minor = i;	if (ioctl(rawctl,RAW_GETBIND,&req) < 0) break;	if (req.block_major == dev_major && req.block_minor == dev_minor)	{   sprintf (rawdevname,"/dev/raw/raw%d",i);	    ret = rawdevname;	    break;	}    }    close (rawctl);  return ret;}char *setup_fds (char *device){ char *odevice;  uid_t uid=getuid();  struct stat64 sb,sc;  int fd;    /*     * I ignore return values from set{re}uid calls because if     * they fail we have no privileges to care about and should     * just proceed anyway...     */#if 0#define GET_REAL    /*     * Get real, but preserve saved uid. I count that user is     * logged on console and therefore owns the 'device' [this     * is a PAM's resposibility to arrange].     */    setreuid ((uid_t)-1,uid);#else    /*     * More "traditional" set-root-uid behaviour. I assume that if     * administrator has installed growisofs set-root-uid, then     * [s]he consciously wanted to grant access to /dev/scdN to     * everybody, not just console user.     */#endif    if ((in_fd = open64 (device,O_RDONLY)) < 0)	if (!(errno == ENOMEDIUM || errno == EMEDIUMTYPE) ||	    (in_fd = open64 (device,O_RDONLY|O_NONBLOCK)) < 0)	    fprintf (stderr,":-( unable to open64(\"%s\",O_RDONLY): ",device),	    perror (NULL), exit (FATAL_START(errno));#ifdef GET_REAL    setreuid ((uid_t)-1,uid);#endif    if (fstat64(in_fd,&sb) < 0)	fprintf (stderr,":-( unable to stat64(\"%s\"): ",device),	perror (NULL), exit (FATAL_START(errno));    if (!S_ISBLK(sb.st_mode))    {	setuid(uid);		/* drop all privileges	*/	close (in_fd);		/* reopen as mortal	*/	if ((in_fd = open64 (device,O_RDONLY)) < 0)	    fprintf (stderr,":-( unable to re-open64(\"%s\",O_RDONLY): ",			    device),	    perror (NULL), exit (FATAL_START(errno));      open_rw:	if ((out_fd = open64 (device,O_RDWR)) < 0)	    fprintf (stderr,":-( unable to open64(\"%s\",O_RDWR): ",device),	    perror (NULL), exit (FATAL_START(errno));	if (fstat64(out_fd,&sc) < 0)	    fprintf (stderr,":-( unable to stat64(\"%s\"): ",device),	    perror (NULL), exit (FATAL_START(errno));	if (sb.st_dev!=sc.st_dev || sb.st_ino!=sc.st_ino)	    fprintf (stderr,":-( %s: race condition detected!\n",device),	    exit(FATAL_START(EPERM));      opened_rw:	poor_man = 0;	if (ioctl_handle!=INVALID_HANDLE)	    close (ioctl_fd), ioctl_handle = INVALID_HANDLE;	setuid (uid);		/* drop all privileges */	return device;    }    /*     * O_RDWR is expected to provide for none set-root-uid     * execution under Linux kernel 2.6[.8]. If it fails     * [as under 2.6.8], CAP_SYS_RAWIO in combination     * with set-root-uid should fill in for the kernel     * deficiency...     */    if ((fd = open64 (device,O_RDWR|O_NONBLOCK)) >= 0)	ioctl_handle=(void *)(long)fd;    else	ioctl_handle=(void *)(long)dup(in_fd);    /*     * get_mmc_profile terminates the program if ioctl_handle is     * not an MMC unit...     */    mmc_profile = get_mmc_profile (ioctl_handle);    /* Consume media_changed flag */    if (ioctl (ioctl_fd,CDROM_MEDIA_CHANGED,CDSL_CURRENT) < 0)    {	fprintf (stderr,":-( %s: CD_ROM_MEDIA_CHANGED ioctl failed: ",			device),	perror (NULL), exit (FATAL_START(errno));    }    switch (mmc_profile&0xFFFF)    {	case 0x11:	/* DVD-R			*/	case 0x13:	/* DVD-RW Restricted Overwrite	*/	case 0x14:	/* DVD-RW Sequential		*/	case 0x1B:	/* DVD+R			*/	case 0x2B:	/* DVD+R Double Layer		*/	open_poor_man:	    poor_man = 1;	    out_fd = dup(ioctl_fd);#if defined(PR_SET_KEEPCAPS)	    if (prctl(PR_SET_KEEPCAPS,1) == 0) do {#if defined(_LINUX_CAPABILITY_VERSION) && defined(CAP_SYS_RAWIO) && defined(SYS_capset)		struct __user_cap_header_struct	h;		struct __user_cap_data_struct	d;		h.version	= _LINUX_CAPABILITY_VERSION;		h.pid		= 0;		d.effective	= 0;		d.permitted	= 1<<CAP_SYS_RAWIO;		d.inheritable	= 0;		if (syscall(SYS_capset,&h,&d) < 0) break;		/* drop all privileges & effective capabilities */		/* setuid(uid) seems to preserve saved uid		   after dropping CAP_SETUID above... */		setresuid (uid,uid,uid);		d.effective	= 1<<CAP_SYS_RAWIO;		if (syscall(SYS_capset,&h,&d) < 0) break;#endif	    } while (0);#endif	    setuid (uid);	/* drop all privileges	*/	    return ioctl_device=device;	case 0x1A:	/* DVD+RW			*/	case 0x12:	/* DVD-RAM			*/	    if (poor_man>0) goto open_poor_man;	    break;	default:	    fprintf (stderr,":-( %s: media is not recognized as "			    "recordable DVD: %X\n",device,mmc_profile);	    exit (FATAL_START(EMEDIUMTYPE));    }    /*     * Attempt to locate /dev/raw/raw*     */#ifdef GET_REAL#undef GET_REAL    setreuid((uid_t)-1,0);	/* get root for a /dev/raw sake */#endif    if ((odevice=find_raw_device (&sb)))	/* /dev/raw */    {	if ((out_fd=open64 (odevice,O_RDWR)) < 0)	{   if (errno == EROFS)	/* must be unpatched kernel */		goto open_poor_man;	    else		fprintf (stderr,":-( unable to open64(\"%s\",O_RDWR): ",				odevice),		perror (NULL), exit (FATAL_START(errno));	}	device=odevice;	goto opened_rw;    }    if ((mmc_profile&0xFFFF) == 0x12)	goto open_rw;	/* DVD-RAM */    else				goto open_poor_man;}#elif defined(__OpenBSD__) || defined(__NetBSD__)char *setup_fds (char *device){ uid_t uid=getuid();  struct stat sb,sc;    /*     * We might be entering as euid=root!     */    if ((in_fd = open (device,O_RDONLY)) < 0)	fprintf (stderr,":-( unable to open(\"%s\",O_RDONLY): ",device),	perror (NULL), exit (FATAL_START(errno));    if (fstat (in_fd,&sb) < 0)	fprintf (stderr,":-( unable to stat(\"%s\"): ",device),	perror (NULL), exit (FATAL_START(errno));    if (!S_ISCHR(sb.st_mode))    {	if (S_ISBLK(sb.st_mode) && !strncmp (device,"/dev/cd",7))	{   fprintf (stderr,":-) you most likely want to use /dev/r%s instead!\n",			    device+5);	    if (isatty(0) && !dry_run) poll(NULL,0,5000);	}	setuid(uid);	/* drop all privileges	*/	close (in_fd);	/* reopen as mortal	*/	if ((in_fd = open (device,O_RDONLY)) < 0)	    fprintf (stderr,":-( unable to reopen(\"%s\",O_RDONLY): ",device),	    perror (NULL), exit (FATAL_START(errno));      open_rw:	if ((out_fd = open (device,O_RDWR)) < 0)	    fprintf (stderr,":-( unable to open(\"%s\",O_RDWR): ",device),	    perror (NULL), exit (FATAL_START(errno));      opened_rw:	poor_man = 0;	close (ioctl_fd);	ioctl_handle = INVALID_HANDLE;	setuid (uid);	/* drop all privileges	*/	return device;    }    /*     * Still as euid=root! But note that get_mmc_profile makes sure it's     * an MMC device, as it terminates the program if the unit doesn't     * reply to GET CONFIGURATON. In combination with following switch     * this means that if installed set-root-uid, growisofs grants     * access to DVD burner(s), but not to any other device.     */    ioctl_handle = (void *)(long)open (device,O_RDWR); /* O_RDWR is a must for SCIOCCOMMAND */    if (ioctl_handle == INVALID_HANDLE)    {	fprintf (stderr,":-( unable to open(\"%s\",O_RDWR): ",device),	perror (NULL);	if (errno == EBUSY)	    fprintf (stderr,"    is its block counterpart mounted?\n");	exit (FATAL_START(errno));    }    if (fstat(ioctl_fd,&sc) < 0)	fprintf (stderr,":-( unable to stat(\"%s\"): ",device),	perror (NULL), exit (FATAL_START(errno));    if (sb.st_dev!=sc.st_dev || sb.st_ino!=sc.st_ino)	fprintf (stderr,":-( %s: race condition detected!\n",device),	exit(FATAL_START(EPERM));    mmc_profile = get_mmc_profile (ioctl_handle);    switch (mmc_profile&0xFFFF)    {	case 0x11:	/* DVD-R			*/	case 0x13:	/* DVD-RW Restricted Overwrite	*/	case 0x14:	/* DVD-RW Sequential		*/	case 0x1A:	/* DVD+RW			*/	case 0x1B:	/* DVD+R			*/	case 0x2B:	/* DVD+R Double Layer		*/	open_poor_man:	    poor_man = 1;	    out_fd = dup(ioctl_fd);	    setuid (uid);	/* drop all privileges	*/	    return ioctl_device=device;	case 0x12:	/* DVD-RAM			*/	    if (poor_man>0) goto open_poor_man;	    out_fd = dup(ioctl_fd);	    goto opened_rw;	default:	    fprintf (stderr,":-( %s: media is not recognized as "			    "recordable DVD: %X\n",device,mmc_profile);	    exit (FATAL_START(EMEDIUMTYPE));    }    /* not actually reached */    setuid(uid);    goto open_rw;}#elif defined(__FreeBSD__)#include <sys/cdio.h>#include <camlib.h>#include <cam/scsi/scsi_pass.h>#undef	ioctl_fd#define	ioctl_fd (((struct cam_device *)ioctl_handle)->fd)#define PASS_STDIN_TO_MKISOFSchar *setup_fds (char *device){ uid_t		uid=getuid();  struct stat	sb,sc;  union ccb	ccb;  char		pass[32]; /* periph_name is 16 chars long */  struct cam_device *cam;  int		once=1;    /*     * We might be entering as euid=root!     */    if ((in_fd = open (device,O_RDONLY)) < 0)	fprintf (stderr,":-( unable to open(\"%s\",O_RDONLY): ",device),	perror (NULL), exit (FATAL_START(errno));    if (fstat (in_fd,&sb) < 0)	fprintf (stderr,":-( unable to stat(\"%s\"): ",device),	perror (NULL), exit (FATAL_START(errno));    if (!S_ISCHR(sb.st_mode))    {	setuid(uid);	/* drop all privileges	*/	close (in_fd);	/* reopen as mortal	*/	if ((in_fd = open (device,O_RDONLY)) < 0)	    fprintf (stderr,":-( unable to reopen(\"%s\",O_RDONLY): ",device),	    perror (NULL), exit (FATAL_START(errno));      open_rw:	if ((out_fd = open (device,O_RDWR)) < 0)	    fprintf (stderr,":-( unable to open(\"%s\",O_RDWR): ",device),	    perror (NULL), exit (FATAL_START(errno));	if (fstat(out_fd,&sc) < 0)	    fprintf (stderr,":-( unable to stat(\"%s\"): ",device),	    perror (NULL), exit (FATAL_START(errno));	if (sb.st_dev!=sc.st_dev || sb.st_ino!=sc.st_ino)	    fprintf (stderr,":-( %s: race condition detected!\n",device),	    exit(FATAL_START(EPERM));      opened_rw:	poor_man = 0;	if (ioctl_handle && ioctl_handle != INVALID_HANDLE)	    cam_close_device (ioctl_handle);	ioctl_handle = INVALID_HANDLE;	setuid (uid);	/* drop all privileges	*/	return device;    }    /*     * Still as euid=root! But note that get_mmc_profile makes sure it's     * an MMC device, as it terminates the program if the unit doesn't     * reply to GET CONFIGURATON. In combination with following switch

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -