om

om - the most recently modified file in a directory
Log | Files | Refs | README

commit 3f3aec0425cec5ed2960421299e52abc53fb1348
Author: Larry Hynes <larry@larryhynes.com>
Date:   Wed Mar  8 17:48:20 +0000

om

Diffstat:
.gitignore | 2++
Makefile | 17+++++++++++++++++
README | 72++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
om.1 | 40++++++++++++++++++++++++++++++++++++++++
om.c | 79+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 210 insertions(+), 0 deletions(-)
diff --git a/.gitignore b/.gitignore @@ -0,0 +1,2 @@ +om +urls diff --git a/Makefile b/Makefile @@ -0,0 +1,17 @@ +CC = gcc +CFLAGS = -Wall -Wextra -pedantic -O2 + +BINDIR=/usr/local/bin +MANDIR=/usr/local/share/man/man1 + +OBJS = om.o + +om: $(OBJS) + $(CC) $(CFLAGS) -o om $(OBJS) + +clean: + $(RM) om.o + +install: om + install -m 0755 om $(BINDIR) + install -m 0644 om.1 $(MANDIR) diff --git a/README b/README @@ -0,0 +1,72 @@ +om - the most recently modified file in a directory + +om identifies the most recently modified regular file in the given +directory and prints the name of that file, possibly preceded by a +path component, on stdout. + +Having moved on from zsh (to ksh) one thing I did miss was zsh's + + vi *(.om[1]) + +to edit the most recent file. Hence om was born. (I did use the +following shell script, which I called 'latest', but om is more +fun.) + +================================================================== +#!/bin/sh + +if [ -d "$1" ] ; then + dir=$(cd "$1" || exit ; pwd) + file=$(ls -1AFt "$1" | sed '/[/*@=%|]$/d' | sed q) + echo "${dir}"/"${file}" +else + echo "$1" "is not a directory" +fi +================================================================== + +EXAMPLES +======= + + vi "$(om notes)" + + cp $(om ~/Downloads) ~/src + + tail -f $(om /var/log) + + scp `om .` frobzbox: + + mpv `om dl` + +BUGS +==== + +Obviously this is a little bit brain-damaged insofar as one never +knows with absolute certainty which file is the most recently +modified, that is to say the file that one thinks will be the most +recently modifed may not always be. + +IMPORTANT DISCLAIMER +==================== + +I have no idea what I'm doing. + +LICENSE +======= + +There is not enough art here to justify rights, but I include a +license to remove any ambiguity and to make it clear that there is +no warranty. + +Copyright (c) 2017 Larry Hynes <my first name at larryhynes.com> + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/om.1 b/om.1 @@ -0,0 +1,40 @@ +.Dd March 5, 2017 +.Dt OM 1 +.Os +.Sh NAME +.Nm om +.Nd the most recently modified file in a directory +.Sh SYNOPSIS +.Nm om +.Op Ar directory +.Sh DESCRIPTION +.Nm +identifies the most recently modified regular file in the given +.Ar directory +and prints the name of that file, possibly preceded by a path component, +on stdout. +.Sh EXAMPLES +vi "$( +.Nm +.Ar notes +)" +.Pp +cp $( +.Nm +.Ar ~/Downloads +) ~/src +.Pp +tail -f $( +.Nm +.Ar /var/log +) +.Pp +scp ` +.Nm +.Ar \&. +` frobzbox: +.Pp +mpv ` +.Nm +.Ar dl +` diff --git a/om.c b/om.c @@ -0,0 +1,79 @@ +#include <sys/stat.h> + +#include <dirent.h> +#include <err.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sysexits.h> + +#define MAX_LEN 1024 + +char *dir; + +/* Test if the argument is a directory */ +int +isadir() +{ + struct stat sb; + if (stat (dir, &sb) == 0 && S_ISDIR(sb.st_mode)) + { + return 0; + } + else { + errx(EX_NOINPUT, "Could not stat %s", dir); + return 1; + } +} + +char buf[MAX_LEN]; +char rcnt[MAX_LEN]; + +void +om(const char* dir, char* rcnt) +{ + DIR *dirp; + struct dirent *ent; + struct stat sb; + time_t mtime = 0; + + dirp = opendir(dir); + if (dirp != NULL) { + while ((ent = readdir (dirp)) != NULL) { + if (ent->d_type == DT_REG) { + snprintf(buf, MAX_LEN, "%s/%s", dir, ent->d_name); + stat(buf, &sb); + if (sb.st_mtime > mtime) { + snprintf(rcnt, MAX_LEN, "%s/%s", dir, ent->d_name ); + mtime = sb.st_mtime; + } + } + } + + closedir(dirp); + + } else { + errx(EX_NOINPUT, "Something went wrong"); + } +} + +int +main(int argc, char *argv[]) +{ + if (argc == 2) + { + dir = argv[1]; + + } else { + errx(EX_USAGE, "Usage: %s directory", argv[0]); + } + + isadir(); + + om(dir, rcnt); + printf("%s\n", rcnt); + + return 1; + + +}