Skip to content

Instantly share code, notes, and snippets.

@danielfdickinson
Last active February 18, 2025 02:43
ucode version of mountpoint command

mountpoint-ucode

Due to openwrt/openwrt#13873 the author needed a version of the mountpoint command for OpenWrt. Since they wanted to learn ucode, they coded the needed command in ucode. This may be moot as enabling the busybox mountpoint applet may be more space-efficient, but the author enjoyed the exercise.

On an modern OpenWrt system:
mountpoint should be placed in /usr/bin and chowned 0744 (executable)
mountpoint.uc should be placed in /usr/share/ucode.

This code can also be viewed on the mountpoint-ucode blog post on Wild Tech 'Garden'.

License: GPL-2.0-or-later

#!/usr/bin/env ucode
import { print_is_mountpoint } from "mountpoint";
let args = ARGV;
const arg1 = shift(args);
let do_message = false;
let show_errors = false;
if (arg1 == "-v") {
do_message = true;
} else if (arg1 == "-vv") {
do_message = true;
show_errors = true;
} else {
unshift(args, arg1);
}
exit(print_is_mountpoint(join(" ", args), do_message, show_errors));
// https://github.com/util-linux/util-linux/blob/master/sys-utils/mountpoint.c
import { access, dirname, open, realpath, stat } from 'fs';
function _is_dm_devname(canonical) {
let dmpath = null;
const spos = rindex(canonical, "/");
if (spos != null) {
dmpath = substr(canonical, spos + 1);
} else {
return {
error: true,
dmpath: null,
error_message: "Not a device path"
};
}
const can_stat = stat(canonical);
if (can_stat == null) {
return {
error: true,
dmpath: null,
error_message: sprintf("Unable to access path %s", canonical)
};
}
if (
(length(dmpath) < 5) ||
(substr(dmpath, 0, 4) != "/dm-") ||
(int(substr(dmpath, 4)) == NaN) ||
(can_stat.type != "block")
) {
return {
error: false,
dmpath: null,
error_message: null
};
}
return {
error: false,
dmpath: dmpath,
error_message: null
};
}
function _canonicalize_dm_name(path) {
if (path == null) {
return {
error: true,
dmpath: null,
error_message: "No input path"
};
}
const fpath = sprintf("/sys/block/%s/dm/name", path);
const f = open(fpath, "r");
if (f == null) {
return {
error: true,
dmpath: null,
error_message: sprintf("Unable to open '%s'", fpath)
};
}
const dmname = f.read("\n");
f.close();
if (dmname == null) {
return {
error: true,
dmpath: null,
error_message: sprintf("Failed to read '%s'", fpath)
};
}
const dmpath = sprintf("/dev/mapper/%s", dmname);
if (!access(dmpath)) {
return {
error: true,
dmpath: null,
error_message: sprintf("Unable to access '%s'", dmpath)
};
}
return {
error: false,
dmpath: dmpath,
error_message: null
};
}
function _canonicalize_device_path(path) {
if (!path) {
return {
error: true,
canonical: null,
error_message: "No input path"
};
}
let canonical = realpath(path);
if (!canonical) {
return {
error: true,
canonical: null,
error_message: sprintf("'%s' has no canonical path", path)
};
}
const dmname_result = _is_dm_devname(canonical);
if (!dmname_result.error) {
if (dmname_result.dmname != null) {
const dmcanonical_result = _canonicalize_dm_name(dmname_result.dmname);
if (dmcanonical_result.dmname != null) {
canonical = dmcanonical_result.dmname;
} else if (dmcanonical_result.error) {
return {
error: true,
canonical: null,
error_message: sprintf("'%s' could not be canonicalized: %s", path, dmcanonical_result.error_message)
};
}
}
} else if (dmname_result.error_message != "Not a device path") {
return {
error: true,
canonical: null,
error_message: sprintf("'%s' could not be read: %s", canonical, dmname_result.error_message)
};
}
return {
error: false,
canonical: canonical,
error_message: null
};
}
function _dir_to_device(in_stat, in_path) {
if (in_path == null) {
return {
error: true,
device: null,
error_message: "No input path"
};
}
const canonical_result = _canonicalize_device_path(in_path);
if (canonical_result.error) {
return {
error: true,
device: null,
error_message: canonical_result.error_message
};
}
const canstat_result = stat(canonical_result.canonical);
if (canstat_result == null) {
return {
error: true,
device: null,
error_message: sprintf("Could not stat '%s' (canonical path for '%s')", canonical_result.canonical, in_path)
};
}
let parent_path = sprintf("%s/..", canonical_result.canonical);
if (canstat_result.type != "directory") {
parent_path = dirname(canonical_result.canonical);
}
const parent_stat = stat(parent_path);
if (parent_stat == null) {
return {
error: true,
device: null,
error_message: sprintf("Could not stat parent directory of '%s' (canonical path for '%s')", canonical_result.canonical, in_path)
};
}
if ((in_stat.dev.major != parent_stat.dev.major) || (in_stat.dev.minor != parent_stat.dev.minor) || (in_stat.inode == parent_stat.inode)) {
return {
error: false,
device: in_stat.dev,
error_message: null
};
}
return {
error: false,
device: null,
error_message: null
};
}
function _is_mountpoint(path) {
const path_stat = stat(path);
if (path_stat == null) {
return {
error: true,
is_mountpoint: null,
device: null,
error_message: sprintf("Could not stat '%s'", path)
};
}
const path_device_result = _dir_to_device(path_stat, path);
if (path_device_result.error) {
return {
error: true,
is_mountpoint: null,
device: null,
error_message: sprintf("Could not get device for '%s': %s", path, path_device_result.error_message)
};
} else {
return {
error: false,
is_mountpoint: (path_device_result.device != null),
device: path_device_result.device,
error_message: null
}
}
}
function is_mountpoint(path, show_error) {
const is_mp_result = _is_mountpoint(path);
if (is_mp_result.error) {
if (show_error) {
printf("%s\n", is_mp_result.error_message);
}
return -1;
} else {
return (is_mp_result.is_mountpoint ? 0 : 1);
}
}
function print_is_mountpoint(path, show_message, show_error) {
const is_mp = is_mountpoint(path, show_error);
if (is_mp == -1) {
exit(-1);
}
if (is_mp == 0) {
if (show_message) {
printf("%s is a mountpoint\n", path);
}
exit(0);
} else {
if (show_message) {
printf("%s is not a mountpoint\n", path);
}
exit(1);
}
}
export { is_mountpoint, print_is_mountpoint };
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment