3 const char *prog
= "<unset>";
5 void set_prog(const char *p
)
6 { const char *q
= strrchr(p
, '/'); prog
= q ? q
+ 1 : p
; }
8 void vmoan(const char *fmt
, va_list ap
)
9 { fprintf(stderr
, "%s: ", prog
); vfprintf(stderr
, fmt
, ap
); }
11 __attribute__((format(printf
, 1, 2)))
12 void moan(const char *fmt
, ...)
16 va_start(ap
, fmt
); vmoan(fmt
, ap
); va_end(ap
);
20 __attribute__((noreturn
, format(printf
, 1, 2)))
21 void bail(const char *fmt
, ...)
25 va_start(ap
, fmt
); vmoan(fmt
, ap
); va_end(ap
);
30 __attribute__((noreturn
, format(printf
, 2, 3)))
31 void bail_syserr(int err
, const char *fmt
, ...)
35 va_start(ap
, fmt
); vmoan(fmt
, ap
); va_end(ap
);
36 if (err
) fprintf(stderr
, ": %s", strerror(errno
));
44 double whole
= floor(t
);
47 tv
.tv_sec
= whole
; tv
.tv_usec
= floor((t
- whole
)*1.0e6
) + 1;
48 if (select(0, 0, 0, 0, &tv
) < 0) bail_syserr(errno
, "failed to sleep");
52 void carefully_write(int fd
, const void *buf
, size_t sz
)
54 const unsigned char *p
= buf
;
61 if (errno
== EINTR
) continue;
62 bail_syserr(errno
, "failed to write to output file");
64 if (!n
) bail("unexpected short write to output file");
69 void open_file_on_demand(const char *file
, FILE **fp_inout
, const char *what
)
74 fp
= fopen(file
, "w");
75 if (!fp
) bail_syserr(errno
, "failed to open %s file `%s'", what
, file
);
76 fprintf(fp
, "## %s\n\n", what
);
81 void check_write(FILE *fp
, const char *what
)
84 if (ferror(fp
)) bail_syserr(errno
, "error writing %s file", what
);
87 void carefully_fclose(FILE *fp
, const char *what
)
89 if (fp
&& (ferror(fp
) || fclose(fp
)))
90 bail_syserr(errno
, "error writing %s file", what
);
93 void store_filename(char *buf
, ident id
)
95 switch (id_kind(id
)) {
97 sprintf(buf
, "#<raw device>");
100 if (!id_title(id
)) sprintf(buf
, "/VIDEO_TS/VIDEO_TS.IFO");
101 else sprintf(buf
, "/VIDEO_TS/VTS_%02u_0.IFO", id_title(id
));
104 if (!id_title(id
)) sprintf(buf
, "/VIDEO_TS/VIDEO_TS.BUP");
105 else sprintf(buf
, "/VIDEO_TS/VTS_%02u_0.BUP", id_title(id
));
108 if (!id_title(id
)) sprintf(buf
, "/VIDEO_TS/VIDEO_TS.VOB");
110 sprintf(buf
, "/VIDEO_TS/VTS_%02u_%u.VOB", id_title(id
), id_part(id
));
117 struct progress_state progress
= PROGRESS_STATE_INIT
;
118 static struct banner_progress_item banner_progress
;
120 static void render_banner_progress(struct progress_item
*item
,
121 struct progress_render_state
*render
)
123 struct banner_progress_item
*bi
= (struct banner_progress_item
*)item
;
125 progress_putleft(render
, " %s", bi
->msg
);
126 progress_shownotice(render
, 4, 7);
129 void show_banner(const char *msg
)
131 banner_progress
._base
.render
= render_banner_progress
;
132 progress_additem(&progress
, &banner_progress
._base
);
133 banner_progress
.msg
= msg
;
134 progress_update(&progress
);
137 void hide_banner(void)
139 if (!progress_removeitem(&progress
, &banner_progress
._base
))
140 progress_update(&progress
);
144 static void logfn(void *p
, dvd_logger_level_t lev
,
145 const char *fmt
, va_list ap
)
148 case DVD_LOGGER_LEVEL_ERROR
:
149 fprintf("%s (libdvdread error): ", prog
);
151 case DVD_LOGGER_LEVEL_WARN
:
152 fprintf("%s (libdvdread warning): ", prog
);
157 vfprintf(stderr
, fmt
, ap
);
160 static const dvd_logger_cb logger
= { logfn
};
163 void open_dvd(const char *device
, int *fd_out
, dvd_reader_t
**dvd_out
)
170 fd
= open(device
, O_RDONLY
);
171 if (fd
>= 0 || errno
!= ENOMEDIUM
) break;
173 show_banner("Waiting for disc to be inserted...");
178 if (bannerp
) hide_banner();
179 if (fd
< 0) bail_syserr(errno
, "failed to open device `%s'", device
);
182 dvd
= DVDOpen2(0, &logger
, device
);
184 dvd
= DVDOpen(device
);
186 if (!dvd
) bail("failed to open DVD on `%s'", device
);
189 if (fd_out
) *fd_out
= fd
;