+ char *c;
+
+ /* TODO: Handle other path separators. */
+ c = strrchr(name, '/');
+ if (!c)
+ return (char *)name;
+ return c+1;
+}
+
+struct lbx *lbx_fopen(const char *file)
+{
+ const char *name = last_component(file);
+ struct lbx_pipe_state *p;
+ FILE *f;
+
+ f = fopen(file, "rb");
+ if (!f) {
+ lbx_error_raise(-errno);
+ return NULL;
+ }
+
+ if (fseek(f, 0, SEEK_CUR) == 0)
+ return lbx_open(f, &lbx_default_fops, file_close, name);
+
+ p = malloc(sizeof *p);
+ if (!p) {
+ lbx_error_raise(LBX_ENOMEM);
+ fclose(f);
+ return NULL;
+ }
+
+ *p = (struct lbx_pipe_state) { .f = f };
+ return lbx_open(p, &lbx_pipe_fops, pipe_close, name);
+}
+
+int lbx_file_stat(struct lbx *pub, unsigned fileno, struct lbx_statbuf *buf)
+{
+ struct lbx_priv *lbx = (struct lbx_priv *)pub;