1 /*
2  * Calcurse - text-based organizer
3  *
4  * Copyright (c) 2004-2020 calcurse Development Team <misc@calcurse.org>
5  * 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  *
11  *      - Redistributions of source code must retain the above
12  *        copyright notice, this list of conditions and the
13  *        following disclaimer.
14  *
15  *      - Redistributions in binary form must reproduce the above
16  *        copyright notice, this list of conditions and the
17  *        following disclaimer in the documentation and/or other
18  *        materials provided with the distribution.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  * Send your feedback or comments to : misc@calcurse.org
33  * Calcurse home page : http://calcurse.org
34  *
35  */
36 
37 #include "calcurse.h"
38 
find_basedir(const char * locale_info[],unsigned n,char ** basedir)39 static int find_basedir(const char *locale_info[], unsigned n, char **basedir)
40 {
41 	int i;
42 	char *locale = NULL;
43 	int ret = 0;
44 
45 	for (i = 0; i < n; i++) {
46 		if (!locale_info[i])
47 			continue;
48 		locale = mem_strdup(locale_info[i]);
49 
50 		asprintf(basedir, "%s/%s", DOCDIR, locale);
51 		if (io_dir_exists(*basedir)) {
52 			ret = 1;
53 			goto cleanup;
54 		}
55 
56 		strtok(locale, ".@");
57 
58 		mem_free(*basedir);
59 		asprintf(basedir, "%s/%s", DOCDIR, locale);
60 		if (io_dir_exists(*basedir)) {
61 			ret = 1;
62 			goto cleanup;
63 		}
64 
65 		strtok(locale, "_");
66 
67 		mem_free(*basedir);
68 		asprintf(basedir, "%s/%s", DOCDIR, locale);
69 		if (io_dir_exists(*basedir)) {
70 			ret = 1;
71 			goto cleanup;
72 		}
73 
74 		mem_free(*basedir);
75 		*basedir = NULL;
76 		mem_free(locale);
77 		locale = NULL;
78 	}
79 
80 cleanup:
81 	if (locale)
82 		mem_free(locale);
83 	return ret;
84 }
85 
display_help(const char * topic)86 int display_help(const char *topic)
87 {
88 	const char *locale_info[] = {
89 		getenv("LANGUAGE"),
90 		getenv("LC_ALL"),
91 		getenv("LC_MESSAGE"),
92 		getenv("LANG")
93 	};
94 	char *basedir;
95 	char *path;
96 	int ret = 0;
97 
98 	if (!topic)
99 		topic = "intro";
100 
101 	if (!find_basedir(locale_info, ARRAY_SIZE(locale_info), &basedir))
102 		asprintf(&basedir, "%s", DOCDIR);
103 
104 	asprintf(&path, "%s/%s.txt", basedir, topic);
105 
106 	if (!io_file_exists(path)) {
107 		int ch = keys_str2int(topic);
108 		enum key action = keys_get_action(ch);
109 		if (ch > 0 && action > 0 && action != KEY_UNDEF) {
110 			topic = keys_get_label(action);
111 			mem_free(path);
112 			asprintf(&path, "%s/%s.txt", basedir, topic);
113 		}
114 	}
115 
116 	if (!io_file_exists(path)) {
117 		if (!strcmp(topic, "generic-cancel"))
118 			topic = "general";
119 		else if (!strcmp(topic, "generic-select"))
120 			topic = "general";
121 		else if (!strcmp(topic, "generic-credits"))
122 			topic = "intro";
123 		else if (!strcmp(topic, "generic-help"))
124 			topic = "intro";
125 		else if (!strcmp(topic, "generic-quit"))
126 			topic = "general";
127 		else if (!strcmp(topic, "generic-save"))
128 			topic = "save";
129 		else if (!strcmp(topic, "generic-reload"))
130 			topic = "reload";
131 		else if (!strcmp(topic, "generic-copy"))
132 			topic = "copy-paste";
133 		else if (!strcmp(topic, "generic-paste"))
134 			topic = "copy-paste";
135 		else if (!strcmp(topic, "generic-change-view"))
136 			topic = "tab";
137 		else if (!strcmp(topic, "generic-import"))
138 			topic = "import";
139 		else if (!strcmp(topic, "generic-export"))
140 			topic = "export";
141 		else if (!strcmp(topic, "generic-goto"))
142 			topic = "goto";
143 		else if (!strcmp(topic, "generic-other-cmd"))
144 			topic = "other";
145 		else if (!strcmp(topic, "generic-config-menu"))
146 			topic = "config";
147 		else if (!strcmp(topic, "generic-redraw"))
148 			topic = "general";
149 		else if (!strcmp(topic, "generic-add-appt"))
150 			topic = "general";
151 		else if (!strcmp(topic, "generic-add-todo"))
152 			topic = "general";
153 		else if (!strcmp(topic, "generic-prev-day"))
154 			topic = "general";
155 		else if (!strcmp(topic, "generic-next-day"))
156 			topic = "general";
157 		else if (!strcmp(topic, "generic-prev-week"))
158 			topic = "general";
159 		else if (!strcmp(topic, "generic-next-week"))
160 			topic = "general";
161 		else if (!strcmp(topic, "generic-prev-month"))
162 			topic = "general";
163 		else if (!strcmp(topic, "generic-next-month"))
164 			topic = "general";
165 		else if (!strcmp(topic, "generic-prev-year"))
166 			topic = "general";
167 		else if (!strcmp(topic, "generic-next-year"))
168 			topic = "general";
169 		else if (!strcmp(topic, "generic-scroll-down"))
170 			topic = "general";
171 		else if (!strcmp(topic, "generic-scroll-up"))
172 			topic = "general";
173 		else if (!strcmp(topic, "generic-goto-today"))
174 			topic = "general";
175 		else if (!strcmp(topic, "generic-command"))
176 			topic = "general";
177 		else if (!strcmp(topic, "move-right"))
178 			topic = "displacement";
179 		else if (!strcmp(topic, "move-left"))
180 			topic = "displacement";
181 		else if (!strcmp(topic, "move-down"))
182 			topic = "displacement";
183 		else if (!strcmp(topic, "move-up"))
184 			topic = "displacement";
185 		else if (!strcmp(topic, "start-of-week"))
186 			topic = "displacement";
187 		else if (!strcmp(topic, "end-of-week"))
188 			topic = "displacement";
189 		else if (!strcmp(topic, "add-item"))
190 			topic = "add";
191 		else if (!strcmp(topic, "del-item"))
192 			topic = "delete";
193 		else if (!strcmp(topic, "edit-item"))
194 			topic = "edit";
195 		else if (!strcmp(topic, "view-item"))
196 			topic = "view";
197 		else if (!strcmp(topic, "pipe-item"))
198 			topic = "pipe";
199 		else if (!strcmp(topic, "flag-item"))
200 			topic = "flag";
201 		else if (!strcmp(topic, "repeat"))
202 			topic = "repeat";
203 		else if (!strcmp(topic, "edit-note"))
204 			topic = "enote";
205 		else if (!strcmp(topic, "view-note"))
206 			topic = "vnote";
207 		else if (!strcmp(topic, "raise-priority"))
208 			topic = "priority";
209 		else if (!strcmp(topic, "lower-priority"))
210 			topic = "priority";
211 		mem_free(path);
212 		asprintf(&path, "%s/%s.txt", basedir, topic);
213 	}
214 
215 	if (io_file_exists(path)) {
216 		const char *arg[] = { conf.pager, path, NULL };
217 		wins_launch_external(arg);
218 		ret = 1;
219 	}
220 
221 	mem_free(basedir);
222 	mem_free(path);
223 	return ret;
224 }
225