/** * mnt_unref_cache: * @cache: cache pointer * * De-increments reference counter, on zero the cache is automatically * deallocated by mnt_free_cache(). */ void mnt_unref_cache(struct libmnt_cache *cache) { if (cache) { cache->refcount--; /*DBG(CACHE, ul_debugobj(cache, "unref=%d", cache->refcount));*/ if (cache->refcount <= 0) { mnt_unref_table(cache->mtab); mnt_free_cache(cache); } } }
int test_read_tags(struct libmnt_test *ts, int argc, char *argv[]) { char line[BUFSIZ]; struct libmnt_cache *cache; int i; cache = mnt_new_cache(); if (!cache) return -ENOMEM; while(fgets(line, sizeof(line), stdin)) { size_t sz = strlen(line); if (line[sz - 1] == '\n') line[sz - 1] = '\0'; if (!strcmp(line, "quit")) break; if (*line == '/') { if (mnt_cache_read_tags(cache, line) < 0) fprintf(stderr, "%s: read tags failed\n", line); } else if (strchr(line, '=')) { char *tag, *val; const char *cn = NULL; if (!blkid_parse_tag_string(line, &tag, &val)) { cn = cache_find_tag(cache, tag, val); free(tag); free(val); } if (cn) printf("%s: %s\n", line, cn); else printf("%s: not cached\n", line); } } for (i = 0; i < cache->nents; i++) { struct mnt_cache_entry *e = &cache->ents[i]; if (!(e->flag & MNT_CACHE_ISTAG)) continue; printf("%15s : %5s : %s\n", e->value, e->key, e->key + strlen(e->key) + 1); } mnt_free_cache(cache); return 0; }
static int dir_to_device(const char *spec, dev_t *dev) { struct libmnt_table *tb = mnt_new_table_from_file("/proc/self/mountinfo"); struct libmnt_fs *fs; struct libmnt_cache *cache; int rc = -1; if (!tb) { /* * Fallback. Traditional way to detect mountpoints. This way * is independent on /proc, but not able to detect bind mounts. */ struct stat pst, st; char buf[PATH_MAX], *cn; int len; if (stat(spec, &st) != 0) return -1; cn = mnt_resolve_path(spec, NULL); /* canonicalize */ len = snprintf(buf, sizeof(buf), "%s/..", cn ? cn : spec); free(cn); if (len < 0 || (size_t) len + 1 > sizeof(buf)) return -1; if (stat(buf, &pst) !=0) return -1; if ((st.st_dev != pst.st_dev) || (st.st_dev == pst.st_dev && st.st_ino == pst.st_ino)) { *dev = st.st_dev; return 0; } return -1; } /* to canonicalize all necessary paths */ cache = mnt_new_cache(); mnt_table_set_cache(tb, cache); fs = mnt_table_find_target(tb, spec, MNT_ITER_BACKWARD); if (fs && mnt_fs_get_target(fs)) { *dev = mnt_fs_get_devno(fs); rc = 0; } mnt_free_table(tb); mnt_free_cache(cache); return rc; }
int test_resolve_spec(struct libmnt_test *ts, int argc, char *argv[]) { char line[BUFSIZ]; struct libmnt_cache *cache; cache = mnt_new_cache(); if (!cache) return -ENOMEM; while(fgets(line, sizeof(line), stdin)) { size_t sz = strlen(line); char *p; if (line[sz - 1] == '\n') line[sz - 1] = '\0'; p = mnt_resolve_spec(line, cache); printf("%s : %s\n", line, p); } mnt_free_cache(cache); return 0; }
/* main program */ int main(int argc, char **argv) { char *device = NULL; char *disk = NULL; char *mountpoint = NULL; int worked = 0; /* set to 1 when successfully ejected */ int fd; /* file descriptor for device */ setlocale(LC_ALL,""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); atexit(close_stdout); /* parse the command line arguments */ parse_args(argc, argv, &device); /* handle -d option */ if (d_option) { info(_("default device: `%s'"), EJECT_DEFAULT_DEVICE); return EXIT_SUCCESS; } if (!device) { device = mnt_resolve_path(EJECT_DEFAULT_DEVICE, NULL); verbose(_("using default device `%s'"), device); } else { char *p; if (device[strlen(device)-1] == '/') device[strlen(device)-1] = '\0'; /* figure out full device or mount point name */ p = find_device(device); if (p) free(device); else p = device; device = mnt_resolve_spec(p, NULL); free(p); } if (!device) errx(EXIT_FAILURE, _("%s: unable to find device"), device); verbose(_("device name is `%s'"), device); device_get_mountpoint(&device, &mountpoint); if (mountpoint) verbose(_("%s: mounted at %s"), device, mountpoint); else verbose(_("%s: not mounted"), device); disk = get_disk_devname(device); if (disk) { verbose(_("%s: disc device: %s (disk device will be used for eject)"), device, disk); free(device); device = disk; disk = NULL; } else verbose(_("%s: is whole-disk device"), device); if (F_option == 0 && is_hotpluggable(device) == 0) errx(EXIT_FAILURE, _("%s: is not hot-pluggable device"), device); /* handle -n option */ if (n_option) { info(_("device is `%s'"), device); verbose(_("exiting due to -n/--noop option")); return EXIT_SUCCESS; } /* handle -i option */ if (i_option) { fd = open_device(device); manual_eject(fd, i_arg); return EXIT_SUCCESS; } /* handle -a option */ if (a_option) { if (a_arg) verbose(_("%s: enabling auto-eject mode"), device); else verbose(_("%s: disabling auto-eject mode"), device); fd = open_device(device); auto_eject(fd, a_arg); return EXIT_SUCCESS; } /* handle -t option */ if (t_option) { verbose(_("%s: closing tray"), device); fd = open_device(device); close_tray(fd); set_device_speed(device); return EXIT_SUCCESS; } /* handle -T option */ if (T_option) { verbose(_("%s: toggling tray"), device); fd = open_device(device); toggle_tray(fd); set_device_speed(device); return EXIT_SUCCESS; } /* handle -X option */ if (X_option) { verbose(_("%s: listing CD-ROM speed"), device); fd = open_device(device); list_speeds(device, fd); return EXIT_SUCCESS; } /* handle -x option only */ if (!c_option) set_device_speed(device); /* if it is a multipartition device, unmount any other partitions on the device */ if (m_option != 1) { if (mountpoint) umount_one(mountpoint); /* usually whole-disk */ umount_partitions(device); } /* handle -c option */ if (c_option) { verbose(_("%s: selecting CD-ROM disc #%ld"), device, c_arg); fd = open_device(device); changer_select(fd, c_arg); set_device_speed(device); return EXIT_SUCCESS; } /* if user did not specify type of eject, try all four methods */ if (r_option + s_option + f_option + q_option == 0) r_option = s_option = f_option = q_option = 1; /* open device */ fd = open_device(device); /* try various methods of ejecting until it works */ if (r_option) { verbose(_("%s: trying to eject using CD-ROM eject command"), device); worked = eject_cdrom(fd); verbose(worked ? _("CD-ROM eject command succeeded") : _("CD-ROM eject command failed")); } if (s_option && !worked) { verbose(_("%s: trying to eject using SCSI commands"), device); worked = eject_scsi(fd); verbose(worked ? _("SCSI eject succeeded") : _("SCSI eject failed")); } if (f_option && !worked) { verbose(_("%s: trying to eject using floppy eject command"), device); worked = eject_floppy(fd); verbose(worked ? _("floppy eject command succeeded") : _("floppy eject command failed")); } if (q_option && !worked) { verbose(_("%s: trying to eject using tape offline command"), device); worked = eject_tape(fd); verbose(worked ? _("tape offline command succeeded") : _("tape offline command failed")); } if (!worked) errx(EXIT_FAILURE, _("unable to eject")); /* cleanup */ close(fd); free(device); free(mountpoint); mnt_free_table(mtab); mnt_free_cache(cache); return EXIT_SUCCESS; }