📄 growisofs.c
字号:
{ if ((waitpid (mkisofs_pid,&ret,0)) == -1) perror (":-( waitpid failed"), exit (errno); if (!WIFEXITED(ret) || WEXITSTATUS(ret)!=0) fprintf (stderr,":-( mkisofs has failed: %d\n",WEXITSTATUS(ret)), exit (1); } else if (n<0) { int err = errno; errno = err&0x7F; /* they might be passing FATAL_START */ perror (":-( write failed"), exit (err); }}/* * This may not be larger than 32KB! */#define MAX_IVDs 16#define IVDs_SIZE (sizeof(struct iso_primary_descriptor)*MAX_IVDs)int main (int argc, char *argv[]){ int imgfd=-1; char *in_device=NULL,*out_device=NULL,*in_image=NULL,*env; char dev_found; int i,n,warn_for_isofs=0; char **mkisofs_argv,C_parm[24],M_parm_[16],*M_parm=M_parm_; int mkisofs_argc,growisofs_argc; int next_session=-1,alleged_next_session=-1; unsigned int new_size; struct iso_primary_descriptor *descr;#if !defined(I_KNOW_ALL_ABOUT_SUDO) if (getenv ("SUDO_COMMAND")) { fprintf (stderr,":-( %s is being executed under sudo, " "aborting!\n",argv[0]); fprintf (stderr," See NOTES paragraph in growisofs " "manual page for further details.\n"); exit(FATAL_START(EACCES)); }#endif /* * This is a set-root-uid "entry point" for listed operations. User * can't trick this code to unmount arbitrary file system, as [s]he * has to pass opened file descriptor to the mounted device. As for * file descriptor passed by this program itself, I rely upon the * fact that it was appropriately audited at open time in platform- * specific setup_fds above... */ if (*argv[0] == '-') { int fd; struct stat fdst; chdir ("/"); if (argc != 3) exit (EINVAL); fd=atoi (argv[1]); if (!strcmp(argv[0],"-umount")) { if (fumount (fd)) exit (errno); exit (0); } else if (!strcmp(argv[0],"-reload")) { if (fstat (fd,&fdst) < 0) perror (":-( unable to fstat"), exit (1); close (fd); if (media_reload (argv[2],&fdst)) perror (":-( unable to reload tray"), exit (1); exit (0); } exit(1); } /* mmap buffer so that we can use it with /dev/raw/rawN */#if defined(MAP_ANONYMOUS) && !(defined(__sun) || defined(sun)) the_buffer = mmap (NULL,2*DVD_BLOCK,PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS,-1,(off_t)0);#else { int fd; if ((fd=open ("/dev/zero",O_RDWR)) < 0) perror (":-( unable to open \"/dev/zero\"?"), exit(FATAL_START(errno)); the_buffer = mmap (NULL,2*DVD_BLOCK,PROT_READ|PROT_WRITE, MAP_PRIVATE,fd,0); close (fd); }#endif if (the_buffer == MAP_FAILED) fprintf (stderr,":-( unable to anonymously mmap %d: ",2*DVD_BLOCK), perror (NULL), exit (FATAL_START(errno)); mkisofs_argv = malloc ((argc+3)*sizeof(char *)); if (mkisofs_argv == NULL) fprintf (stderr,":-( unable to allocate %lu bytes: ", (argc+3)*sizeof(char *)), perror (NULL), exit (FATAL_START(errno)); env = getenv ("MKISOFS"); mkisofs_argv[0] = (env?env:"mkisofs"), mkisofs_argc = 1; growisofs_argc=0; _argc=argc, _argv=argv; for (i=1;i<argc;i++) { int len=strlen(argv[i]); char *opt; dev_found = '\0'; if (argv[i][0] == '-') { opt = argv[i] + ((argv[i][1]=='-')?(len--,1):0); if (argv[i][1] == 'M') { if (len > 2) in_device = argv[i]+2; else in_device = argv[++i]; dev_found = 'M'; } else if (!strncmp(opt,"-prev-session",13)) { if (len > 13) in_device = opt+13; else in_device = argv[++i]; dev_found = 'M'; } else if (argv[i][1] == 'Z') { if (len > 2) in_device = argv[i]+2; else in_device = argv[++i]; dev_found = 'Z'; } else if (!strncmp(opt,"-zero-session",13)) { if (len > 13) in_device = opt+13; else in_device = argv[++i]; dev_found = 'Z'; } else if (!strcmp(opt,"-poor-man")) { if (poor_man<0) poor_man = 1; continue; } else if (!strncmp(opt,"-speed",6)) { char *s; if (len>6) (s=strchr(opt,'='))?s++:s; else s=argv[++i]; if (s) speed_factor=atof(s); if (speed_factor<=0) fprintf (stderr,"-speed=%.1f: insane speed factor.\n", speed_factor), exit(FATAL_START(EINVAL)); continue; } else if (!strcmp(opt,"-dvd-compat")) { if (poor_man<0) poor_man = 1; dvd_compat++; continue; } else if (!strcmp(opt,"-overburn")) { overburn = 1; continue; } else if (argv[i][1] == 'o') { if (!strchr(argv[i]+2,'-')) /* somewhat opportunistic... */ fprintf (stderr,"%s: -o[output] option " "is not permitted.\n",argv[0]), exit(FATAL_START(EINVAL)); } else if (!strncmp(opt,"-use-the-force-luke",19)) { char *s=strchr (opt,'='),*o; if (s == NULL) /* backward compatibility */ no_tty_check = 1; else { s++; if (strstr(s,"tty")) no_tty_check = 1; if (strstr(s,"dummy")) test_write = 1; if (strstr(s,"notray")) no_reload = 1; if (strstr(s,"noload")) no_reload = -1; if (strstr(s,"wrvfy")) wrvfy = 1; if (strstr(s,"4gms")) no_4gb_check = 1; if (strstr(s,"moi")) { quiet=-1; mkisofs_argv[mkisofs_argc++] = "-quiet"; } if ((o=strstr(s,"dao"))) { dvd_compat += 256; /* vvvvvvvvvvv tracksize option takes precedence! */ if (dao_size==0 && (o[3]==':' || o[3]=='=')) { dao_size=strtol(o+4,0,0); if (dao_size<=0) fprintf (stderr,":-( insane dao%c%d option\n", o[3],dao_size), exit(FATAL_START(EINVAL)); } } if ((o=strstr(s,"tracksize"))) { if (o[9]==':' || o[9]=='=') { dao_size=strtol(o+10,0,0); if (dao_size<=0) fprintf (stderr,":-( insane tracksize%c%d option\n", o[9],dao_size), exit(FATAL_START(EINVAL)); } } if ((o=strstr(s,"break"))) { if (o[5]==':' || o[5]=='=') { layer_break=strtol(o+6,0,0); if (layer_break<=0 || layer_break%16) fprintf (stderr,":-( insane break%c%d option\n", o[5],layer_break), exit(FATAL_START(EINVAL)); } } if ((o=strstr(s,"seek")) && next_session<0) { if (o[4]==':' || o[4]=='=') { next_session=strtol(o+5,0,0); if (next_session<0 || next_session%16) fprintf (stderr,":-( insane seek%c%d option\n", o[4],next_session), exit(FATAL_START(EINVAL)); } } } continue; } else if (!strcmp(opt,"-dvd-video")) { if (poor_man<0) poor_man = 1; dvd_compat++, growisofs_argc++; } else if (!strcmp(opt,"-quiet")) quiet++, growisofs_argc++; else if (argv[i][1] == 'C' || !strncmp(opt,"-cdrecord-params",16)) { char *s=argv[i+1]; int i1,i2; if (argv[i][1]=='C' && len>2) s=argv[i]+2; else i++; if (sscanf (s,"%d,%d",&i1,&i2) == 2) alleged_next_session=i2; continue; } else if (argv[i][1] == '#' || !strcmp(opt,"-dry-run")) { dry_run = 1; continue; } else if (argv[i][1] == '?' || !strcmp(opt,"-help")) { PRINT_VERSION (argv[0]); printf ("- usage: %s [-dvd-compat] [-overburn] [-speed=1] \\\n" " -[ZM] /dev/dvd <mkisofs options>\n",argv[0]); printf (" for <mkisofs options> see 'mkisofs %s'\n",opt); exit (FATAL_START(EINVAL)); } else if (strstr (opt,"-version")) { PRINT_VERSION (argv[0]); printf (" front-ending to %s: ",mkisofs_argv[0]); fflush (stdout); setuid(getuid()); execlp (mkisofs_argv[0],mkisofs_argv[0],"-version",NULL); fprintf (stderr,"\n- %s: unable to execute %s: ", argv[0],mkisofs_argv[0]), perror (NULL), exit (FATAL_START(errno)); } } if (dev_found && in_device) { if (*in_device == '=') in_device++; if (1 || dev_found == 'Z') { if ((in_image = strchr(in_device,'='))) { uid_t euid=geteuid(); seteuid (getuid()); /* get real for parsing -[ZM] a=b */ while (in_image) { *in_image='\0'; errno=0; if (access (in_device,F_OK)==0 || errno!=ENOENT) break; *in_image='=', in_image=strchr(in_image+1,'='); } if (errno) fprintf (stderr,":-( \"%s\": unexpected errno:", in_device), perror (NULL), exit (FATAL_START(errno)); if (in_image) { in_image++; if (sscanf(in_image,"/dev/fd/%u",&imgfd) == 1) imgfd = dup (imgfd); /* validate descriptor */ else imgfd = open64(in_image,O_RDONLY); if (imgfd < 0) fprintf (stderr,":-( unable to open64(\"%s\"," "O_RDONLY): ",in_image), perror (NULL), exit(FATAL_START(errno)); if (!strcmp(in_image,"/dev/zero")) zero_image=1; } seteuid (euid); /* revert to saved [set-]uid */ } } /* * Sets up in_fd, out_fd, ioctl_handle and poor_man variable. * This procedure is platform-specific. If the program * has to be installed set-root-uid, then this procedure * is the one to drop privileges [if appropriate]. */ out_device=setup_fds (in_device); *(long *)the_buffer=0; /* redundant:-) */ if (mmc_profile&0x10000) /* blank media */ n=0, errno=EIO; else { n=pread64 (in_fd,the_buffer,2048,VOLDESC_OFF*CD_BLOCK); if (n==0) errno=EIO; /* end-of-file reached? */ } if (n!=2048 && dev_found=='M') perror (":-( unable to pread64(2) primary volume descriptor"), fprintf (stderr," you most likely want to use -Z option.\n"), exit (FATAL_START(errno)); if (dev_found == 'M') { if (memcmp (the_buffer,"\1CD001",6)) fprintf (stderr,":-( %s doesn't look like isofs...\n", in_device), exit(FATAL_START(EMEDIUMTYPE)); next_session=setup_C_parm(C_parm, (struct iso_primary_descriptor *)the_buffer); if (imgfd>=0) { if (zero_image) { off64_t off=(atoi(C_parm)-16)*CD_BLOCK; dup2(in_fd,imgfd); /* kludge! */ if (lseek64 (imgfd,off,SEEK_SET) == (off64_t)-1) fprintf (stderr,":-( %s: unable to lseek(%lld): ", in_device,off), perror (NULL), exit(FATAL_START(errno)); } else if (alleged_next_session!=next_session) fprintf (stderr,"%s: -C argument is %s.\n", argv[0],alleged_next_session>=0? "insane":"undefined"), exit(FATAL_START(EINVAL)); } else if (next_session > (0x200000-0x5000)) /* 4GB/2K-40MB/2K */ if ((mmc_profile&0xFFFF)!=0x2B || !no_4gb_check) fprintf (stderr,":-( next session would cross 4GB " "boundary, aborting...\n"), exit (FATAL_START(ENOSPC)); mkisofs_argv[mkisofs_argc++] = "-C"; mkisofs_argv[mkisofs_argc++] = C_parm;#ifdef CANNOT_PASS_DEV_FD_N_TO_MKISOFS# ifdef PASS_STDIN_TO_MKISOFS M_parm = "-";# else M_parm = get_M_parm (in_fd,in_device);# endif#else# ifdef PASS_STDIN_TO_MKISOFS M_parm = "/dev/fd/0";# else sprintf (M_parm,"/dev/fd/%d",in_fd);# endif#endif mkisofs_argv[mkisofs_argc++] = "-M"; mkisofs_argv[mkisofs_argc++] = M_parm; len = 3 + strlen(C_parm) + 3 + strlen(M_parm); growisofs_argc += 4; } else { if (!memcmp (the_buffer,"\1CD001",6)) warn_for_isofs = 1; if (next_session<0) next_session = 0; continue; } } else { mkisofs_argv[mkisofs_argc++] = argv[i]; } } if (in_device == NULL) fprintf (stderr,"%s: previous \"session\" device is not specified, " "do use -M or -Z option\n",argv[0]), exit (FATAL_START(EINVAL)); if (imgfd<0) { if (mkisofs_argc==1) fprintf (stderr,"%s: no mkisofs options specified, " "aborting...\n",argv[0]), exit (FATAL_START(EINVAL)); } else if ((mkisofs_argc-growisofs_argc)>1) fprintf (stderr,"%s: no mkisofs options are permitted with =, " "aborting...\n",argv[0]), exit (FATAL_START(EINVAL)); mkisofs_argv[mkisofs_argc] = NULL; assert (next_s
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -