anndl: Fixed a couple of bugs.
[utils.git] / nextep.c
... / ...
CommitLineData
1#include <stdlib.h>
2#include <stdio.h>
3#include <unistd.h>
4#include <string.h>
5#include <libgen.h>
6#include <dirent.h>
7#include <errno.h>
8#include <sys/stat.h>
9
10static int ensuredir(char *base, char *dir)
11{
12 if(access(dir, X_OK)) {
13 if((mkdir(base, 0777) && (errno != EEXIST)) || mkdir(dir, 0777))
14 return(1);
15 }
16 return(0);
17}
18
19static void checkempty(char *dir)
20{
21 DIR *dh;
22 int empty;
23 struct dirent *de;
24
25 if((dh = opendir(dir)) == NULL)
26 return;
27 empty = 1;
28 while((de = readdir(dh)) != NULL) {
29 if(de->d_name[0] != '.') {
30 empty = 0;
31 break;
32 }
33 }
34 closedir(dh);
35 if(empty)
36 rmdir(dir);
37}
38
39static void usage(FILE *out)
40{
41 fprintf(out, "usage: nextep [-h] [-f FILE] [-s SET-VALUE] [DIR]\n");
42}
43
44int main(int argc, char **argv)
45{
46 int c;
47 char buf[1024], dbuf[1024], *p;
48 char *file, *value, *dir;
49 char base[1024], fpath[1024];
50 FILE *fp;
51
52 file = "nextep";
53 value = NULL;
54 while((c = getopt(argc, argv, "hf:s:")) >= 0) {
55 switch(c) {
56 case 'f':
57 file = optarg;
58 break;
59 case 's':
60 value = optarg;
61 break;
62 case 'h':
63 usage(stdout);
64 exit(0);
65 default:
66 usage(stderr);
67 exit(1);
68 }
69 }
70 if(optind < argc) {
71 if(chdir(argv[optind])) {
72 fprintf(stderr, "nextep: %s: %s\n", argv[optind], strerror(errno));
73 exit(1);
74 }
75 optind++;
76 }
77 if(!getcwd(dbuf, sizeof(dbuf))) {
78 fprintf(stderr, "nextep: getcwd: %s\n", strerror(errno));
79 exit(1);
80 }
81 dir = basename(dbuf);
82 if((p = getenv("HOME")) == NULL) {
83 fprintf(stderr, "nextep: $HOME is not set\n");
84 exit(1);
85 }
86 snprintf(buf, sizeof(buf), "%s/.nextep", p);
87 snprintf(base, sizeof(base), "%s/%s", buf, dir);
88 snprintf(fpath, sizeof(fpath), "%s/%s", base, file);
89 if(value == NULL) {
90 if((fp = fopen(fpath, "r")) == NULL) {
91 if(errno != ENOENT) {
92 fprintf(stderr, "nextep: %s: %s\n", fpath, strerror(errno));
93 exit(1);
94 }
95 } else {
96 while(fgets(buf, sizeof(buf), fp) != NULL)
97 printf(buf);
98 fclose(fp);
99 }
100 } else if(!*value) {
101 if(unlink(fpath) && (errno != ENOENT)) {
102 fprintf(stderr, "nextep: %s: %s\n", fpath, strerror(errno));
103 exit(1);
104 }
105 checkempty(base);
106 } else {
107 if(ensuredir(buf, base)) {
108 fprintf(stderr, "nextep: %s: %s\n", base, strerror(errno));
109 exit(1);
110 }
111 if((fp = fopen(fpath, "w")) == NULL) {
112 fprintf(stderr, "nextep: %s: %s\n", fpath, strerror(errno));
113 exit(1);
114 }
115 fprintf(fp, "%s\n", value);
116 fclose(fp);
117 }
118 return(0);
119}
120
121/*
122 * Local Variables:
123 * compile-command: "gcc -Wall -g -o nextep nextep.c"
124 * End:
125 */