exit(2);
}
+double parse_float(const char **p_inout, unsigned f,
+ double min, double max, const char *what)
+{
+ const char *p;
+ char *q;
+ double x;
+ int err;
+
+ err = errno; errno = 0;
+ p = *p_inout;
+ x = strtod(p, &q);
+ if (errno || x < min || x > max || (!(f&PNF_JUNK) && *q))
+ bail("bad %s `%s'", what, p);
+ *p_inout = q; errno = err;
+ return (x);
+}
+
+long parse_int(const char **p_inout, unsigned f,
+ long min, long max, const char *what)
+{
+ const char *p;
+ char *q;
+ long x;
+ int err;
+
+ err = errno; errno = 0;
+ p = *p_inout;
+ x = strtoul(p, &q, 0);
+ if (errno || x < min || x > max || (!(f&PNF_JUNK) && *q))
+ bail("bad %s `%s'", what, p);
+ *p_inout = q; errno = err;
+ return (x);
+}
+
void sit(double t)
{
struct timeval tv;
bail_syserr(errno, "error writing %s file", what);
}
+off_t device_size(int fd, const char *file, int *blksz_out)
+{
+ struct stat st;
+ uint64_t volsz;
+
+ if (fstat(fd, &st))
+ bail_syserr(errno, "failed to obtain status for `%s'", file);
+ if (S_ISREG(st.st_mode))
+ volsz = st.st_size;
+ else if (S_ISBLK(st.st_mode)) {
+ if (ioctl(fd, BLKGETSIZE64, &volsz))
+ bail_syserr(errno, "failed to get volume size for `%s'", file);
+ if (ioctl(fd, BLKSSZGET, blksz_out))
+ bail_syserr(errno, "failed to get block size for `%s'", file);
+ } else
+ bail("can't read size for `%s': expected file or block device", file);
+ return ((off_t)volsz);
+}
+
void store_filename(char *buf, ident id)
{
switch (id_kind(id)) {
static const dvd_logger_cb logger = { logfn };
#endif
-void open_dvd(const char *device, int *fd_out, dvd_reader_t **dvd_out)
+void open_dvd(const char *device, int mode,
+ int *fd_out, dvd_reader_t **dvd_out)
{
int fd;
dvd_reader_t *dvd;
int bannerp = 0;
for (;;) {
- fd = open(device, O_RDONLY);
+ fd = open(device, mode);
if (fd >= 0 || errno != ENOMEDIUM) break;
if (!bannerp) {
show_banner("Waiting for disc to be inserted...");