]> git.cameronkatri.com Git - opendircolors.git/blob - opendircolors.c
Fix some errors
[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 <ctype.h>
30 #include <err.h>
31 #include <errno.h>
32 #include <getopt.h>
33 #include <libgen.h>
34 #include <stdbool.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <sysexits.h>
39
40 #include "common.h"
41
42 static void usage(const char *);
43
44 // clang-format off
45 static const struct option long_options[] = {
46 { "help", no_argument, NULL, 'h' },
47 { "bourne-shell", no_argument, NULL, 0 },
48 { "sh", no_argument, NULL, 'b' },
49 { "csh", no_argument, NULL, 'c' },
50 { "c-shell", no_argument, NULL, 'c' },
51 { NULL, no_argument, NULL, 0 }
52 };
53 // clang-format on
54
55 static const char *long_types[38] = { "NORMAL", "NORM", "FILE", "RESET", "DIR",
56 "LNK", "LINK", "SYMLINK", "ORPHAN", "MISSING", "FIFO", "PIPE", "SOCK",
57 "BLK", "BLOCK", "CHR", "CHAR", "DOOR", "EXEC", "LEFT", "LEFTCODE",
58 "RIGHT", "RIGHTCODE", "END", "ENDCODE", "SUID", "SETUID", "SGID",
59 "SETGID", "STICKY", "OTHER_WRITABLE", "OWR", "STICKY_OTHER_WRITABLE",
60 "OWT", "CAPABILITY", "MULTIHARDLINK", "CLRTOEOL", NULL };
61
62 static const char *short_types[38] = { "no", "no", "fi", "rs", "di", "ln", "ln",
63 "ln", "or", "mi", "pi", "pi", "so", "bd", "bd", "cd", "cd", "do", "ex",
64 "lc", "lc", "rc", "rc", "ec", "ec", "su", "su", "sg", "sg", "st", "ow",
65 "ow", "tw", "tw", "ca", "mh", "cl", NULL };
66
67 static const int indexes[37] = { -1, -1, -1, -1, 0, 1, 1,
68 1, -1, -1, 3, 3, 2, 5, 5, 6, 6, -1, 4,
69 -1, -1, -1, -1, -1, -1, 7, 7, 8, 8, -1, 10,
70 10, 9, 9, -1, -1, -1 };
71
72 int
73 main(int argc, char **argv)
74 {
75 int ch;
76 FILE *fd;
77 char *prefix = "LS_COLORS='";
78 char *suffix = "';\nexport LS_COLORS;";
79 char *lsprefix = "LSCOLORS='";
80 char *lssuffix = "';\nexport LSCOLORS;";
81
82 while (
83 (ch = getopt_long(argc, argv, "hbc", long_options, NULL)) != -1) {
84 switch (ch) {
85 case 'b':
86 prefix = "LS_COLORS='";
87 suffix = "';\nexport LS_COLORS;";
88 lsprefix = "LSCOLORS='";
89 lssuffix = "';\nexport LSCOLORS;";
90 break;
91 case 'c':
92 prefix = "setenv LS_COLORS '";
93 suffix = "'";
94 lsprefix = "setenv LSCOLORS '";
95 lssuffix = "'";
96 break;
97 case 'h':
98 case '?':
99 default:
100 usage(argv[0]);
101 }
102 }
103 argc -= optind;
104 argv += optind;
105
106 if (argc != 1)
107 usage(argv[1]);
108
109 char *path = *argv;
110 if (strcmp(path, "-") == 0)
111 fd = stdin;
112 else if ((fd = fopen(path, "r")) == NULL) {
113 warnx("%s: %s\n", path, strerror(errno));
114 return (errno);
115 }
116
117 char *line = NULL;
118 size_t linecap = 0;
119 ssize_t linelen;
120 char *ls_out = strdup("");
121 char lsout[22] = "xxxxxxxxxxxxxxxxxxxxxx";
122 struct color color;
123
124 while ((linelen = getline(&line, &linecap, fd)) > 0) {
125 if (*line == '#' || *line == '\n')
126 continue;
127 char fmttype[MAXKEYLEN] = "", val[MAXKEYLEN] = "";
128 sscanf(line, "%s %s\n", fmttype, val);
129 if (*line == '.') {
130 sprintf(ls_out + strlen(ls_out), "*%s=%s:", fmttype, val);
131 continue;
132 } else if (*line == '*') {
133 sprintf(ls_out + strlen(ls_out), "%s=%s:", fmttype, val);
134 continue;
135 }
136 for (int i = 0; i < 37; i++) {
137 if (strcmp(fmttype, long_types[i]) == 0) {
138 sprintf(ls_out + strlen(ls_out), "%s=%s:", short_types[i], val);
139 parseansi(val, &color);
140 if (indexes[i] >= 0) {
141 lsout[2 * indexes[i]] = color.fg;
142 lsout[2 * indexes[i] + 1] = color.bg;
143 }
144 break;
145 }
146 }
147 }
148 fclose(fd);
149
150 fprintf(stdout, "%s%s%s\n", prefix, ls_out, suffix);
151 fprintf(stdout, "%s%s%s\n", lsprefix, lsout, lssuffix);
152
153 free(line);
154 free(ls_out);
155
156 return (0);
157 }
158
159 static void
160 usage(const char *progname)
161 {
162 char *path;
163 path = strdup(progname);
164
165 (void)fprintf(stderr, "usage: %s [-bch] [FILE]\n", basename(path));
166 exit(EX_USAGE);
167 }