]> git.cameronkatri.com Git - opendircolors.git/blob - opendircolors.c
Write manpages for dirconvert and opendircolors
[opendircolors.git] / opendircolors.c
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 2021
5 * Cameron Katri. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY CAMERON KATRI AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL CAMERON KATRI OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29 #include <err.h>
30 #include <errno.h>
31 #include <getopt.h>
32 #include <libgen.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <sysexits.h>
37
38 #include "common.h"
39
40 void usage(const char *);
41
42 #define MAXKEYLEN 21
43
44 static const struct option long_options[] = { /* no clang-format */
45 { "help", no_argument, NULL, 'h' }, /**/
46 { "bourne-shell", no_argument, NULL, 'b' }, /**/
47 { "sh", no_argument, NULL, 'b' }, /**/
48 { "csh", no_argument, NULL, 'c' }, /**/
49 { "c-shell", no_argument, NULL, 'c' }, /**/
50 { NULL, no_argument, NULL, 0 }
51 };
52
53 static const char *long_types[38] = { "NORMAL", "NORM", "FILE", "RESET", "DIR",
54 "LNK", "LINK", "SYMLINK", "ORPHAN", "MISSING", "FIFO", "PIPE", "SOCK",
55 "BLK", "BLOCK", "CHR", "CHAR", "DOOR", "EXEC", "LEFT", "LEFTCODE",
56 "RIGHT", "RIGHTCODE", "END", "ENDCODE", "SUID", "SETUID", "SGID",
57 "SETGID", "STICKY", "OTHER_WRITABLE", "OWR", "STICKY_OTHER_WRITABLE",
58 "OWT", "CAPABILITY", "MULTIHARDLINK", "CLRTOEOL", NULL };
59
60 static const char *short_types[38] = { "no", "no", "fi", "rs", "di", "ln", "ln",
61 "ln", "or", "mi", "pi", "pi", "so", "bd", "bd", "cd", "cd", "do", "ex",
62 "lc", "lc", "rc", "rc", "ec", "ec", "su", "su", "sg", "sg", "st", "ow",
63 "ow", "tw", "tw", "ca", "mh", "cl", NULL };
64
65 int
66 main(int argc, char **argv)
67 {
68 int ch;
69 FILE *fd;
70 char *prefix = "LS_COLORS='";
71 char *suffix = "';\nexport LS_COLORS;";
72 char *lsprefix = "LSCOLORS='";
73 char *lssuffix = "';\nexport LSCOLORS;";
74
75 while (
76 (ch = getopt_long(argc, argv, "hbc", long_options, NULL)) != -1) {
77 switch (ch) {
78 case 'b':
79 prefix = "LS_COLORS='";
80 suffix = "';\nexport LS_COLORS;";
81 lsprefix = "LSCOLORS='";
82 lssuffix = "';\nexport LSCOLORS;";
83 break;
84 case 'c':
85 prefix = "setenv LS_COLORS '";
86 suffix = "'";
87 lsprefix = "setenv LSCOLORS '";
88 lssuffix = "'";
89 break;
90 case 'h':
91 case '?':
92 default:
93 usage(argv[0]);
94 }
95 }
96 argc -= optind;
97 argv += optind;
98
99 if (argc != 1)
100 usage(argv[1]);
101
102 char *path = *argv;
103 if (strcmp(path, "-") == 0)
104 fd = stdin;
105 else if ((fd = fopen(path, "r")) == NULL) {
106 warnx("%s: %s\n", path, strerror(errno));
107 return (errno);
108 }
109
110 char *line = NULL;
111 size_t linecap = 0;
112 ssize_t linelen;
113 char *out = strdup("");
114 while ((linelen = getline(&line, &linecap, fd)) > 0) {
115 if (*line == '#' || *line == '\n')
116 continue;
117 char fmttype[MAXKEYLEN] = "", val[MAXKEYLEN] = "";
118 sscanf(line, "%s %s\n", fmttype, val);
119 if (*line == '.') {
120 sprintf(out + strlen(out), "*%s=%s:", fmttype, val);
121 continue;
122 ;
123 } else if (*line == '*') {
124 sprintf(out + strlen(out), "%s=%s:", fmttype, val);
125 continue;
126 }
127 for (int i = 0; i < 37; i++) {
128 if (strcmp(fmttype, long_types[i]) == 0) {
129 sprintf(out + strlen(out),
130 "%s=%s:", short_types[i], val);
131 break;
132 }
133 }
134 }
135 fclose(fd);
136
137 fprintf(stdout, "%s%s%s\n", prefix, out, suffix);
138 fprintf(stdout, "%s%s%s\n", lsprefix, tolscolors(out), lssuffix);
139
140 free(line);
141 free(out);
142
143 return (0);
144 }
145
146 void
147 usage(const char *progname)
148 {
149 char *path;
150 path = strdup(progname);
151
152 (void)fprintf(stderr, "usage: %s [-bch] [FILE]\n", basename(path));
153 exit(EX_USAGE);
154 }