X-Git-Url: https://git.distorted.org.uk/~mdw/dvdrip/blobdiff_plain/9b86c33fd71be1d0310c6e32e12b8fb16c55f690..4144e376c9ecfba9fa3703312a2cf3c8f8620831:/lib.c diff --git a/lib.c b/lib.c index 80b1507..4f2950c 100644 --- a/lib.c +++ b/lib.c @@ -33,6 +33,40 @@ void bail_syserr(int err, const char *fmt, ...) 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; @@ -85,6 +119,25 @@ void carefully_fclose(FILE *fp, const char *what) 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)) {