1 /*
2   DF-SHOW: An interactive directory/file browser written for Unix-like systems.
3   Based on the applications from the PC-DOS DF-EDIT suite by Larry Kroeker.
4   Copyright (C) 2018-2021  Robert Ian Hawdon
5 
6   This program is free software: you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation, either version 3 of the License, or
9   (at your option) any later version.
10 
11   This program is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15 
16   You should have received a copy of the GNU General Public License
17   along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #define _GNU_SOURCE
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <ncurses.h>
24 #include <locale.h>
25 #include <string.h>
26 #include <unistd.h>
27 #include <signal.h>
28 #include <getopt.h>
29 #include <libconfig.h>
30 #include <ctype.h>
31 #include <math.h>
32 #include "config.h"
33 #include "showfunctions.h"
34 #include "showmenus.h"
35 #include "colors.h"
36 #include "menu.h"
37 #include "display.h"
38 #include "settings.h"
39 #include "common.h"
40 #include "show.h"
41 #include "input.h"
42 
43 char * visualPath;
44 char * pagerPath;
45 
46 char currentpwd[4096];
47 
48 int viewMode = 0;
49 int resized = 0;
50 
51 char sortmode[9] = "name";
52 char timestyle[9] = "locale";
53 int reverse = 0;
54 int human = 0;
55 int si = 0;
56 int ogavis = 3;
57 int ogapad = 1;
58 int showbackup = 1;
59 int colormode = 0;
60 int danger = 0;
61 int invalidstart = 0;
62 int filecolors = 0;
63 int markedinfo = 0;
64 int useEnvPager = 0;
65 int launchThemeEditor = 0;
66 int launchSettingsMenu = 0;
67 int oneLine = 0;
68 int skipToFirstFile = 0;
69 bool useDefinedEditor = 0;
70 bool useDefinedPager = 0;
71 
72 bool dirOnly = 0;
73 bool scaleSize = 0;
74 
75 int plugins = 0; // Not yet implemented
76 
77 int enterAsShow = 0;
78 
79 int messageBreak = 0;
80 
81 int showProcesses;
82 
83 int showContext = 0;
84 
85 int showSizeBlocks = 0;
86 
87 int showXAttrs = 0;
88 
89 int showAcls = 0; // Might end up not implementing this.
90 
91 #ifdef HAVE_GNU_BLOCKSIZE
92 int block_size = 1024;
93 #else
94 int block_size = 512;
95 #endif
96 
97 char *objectWild;
98 
99 char block_unit[4] = "\0\0\0\0";
100 
101 results *ob;
102 
103 int segOrder[9] = {COL_MARK, COL_SIZEBLOCKS, COL_ATTR, COL_HLINK, COL_OWNER, COL_CONTEXT, COL_SIZE, COL_DATE, COL_NAME};
104 // int segOrder[9] = {COL_MARK, COL_NAME, COL_SIZE, COL_DATE, COL_ATTR}; // Emulating NET-DF-EDIT's XENIX layout
105 
106 extern int skippable;
107 
108 extern int settingsPos;
109 extern int settingsBinPos;
110 extern int settingsFreePos;
111 
112 extern menuDef *settingsMenu;
113 extern int settingsMenuSize;
114 extern wchar_t *settingsMenuLabel;
115 
116 extern int * pc;
117 
118 extern history *hs;
119 extern int topfileref;
120 extern int lineStart;
121 extern int selected;
122 extern int totalfilecount;
123 extern int showhidden;
124 
125 extern char globalConfLocation[4096];
126 extern char homeConfLocation[4096];
127 
128 extern char themeName[256];
129 
130 struct sigaction sa;
131 
132 extern int exitCode;
133 extern int enableCtrlC;
134 
135 extern wchar_t *globalMenuLabel;
136 extern wchar_t *fileMenuLabel;
137 extern wchar_t *functionMenuLabel;
138 extern wchar_t *modifyMenuLabel;
139 extern wchar_t *sortMenuLabel;
140 extern wchar_t *linkMenuLabel;
141 
142 extern xattrList *xa;
143 extern int xattrPos;
144 
145 int setMarked(char* markedinput);
146 int checkStyle(char* styleinput);
147 
readConfig(const char * confFile)148 void readConfig(const char * confFile)
149 {
150   config_t cfg;
151   config_setting_t *root, *setting, *group, *array; //probably don't need the array, but it may be used in the future.
152   char markedParam[8];
153   int i, n;
154   config_init(&cfg);
155   if (config_read_file(&cfg, confFile)){
156     // Deal with the globals first
157     group = config_lookup(&cfg, "common");
158     if (group){
159       setting = config_setting_get_member(group, "theme");
160       if (setting){
161         if (!getenv("DFS_THEME_OVERRIDE")){
162           strcpy(themeName, config_setting_get_string(setting));
163           setenv("DFS_THEME", themeName, 1);
164         }
165       }
166       setting = config_setting_get_member(group, "sigint");
167       if (setting){
168         if (config_setting_get_int(setting)){
169           enableCtrlC = 1;
170         }
171       }
172     }
173     // Now for program specific
174     group = config_lookup(&cfg, PROGRAM_NAME);
175     if (group){
176       // Check File Colour
177       setting = config_setting_get_member(group, "color");
178       if (setting){
179         if (config_setting_get_int(setting)){
180           filecolors = 1;
181         }
182       }
183       // Check Marked
184       setting = config_setting_get_member(group, "marked");
185       if (setting){
186         strcpy(markedParam, config_setting_get_string(setting));
187         setMarked(markedParam);
188       }
189       // Check Sort
190       setting = config_setting_get_member(group, "sortmode");
191       if (setting){
192         strcpy(sortmode, config_setting_get_string(setting));
193       }
194       // Check Reverse
195       setting = config_setting_get_member(group, "reverse");
196       if (setting){
197         if (config_setting_get_int(setting)){
198           reverse = 1;
199         }
200       }
201       // Check Timestyle
202       setting = config_setting_get_member(group, "timestyle");
203       if (setting){
204         strcpy(timestyle, config_setting_get_string(setting));
205         if(!checkStyle(timestyle)){
206           strcpy(timestyle, "locale");
207         }
208       }
209       // Check Hidden
210       setting = config_setting_get_member(group, "hidden");
211       if (setting){
212         if (config_setting_get_int(setting)){
213           showhidden = 1;
214         }
215       }
216       // Check Ignore Backups
217       setting = config_setting_get_member(group, "ignore-backups");
218       if (setting){
219         if (config_setting_get_int(setting)){
220           showbackup = 0;
221         }
222       }
223       // Check No SF
224       setting = config_setting_get_member(group, "no-sf");
225       if (setting){
226         if (config_setting_get_int(setting)){
227           useEnvPager = 1;
228         }
229       }
230       // Check No Danger
231       setting = config_setting_get_member(group, "no-danger");
232       if (setting){
233         if (config_setting_get_int(setting)){
234           danger = 0;
235         }
236       }
237       // Check SI
238       setting = config_setting_get_member(group, "si");
239       if (setting){
240         if (config_setting_get_int(setting)){
241           si = 1;
242         }
243       }
244       // Check Human Readable
245       setting = config_setting_get_member(group, "human-readable");
246       if (setting){
247         if (config_setting_get_int(setting)){
248           human = 1;
249         }
250       }
251       // Check Enter As Show
252       setting = config_setting_get_member(group, "show-on-enter");
253       if (setting){
254         if (config_setting_get_int(setting)){
255           enterAsShow = 1;
256         }
257       }
258       // Check Security Context
259       setting = config_setting_get_member(group, "context");
260       if (setting){
261         if (config_setting_get_int(setting)){
262           showContext = 1;
263         }
264       }
265       // Check Skip To First Object
266       setting = config_setting_get_member(group, "skip-to-first");
267       if (setting){
268         if (config_setting_get_int(setting)){
269           skipToFirstFile = 1;
270         }
271       }
272       // Check Showing XAttrs
273       setting = config_setting_get_member(group, "showXAttrs");
274       if (setting){
275         if (config_setting_get_int(setting)){
276           showXAttrs = 1;
277         }
278       }
279       // Check Showing Only Directories
280       setting = config_setting_get_member(group, "only-dirs");
281       if (setting){
282         if (config_setting_get_int(setting)){
283           dirOnly = 1;
284         }
285       }
286       // Check Show Size In Blocks
287       setting = config_setting_get_member(group, "sizeblocks");
288       if (setting){
289         if (config_setting_get_int(setting)){
290           dirOnly = 1;
291         }
292       }
293       // Check use defined editor
294       setting = config_setting_get_member(group, "defined-editor");
295       if (setting){
296         if (config_setting_get_int(setting)){
297           useDefinedEditor = 1;
298         }
299       }
300       // Check visualPath
301       setting = config_setting_get_member(group, "visualPath");
302       if (setting){
303         if (visualPath){
304           free(visualPath);
305         }
306         visualPath = calloc(strlen(config_setting_get_string(setting)) + 1, sizeof(char));
307         strcpy(visualPath, config_setting_get_string(setting));
308       }
309       // Check use defined pager
310       setting = config_setting_get_member(group, "defined-pager");
311       if (setting){
312         if (config_setting_get_int(setting)){
313           useDefinedPager = 1;
314         }
315       }
316       // Check pagerPath
317       setting = config_setting_get_member(group, "pagerPath");
318       if (setting){
319         if (pagerPath){
320           free(pagerPath);
321         }
322         pagerPath = calloc(strlen(config_setting_get_string(setting)) + 1, sizeof(char));
323         strcpy(pagerPath, config_setting_get_string(setting));
324       }
325       // Check Layout
326       array = config_setting_get_member(group, "layout");
327       if (array){
328         for (i = 0; i < 8; i++){
329           if (config_setting_get_elem(array, i) != NULL){
330             segOrder[i] = config_setting_get_int_elem(array, i);
331           } else {
332             segOrder[i] = -1;
333           }
334         }
335       }
336     }
337     // Check owner column
338     group = config_lookup(&cfg, "show.owner");
339     if (group){
340       ogavis = 0;
341       setting = config_setting_get_member(group, "owner");
342       if (setting){
343         if (config_setting_get_int(setting)){
344           ogavis = ogavis + 1;
345         }
346       }
347       setting = config_setting_get_member(group, "group");
348       if (setting){
349         if (config_setting_get_int(setting)){
350           ogavis = ogavis + 2;
351         }
352       }
353       setting = config_setting_get_member(group, "author");
354       if (setting){
355         if (config_setting_get_int(setting)){
356           ogavis = ogavis + 4;
357         }
358       }
359     }
360   };
361   config_destroy(&cfg);
362 }
363 
saveConfig(const char * confFile,settingIndex ** settings,t1CharValues ** values,t2BinValues ** bins,int items,int charIndex,int binIndex)364 void saveConfig(const char * confFile, settingIndex **settings, t1CharValues **values, t2BinValues **bins, int items, int charIndex, int binIndex)
365 {
366   config_t cfg;
367   config_setting_t *root, *setting, *group, *subgroup;
368   int i, v;
369 
370   config_init(&cfg);
371 
372   config_read_file(&cfg, confFile);
373   root = config_root_setting(&cfg);
374 
375   group = config_setting_get_member(root, PROGRAM_NAME);
376 
377   if (!group){
378     group = config_setting_add(root, PROGRAM_NAME, CONFIG_TYPE_GROUP);
379   }
380 
381   for (i = 0; i < items; i++){
382     config_setting_remove(group, (*settings)[i].refLabel);
383     if ((*settings)[i].type == SETTING_BOOL){
384       setting = config_setting_add(group, (*settings)[i].refLabel, CONFIG_TYPE_INT);
385 
386       if (!strcmp((*settings)[i].refLabel, "color")){
387         config_setting_set_int(setting, filecolors);
388       } else if (!strcmp((*settings)[i].refLabel, "reverse")){
389         config_setting_set_int(setting, reverse);
390       } else if (!strcmp((*settings)[i].refLabel, "hidden")){
391         config_setting_set_int(setting, showhidden);
392       } else if (!strcmp((*settings)[i].refLabel, "ignore-backups")){
393         config_setting_set_int(setting, !showbackup);
394       } else if (!strcmp((*settings)[i].refLabel, "no-sf")){
395         config_setting_set_int(setting, useEnvPager);
396       } else if (!strcmp((*settings)[i].refLabel, "no-danger")){
397         config_setting_set_int(setting, !danger);
398       } else if (!strcmp((*settings)[i].refLabel, "si")){
399         config_setting_set_int(setting, si);
400       } else if (!strcmp((*settings)[i].refLabel, "human-readable")){
401         config_setting_set_int(setting, human);
402       } else if (!strcmp((*settings)[i].refLabel, "show-on-enter")){
403         config_setting_set_int(setting, enterAsShow);
404       } else if (!strcmp((*settings)[i].refLabel, "context")){
405         config_setting_set_int(setting, showContext);
406       } else if (!strcmp((*settings)[i].refLabel, "skip-to-first")){
407         config_setting_set_int(setting, skipToFirstFile);
408       } else if (!strcmp((*settings)[i].refLabel, "showXAttrs")){
409         config_setting_set_int(setting, showXAttrs);
410       } else if (!strcmp((*settings)[i].refLabel, "only-dirs")){
411         config_setting_set_int(setting, dirOnly);
412       } else if (!strcmp((*settings)[i].refLabel, "sizeblocks")){
413         config_setting_set_int(setting, showSizeBlocks);
414       } else if (!strcmp((*settings)[i].refLabel, "defined-editor")){
415         config_setting_set_int(setting, useDefinedEditor);
416       } else if (!strcmp((*settings)[i].refLabel, "defined-pager")){
417         config_setting_set_int(setting, useDefinedPager);
418       }
419     } else if ((*settings)[i].type == SETTING_SELECT){
420       //
421       setting = config_setting_add(group, (*settings)[i].refLabel, CONFIG_TYPE_STRING);
422       if (!strcmp((*settings)[i].refLabel, "marked")){
423         for(v = 0; v < charIndex; v++){
424           if (!strcmp((*values)[v].refLabel, "marked") && ((*settings)[i].intSetting == (*values)[v].index)){
425             config_setting_set_string(setting, (*values)[v].value);
426           }
427         }
428       } else if (!strcmp((*settings)[i].refLabel, "sortmode")){
429         config_setting_set_string(setting, sortmode);
430       } else if (!strcmp((*settings)[i].refLabel, "timestyle")){
431         config_setting_set_string(setting, timestyle);
432       }
433     } else if ((*settings)[i].type == SETTING_MULTI){
434       if (!strcmp((*settings)[i].refLabel, "owner")){
435         subgroup = config_setting_add(group, "owner", CONFIG_TYPE_GROUP);
436         for (v = 0; v < binIndex; v++){
437           setting = config_setting_add(subgroup, (*bins)[v].settingLabel, CONFIG_TYPE_INT);
438           config_setting_set_int(setting, (*bins)[v].boolVal);
439         }
440       }
441     } else if ((*settings)[i].type == SETTING_FREE){
442       setting = config_setting_add(group, (*settings)[i].refLabel, CONFIG_TYPE_STRING);
443       if (!strcmp((*settings)[i].refLabel, "visualPath")){
444         config_setting_set_string(setting, (*settings)[i].charSetting);
445       } else if (!strcmp((*settings)[i].refLabel, "pagerPath")){
446         config_setting_set_string(setting, (*settings)[i].charSetting);
447       }
448     }
449   }
450 
451   config_write_file(&cfg, confFile);
452 
453   config_destroy(&cfg);
454 }
455 
applySettings(settingIndex ** settings,t1CharValues ** values,int items,int valuesCount)456 void applySettings(settingIndex **settings, t1CharValues **values, int items, int valuesCount)
457 {
458   int i, j;
459   for (i = 0; i < items; i++){
460     if (!strcmp((*settings)[i].refLabel, "color")){
461       filecolors = (*settings)[i].intSetting;
462     } else if (!strcmp((*settings)[i].refLabel, "reverse")){
463       reverse = (*settings)[i].intSetting;
464     } else if (!strcmp((*settings)[i].refLabel, "hidden")){
465       showhidden = (*settings)[i].intSetting;
466     } else if (!strcmp((*settings)[i].refLabel, "ignore-backups")){
467       showbackup = (*settings)[i].intSetting;
468     } else if (!strcmp((*settings)[i].refLabel, "no-sf")){
469       useEnvPager = (*settings)[i].intSetting;
470     } else if (!strcmp((*settings)[i].refLabel, "no-danger")){
471       danger = (*settings)[i].intSetting;
472     } else if (!strcmp((*settings)[i].refLabel, "si")){
473       si = (*settings)[i].intSetting;
474     } else if (!strcmp((*settings)[i].refLabel, "human-readable")){
475       human = (*settings)[i].intSetting;
476     } else if (!strcmp((*settings)[i].refLabel, "show-on-enter")){
477       enterAsShow = (*settings)[i].intSetting;
478     } else if (!strcmp((*settings)[i].refLabel, "marked")){
479       markedinfo = (*settings)[i].intSetting;
480     } else if (!strcmp((*settings)[i].refLabel, "context")){
481       showContext = (*settings)[i].intSetting;
482     } else if (!strcmp((*settings)[i].refLabel, "skip-to-first")){
483       skipToFirstFile = (*settings)[i].intSetting;
484     } else if (!strcmp((*settings)[i].refLabel, "sortmode")){
485       for (j = 0; j < valuesCount; j++){
486         if (!strcmp((*values)[j].refLabel, "sortmode") && ((*values)[j].index == (*settings)[i].intSetting)){
487           strcpy(sortmode, (*values)[j].value);
488         }
489       }
490     } else if (!strcmp((*settings)[i].refLabel, "timestyle")){
491       for (j = 0; j < valuesCount; j++){
492         if (!strcmp((*values)[j].refLabel, "timestyle") && ((*values)[j].index == (*settings)[i].intSetting)){
493           strcpy(timestyle, (*values)[j].value);
494         }
495       }
496     } else if (!strcmp((*settings)[i].refLabel, "owner")){
497       ogavis = (*settings)[i].intSetting;
498     } else if (!strcmp((*settings)[i].refLabel, "showXAttrs")){
499       showXAttrs = (*settings)[i].intSetting;
500     } else if (!strcmp((*settings)[i].refLabel, "only-dirs")){
501       dirOnly = (*settings)[i].intSetting;
502     } else if (!strcmp((*settings)[i].refLabel, "sizeblocks")){
503       showSizeBlocks = (*settings)[i].intSetting;
504     } else if (!strcmp((*settings)[i].refLabel, "defined-editor")){
505       useDefinedEditor = (*settings)[i].intSetting;
506     } else if (!strcmp((*settings)[i].refLabel, "visualPath")){
507       free(visualPath);
508       visualPath = calloc((strlen((*settings)[i].charSetting) + 1), sizeof(char));
509       sprintf(visualPath, "%s", (*settings)[i].charSetting);
510     } else if (!strcmp((*settings)[i].refLabel, "defined-pager")){
511       useDefinedPager = (*settings)[i].intSetting;
512     } else if (!strcmp((*settings)[i].refLabel, "pagerPath")){
513       free(pagerPath);
514       pagerPath = calloc((strlen((*settings)[i].charSetting) + 1), sizeof(char));
515       sprintf(pagerPath, "%s", (*settings)[i].charSetting);
516     }
517   }
518 }
519 
settingsMenuView()520 void settingsMenuView(){
521   uid_t uid=getuid(), euid=geteuid();
522   int items, count = 0;
523   int x = 2;
524   int y = 3;
525   settingIndex *settingIndex;
526   t1CharValues *charValues;
527   t2BinValues *binValues;
528   int markedCount, sortmodeCount, timestyleCount, ownerCount;
529   int charValuesCount;
530   int binValuesCount;
531   int sortmodeInt, timestyleInt;
532   int e;
533   char charTempValue[1024];
534 
535  reloadSettings:
536 
537   items = charValuesCount = binValuesCount = markedCount = sortmodeCount = timestyleCount = ownerCount = 0;
538 
539   clear();
540   wPrintMenu(0,0,settingsMenuLabel);
541   // mvprintw(2, 10, "SHOW Settings Menu");
542 
543   addT1CharValue(&charValues, &charValuesCount, &markedCount, "marked", "never");
544   addT1CharValue(&charValues, &charValuesCount, &markedCount, "marked", "always");
545   addT1CharValue(&charValues, &charValuesCount, &markedCount, "marked", "auto");
546 
547   addT1CharValue(&charValues, &charValuesCount, &sortmodeCount, "sortmode", "name");
548   addT1CharValue(&charValues, &charValuesCount, &sortmodeCount, "sortmode", "date");
549   addT1CharValue(&charValues, &charValuesCount, &sortmodeCount, "sortmode", "size");
550   addT1CharValue(&charValues, &charValuesCount, &sortmodeCount, "sortmode", "unsorted");
551 
552   addT1CharValue(&charValues, &charValuesCount, &timestyleCount, "timestyle", "locale");
553   addT1CharValue(&charValues, &charValuesCount, &timestyleCount, "timestyle", "iso");
554   addT1CharValue(&charValues, &charValuesCount, &timestyleCount, "timestyle", "long-iso");
555   addT1CharValue(&charValues, &charValuesCount, &timestyleCount, "timestyle", "full-iso");
556 
557   addT2BinValue(&binValues, &binValuesCount, &ownerCount, "owner", "owner", 1);
558   addT2BinValue(&binValues, &binValuesCount, &ownerCount, "owner", "group", 0);
559   addT2BinValue(&binValues, &binValuesCount, &ownerCount, "owner", "author", 0);
560 
561   sortmodeInt = textValueLookup(&charValues, &charValuesCount, "sortmode", sortmode);
562   timestyleInt = textValueLookup(&charValues, &charValuesCount, "timestyle", timestyle);
563 
564   importSetting(&settingIndex, &items, "color",          L"Display file colors", SETTING_BOOL, NULL, filecolors, -1, 0);
565   importSetting(&settingIndex, &items, "marked",         L"Show marked file info", SETTING_SELECT, NULL, markedinfo, markedCount, 0);
566   importSetting(&settingIndex, &items, "sortmode",       L"Sorting mode", SETTING_SELECT, NULL, sortmodeInt, sortmodeCount, 0);
567   importSetting(&settingIndex, &items, "reverse",        L"Reverse sorting order", SETTING_BOOL, NULL, reverse, -1, 0);
568   importSetting(&settingIndex, &items, "timestyle",      L"Time style", SETTING_SELECT, NULL, timestyleInt, timestyleCount, 0);
569   importSetting(&settingIndex, &items, "hidden",         L"Show hidden files", SETTING_BOOL, NULL, showhidden, -1, 0);
570   importSetting(&settingIndex, &items, "ignore-backups", L"Hide backup files", SETTING_BOOL, NULL, showbackup, -1, 1);
571   importSetting(&settingIndex, &items, "no-sf",          L"Use 3rd party pager over SF", SETTING_BOOL, NULL, useEnvPager, -1, 0);
572   if (uid == 0 || euid == 0){
573     importSetting(&settingIndex, &items, "no-danger",      L"Hide danger lines as root", SETTING_BOOL, NULL, danger, -1, 1);
574   }
575   importSetting(&settingIndex, &items, "si",             L"Use SI units", SETTING_BOOL, NULL, si, -1, 0);
576   importSetting(&settingIndex, &items, "human-readable", L"Human readable sizes", SETTING_BOOL, NULL, human, -1, 0);
577   importSetting(&settingIndex, &items, "show-on-enter",  L"Enter key acts like Show", SETTING_BOOL, NULL, enterAsShow, -1, 0);
578   importSetting(&settingIndex, &items, "owner",          L"Owner Column", SETTING_MULTI, NULL, ogavis, ownerCount, 0);
579   importSetting(&settingIndex, &items, "context",        L"Show security context of files", SETTING_BOOL, NULL, showContext, -1, 0);
580   importSetting(&settingIndex, &items, "skip-to-first",  L"Skip to the first object", SETTING_BOOL, NULL, skipToFirstFile, -1, 0);
581 #ifdef HAVE_ACL_TYPE_EXTENDED
582   importSetting(&settingIndex, &items, "showXAttrs",     L"Display extended attribute keys and sizes", SETTING_BOOL, NULL, showXAttrs, -1, 0);
583 #endif
584   importSetting(&settingIndex, &items, "only-dirs",      L"Display only directories", SETTING_BOOL, NULL, dirOnly, -1, 0);
585   importSetting(&settingIndex, &items, "sizeblocks",     L"Show allocated size in blocks", SETTING_BOOL, NULL, showSizeBlocks, -1, 0);
586   importSetting(&settingIndex, &items, "defined-editor", L"Override default editor", SETTING_BOOL, NULL, useDefinedEditor, -1, 0);
587   importSetting(&settingIndex, &items, "visualPath",     L"Editor utility program command", SETTING_FREE, visualPath, -1, -1, 0);
588   importSetting(&settingIndex, &items, "defined-pager",  L"Override default pager", SETTING_BOOL, NULL, useDefinedPager, -1, 0);
589   importSetting(&settingIndex, &items, "pagerPath",      L"Pager utility program command", SETTING_FREE, pagerPath, -1, -1, 0);
590 
591   populateBool(&binValues, "owner", ogavis, binValuesCount);
592 
593   while(1)
594     {
595       for (count = 0; count < items; count++){
596         printSetting(2 + count, 3, &settingIndex, &charValues, &binValues, count, charValuesCount, binValuesCount, settingIndex[count].type, settingIndex[count].invert);
597       }
598 
599       move(x + settingsPos, y + 1);
600       *pc = getch10th();
601       if (*pc == menuHotkeyLookup(settingsMenu, "s_quit", settingsMenuSize)){
602         curs_set(FALSE);
603         applySettings(&settingIndex, &charValues, items, charValuesCount);
604         free(settingIndex);
605         return;
606       } else if (*pc == menuHotkeyLookup(settingsMenu, "s_revert", settingsMenuSize)){
607         free(settingIndex);
608         goto reloadSettings;
609       } else if (*pc == menuHotkeyLookup(settingsMenu, "s_save", settingsMenuSize)){
610         applySettings(&settingIndex, &charValues, items, charValuesCount);
611         if (access(dirFromPath(homeConfLocation), W_OK) != 0) {
612           createParentDirs(homeConfLocation);
613         }
614         saveConfig(homeConfLocation, &settingIndex, &charValues, &binValues, items, charValuesCount, binValuesCount);
615         curs_set(FALSE);
616         topLineMessage("Settings saved.");
617         curs_set(TRUE);
618         wPrintMenu(0,0,settingsMenuLabel);
619       } else if (*pc == 258 || *pc == 10){
620         if (settingsPos < (items -1 )){
621           settingsBinPos = -1;
622           settingsPos++;
623         }
624       } else if (*pc == 32 || *pc == 260 || *pc == 261){
625         // Adjust
626         if (settingIndex[settingsPos].type == SETTING_BOOL){
627           if (settingIndex[settingsPos].intSetting > 0){
628             updateSetting(&settingIndex, settingsPos, 0, 0);
629           } else {
630             updateSetting(&settingIndex, settingsPos, 0, 1);
631           }
632         } else if (settingIndex[settingsPos].type == SETTING_SELECT){
633           if (*pc == 32 || *pc == 261){
634             if (settingIndex[settingsPos].intSetting < (settingIndex[settingsPos].maxValue) - 1){
635               updateSetting(&settingIndex, settingsPos, 1, (settingIndex[settingsPos].intSetting) + 1);
636             } else {
637               updateSetting(&settingIndex, settingsPos, 1, 0);
638             }
639           } else {
640             if (settingIndex[settingsPos].intSetting > 0){
641               updateSetting(&settingIndex, settingsPos, 1, (settingIndex[settingsPos].intSetting) - 1);
642             } else {
643               updateSetting(&settingIndex, settingsPos, 1, (settingIndex[settingsPos].maxValue - 1));
644             }
645           }
646         } else if (settingIndex[settingsPos].type == SETTING_MULTI){
647           if (*pc == 261 && (settingsBinPos < (settingIndex[settingsPos].maxValue -1))){
648             settingsBinPos++;
649           } else if (*pc == 260 && (settingsBinPos > -1)){
650             settingsBinPos--;
651           } else if (*pc == 32 && (settingsBinPos > -1)){
652             // Not fond of this, but it should work
653             if (!strcmp(settingIndex[settingsPos].refLabel, "owner")){
654               adjustBinSetting(&settingIndex, &binValues, "owner", &ogavis, binValuesCount);
655             }
656           }
657         } else if (settingIndex[settingsPos].type == SETTING_FREE){
658           if (*pc == 32 || *pc == 261) {
659             settingsFreePos = 0;
660             move(x + settingsPos, y + wcslen(settingIndex[settingsPos].textLabel) + 6);
661             e = readline(charTempValue, 1024, settingIndex[settingsPos].charSetting);
662             if (strcmp(charTempValue, "")){
663               free(settingIndex[settingsPos].charSetting);
664               settingIndex[settingsPos].charSetting = malloc(sizeof(char) * (strlen(charTempValue) + 1));
665               sprintf(settingIndex[settingsPos].charSetting, "%s", charTempValue);
666             }
667             move(x + settingsPos, 0);
668             clrtoeol();
669             settingsFreePos = -1;
670           }
671         }
672       } else if (*pc == 259){
673         if (settingsPos > 0){
674           settingsBinPos = -1;
675           settingsPos--;
676         }
677       }
678     }
679 }
680 
directory_view(char * currentpwd)681 int directory_view(char * currentpwd)
682 {
683   objectWild = objectFromPath(currentpwd);
684   if ( strchr(objectWild, MULTICHAR) || strchr(objectWild, ONECHAR)){
685     strcpy(currentpwd, dirFromPath(currentpwd));
686   } else {
687     strcpy(objectWild, "");
688   }
689 
690   lineStart = 0;
691   clear();
692   setColors(COMMAND_PAIR);
693 
694 
695   wPrintMenu(0, 0, fileMenuLabel);
696 
697   set_history(currentpwd, "", "", 0, 0);
698   freeResults(ob, totalfilecount);
699   freeXAttrs(xa, xattrPos);
700   ob = get_dir(currentpwd);
701   reorder_ob(ob, sortmode);
702   generateEntryLineIndex(ob);
703 
704   if (skipToFirstFile == 1 && skippable == 1){
705     selected = 2;
706   } else {
707     selected = 0;
708   }
709 
710   display_dir(currentpwd, ob);
711 
712   refresh();
713 
714   directory_view_menu_inputs();
715 
716   freeResults(ob, totalfilecount); //freeing memory
717   freeXAttrs(xa, xattrPos);
718   return 0;
719 }
720 
global_menu()721 int global_menu()
722 {
723   clear();
724   refresh();
725   global_menu_inputs();
726   return 0;
727 }
728 
setMarked(char * markedinput)729 int setMarked(char* markedinput)
730 {
731   int status = -1;
732   if (!strcmp(markedinput, "always")){
733     markedinfo = 1;
734     status = 0;
735   } else if (!strcmp(markedinput, "never")){
736     markedinfo = 0;
737     status = 0;
738   } else if (!strcmp(markedinput, "auto")){
739     markedinfo = 2;
740     status = 0;
741   }
742   return(status);
743 }
744 
checkStyle(char * styleinput)745 int checkStyle(char* styleinput)
746 {
747   if ( (strcmp(styleinput, "long-iso") && (strcmp(styleinput, "full-iso") && strcmp(styleinput, "iso") && strcmp(styleinput, "locale") ))){
748       return 0;
749     } else {
750       return 1;
751     }
752 }
753 
setColor(char * colorinput)754 int setColor(char* colorinput)
755 {
756   if (!strcmp(colorinput, "always")){
757     filecolors = 1;
758     return 1;
759   } else if (!strcmp(colorinput, "never")){
760     filecolors = 0;
761     return 1;
762   } else {
763     return 0;
764   }
765 }
766 
setBlockSize(const char * arg)767 int setBlockSize(const char * arg){
768     size_t numarg;
769     int returnCode = 0;
770     int multiplier = 1;
771     int power = 1;
772     int powerUnit = 1024;
773 
774     int i1 = 1;
775     signed char c1;
776     signed char e1 = 0;
777     signed char e2 = 0;
778 
779     if ( isdigit(arg[0]) ){
780       sscanf(arg, "%d%1c%1c%1c", &i1, &c1, &e1, &e2);
781     } else {
782       sscanf(arg, "%1c%1c%1c", &c1, &e1, &e2);
783     }
784 
785     if ( e1 == 66 || e1 == 98){
786       powerUnit = 1000;
787     } else if ( e1 != 0){
788       returnCode = 1;
789     }
790 
791     if ( e2 != 0 ){
792       returnCode = 1;
793     }
794 
795     // Deal with humans using lowercase
796     if ((c1 < 123) && (c1 > 96)){
797       c1 = c1 - 32;
798     }
799 
800     block_unit[0] = c1;
801     block_unit[1] = e1;
802 
803     switch (c1){
804       case 'K':
805         power = 1;
806         break;
807       case 'M':
808         power = 2;
809         break;
810       case 'G':
811         power = 3;
812         break;
813       case 'T':
814         power = 4;
815         break;
816       case 'P':
817         power = 5;
818         break;
819       case 'E':
820         power = 6;
821         break;
822       case 'Z':
823         power = 7;
824         break;
825       case 'Y':
826         power = 8;
827         break;
828       case '\0':
829         power = 0;
830         break;
831       default:
832         returnCode = 1;
833         break;
834     }
835 
836     multiplier = pow(powerUnit, power);
837 
838     numarg = i1 * multiplier;
839     if (returnCode != 1){
840       if (numarg < 1){
841         returnCode = 1;
842       } else {
843         block_size = numarg;
844         returnCode = 0;
845       }
846     }
847 
848     return returnCode;
849 }
850 
refreshScreen()851 void refreshScreen()
852 {
853   endwin();
854   clear();
855   cbreak();
856   noecho();
857   curs_set(FALSE);
858   keypad(stdscr, TRUE);
859   refresh();
860   unloadMenuLabels();
861   refreshMenuLabels();
862   switch(viewMode)
863     {
864     case 0:
865       wPrintMenu(0, 0, fileMenuLabel);
866       wPrintMenu(LINES-1, 0, functionMenuLabel);
867       resizeDisplayDir(ob);
868       break;
869     case 1:
870       wPrintMenu(0,0,globalMenuLabel);
871       wPrintMenu(LINES-1, 0, functionMenuLabel);
872       resizeDisplayDir(ob);
873       break;
874     case 2:
875       wPrintMenu(0, 0, modifyMenuLabel);
876       wPrintMenu(LINES-1, 0, functionMenuLabel);
877       resizeDisplayDir(ob);
878       break;
879     case 3:
880       wPrintMenu(0, 0, sortMenuLabel);
881       wPrintMenu(LINES-1, 0, functionMenuLabel);
882       resizeDisplayDir(ob);
883       break;
884     case 4:
885       wPrintMenu(0,0,globalMenuLabel);
886       break;
887     case 5:
888       wPrintMenu(0, 0, linkMenuLabel);
889       wPrintMenu(LINES-1, 0, functionMenuLabel);
890       resizeDisplayDir(ob);
891       break;
892     }
893 }
894 
sigwinchHandle(int sig)895 void sigwinchHandle(int sig){
896   resized = 1;
897 }
898 
printHelp(char * programName)899 void printHelp(char* programName){
900   printf (("Usage: %s [OPTION]... [FILE]...\n"), programName);
901   fputs ((PROGRAM_DESC), stdout);
902   fputs (("\n\
903 Sorts objects alphabetically if -St is not set.\n\
904 "), stdout);
905   fputs (("\n\
906 Options shared with ls:\n"), stdout);
907 #ifdef HAVE_ACL_TYPE_EXTENDED
908   fputs(("  -@                           display extended attribute keys and sizes\n"), stdout);
909 #endif
910   fputs(("  -a, --all                    do not ignore entries starting with .\n\
911       --author                 prints the author of each file\n\
912       --block-size=SIZE        scale sizes by SIZE, for example '--block-size=M'\n\
913                                  see SIZE format below\n\
914   -B, --ignore-backups         do not list implied entries ending with ~\n\
915       --color[=WHEN]           colorize the output, see the color section below\n\
916   -d, --directory              show only directories\n\
917   -f                           do not sort, enables -aU\n\
918       --full-time              display time as full-iso format\n\
919   -g                           only show group\n\
920   -G, --no-group               do not show group\n\
921   -h, --human-readable         print sizes like 1K 234M 2G etc.\n\
922       --si                     as above, but use powers of 1000 not 1024\n\
923   -r, --reverse                reverse order while sorting\n\
924   -s, --size                   display the allocated size of files, in blocks\n\
925   -S                           sort file by size, largest first\n\
926       --time-style=TIME_STYLE  time/date format, see TIME_STYLE section below\n\
927   -t                           sort by modification time, newest first\n\
928   -U                           do not sort; lists objects in directory order\n\
929   -Z, --context                show security context of each file, if any\n\
930   -1                           only show file name, one per line\n\
931       --help                   displays help message, then exits\n\
932       --version                displays version, then exits\n"), stdout);
933   fputs (("\n\
934 The SIZE agrument is an integer and optional unit (for example: 10K = 10*1024).\n\
935 The units are K,M,G,T,P,E,Z,Y (powers of 1024) or KB,MB, etc. (powers of 1000).\n"), stdout);
936   fputs (("\n\
937 The TIME_STYLE argument can be: full-iso; long-iso; iso; locale.\n"), stdout);
938   fputs (("\n\
939 Using color to highlight file attributes is disabled by default and with\n\
940 --color=never. With --color or --color=always this function is enabled.\n"), stdout);
941   fputs (("\n\
942 Options specific to show:\n\
943       --theme=[THEME]          color themes, see the THEME section below for\n\
944                                  valid themes\n\
945       --no-danger              turns off danger colors when running with\n\
946                                  elevated privileges\n\
947       --marked=[MARKED]        shows information about marked objects. See\n\
948                                  MARKED section below for valid options\n\
949       --no-sf                  does not display files in sf\n\
950       --show-on-enter          repurposes the Enter key to launch the show\n\
951                                  command\n\
952       --running                display number of parent show processes\n\
953       --settings-menu          launch settings menu\n\
954       --edit-themes            launchs directly into the theme editor\n\
955       --skip-to-first          skips navigation items if at the top of list\n"), stdout);
956   fputs (("\n\
957 The THEME argument can be:\n"), stdout);
958   listThemes();
959   fputs (("\n\
960 Exit status:\n\
961  0  if OK,\n\
962  1  if minor problems (e.g., cannot access subdirectory),\n\
963  2  if major problems (e.g., cannot access command-line arguement).\n"), stdout);
964   printf ("\nPlease report any bugs to: <%s>\n", PACKAGE_BUGREPORT);
965 }
966 
freeSettingVars()967 void freeSettingVars()
968 {
969   free(visualPath);
970   return;
971 }
972 
main(int argc,char * argv[])973 int main(int argc, char *argv[])
974 {
975   uid_t uid=getuid(), euid=geteuid();
976   int c;
977   char * tmpPwd;
978   char options[20];
979 
980 #ifdef HAVE_ACL_TYPE_EXTENDED
981   strcpy(options, "@aABdfgGhlrsStUZ1");
982 #else
983   strcpy(options, "aABdfgGhlrsStUZ1");
984 #endif
985 
986   // Setting the default editor
987 #ifdef HAVE_NANO
988   visualPath = calloc(5, sizeof(char));
989   sprintf(visualPath, "nano");
990 #elif HAVE_VIM
991   visualPath = calloc(4, sizeof(char));
992   sprintf(visualPath, "vim");
993 #elif HAVE_VI
994   visualPath = calloc(3, sizeof(char));
995   sprintf(visualPath, "vi");
996 #elif HAVE_EMACS
997   visualPath = calloc(6, sizeof(char));
998   sprintf(visualPath, "emacs");
999 #elif HAVE_JED
1000   visualPath = calloc(4, sizeof(char));
1001   sprintf(visualPath, "jed");
1002 #else
1003   visualPath = calloc(3, sizeof(char));
1004   sprintf(visualPath, "vi");
1005 #endif
1006 
1007   // Setting the default pager
1008 #ifdef HAVE_LESS
1009   pagerPath = calloc(5, sizeof(char));
1010   sprintf(pagerPath, "less");
1011 #elif HAVE_MORE
1012   pagerPath = calloc(5, sizeof(char));
1013   sprintf(pagerPath, "more");
1014 #else
1015   pagerPath = calloc(5, sizeof(char));
1016   sprintf(pagerPath, "more");
1017 #endif
1018 
1019   showProcesses = checkRunningEnv() + 1;
1020 
1021   // Set Config locations
1022   setConfLocations();
1023 
1024   // Check if we're root to display danger
1025   if (uid == 0 || euid == 0){
1026     danger = 1;
1027   }
1028 
1029   // Read the config
1030 
1031   readConfig(globalConfLocation);
1032   readConfig(homeConfLocation);
1033 
1034   // Check for theme env variable
1035   if ( getenv("DFS_THEME")) {
1036     strcpy(themeName, getenv("DFS_THEME"));
1037   }
1038 
1039   // Getting arguments
1040   while (1)
1041     {
1042       static struct option long_options[] =
1043         {
1044          {"all",            no_argument,       0, 'a'},
1045          {"almost-all",     no_argument,       0, 'A'},
1046          {"author",         no_argument,       0, GETOPT_AUTHOR_CHAR},
1047          {"block-size",     required_argument, 0, GETOPT_BLOCKSIZE_CHAR},
1048          {"ignore-backups", no_argument,       0, 'B'},
1049          {"directory",      no_argument,       0, 'd'},
1050          {"human-readable", no_argument,       0, 'h'},
1051          {"no-group",       no_argument,       0, 'G'},
1052          {"reverse",        no_argument,       0, 'r'},
1053          {"size",           no_argument,       0, 's'},
1054          {"time-style",     required_argument, 0, GETOPT_TIMESTYLE_CHAR},
1055          {"si",             no_argument,       0, GETOPT_SI_CHAR},
1056          {"help",           no_argument,       0, GETOPT_HELP_CHAR},
1057          {"version",        no_argument,       0, GETOPT_VERSION_CHAR},
1058          {"no-danger",      no_argument,       0, GETOPT_NODANGER_CHAR},
1059          {"color",          optional_argument, 0, GETOPT_COLOR_CHAR},
1060          {"theme",          optional_argument, 0, GETOPT_THEME_CHAR},
1061          {"marked",         optional_argument, 0, GETOPT_MARKED_CHAR},
1062          {"no-sf",          no_argument,       0, GETOPT_ENVPAGER_CHAR},
1063          {"show-on-enter",  no_argument,       0, GETOPT_SHOWONENTER_CHAR},
1064          {"running",        no_argument,       0, GETOPT_SHOWRUNNING_CHAR},
1065          {"full-time",      no_argument,       0, GETOPT_FULLTIME_CHAR},
1066          {"edit-themes",    no_argument,       0, GETOPT_THEMEEDIT_CHAR},
1067          {"settings-menu",  no_argument,       0, GETOPT_OPTIONSMENU_CHAR},
1068          {"contect",        no_argument,       0, 'Z'},
1069          {"skip-to-first",  no_argument,       0, GETOPT_SKIPTOFIRST_CHAR},
1070          {0, 0, 0, 0}
1071         };
1072       int option_index = 0;
1073 
1074       c = getopt_long(argc, argv, options, long_options, &option_index);
1075 
1076       if ( c == -1 ){
1077         break;
1078       }
1079 
1080     switch(c){
1081     case 'A':
1082       // Dropthrough
1083     case 'a':
1084       showhidden = 1;
1085       break;
1086     case GETOPT_AUTHOR_CHAR:
1087       ogavis = ogavis + 4;
1088       break;
1089     case GETOPT_BLOCKSIZE_CHAR:
1090       if (setBlockSize(optarg)){
1091           printf("%s: invalid argument '%s' for 'block-size'\n", argv[0], optarg);
1092           exit(2);
1093       };
1094       scaleSize = 1;
1095       break;
1096     case 'B':
1097       showbackup = 0;
1098       break;
1099     case GETOPT_COLOR_CHAR:
1100       if (optarg){
1101         if (!setColor(optarg)){
1102           printf("%s: invalid argument '%s' for 'color'\n", argv[0], optarg);
1103           fputs (("\
1104 Valid arguments are:\n\
1105   - always\n\
1106   - never\n"), stdout);
1107           printf("Try '%s --help' for more information.\n", argv[0]);
1108           exit(2);
1109         }
1110       } else {
1111         filecolors = 1;
1112         }
1113       break;
1114     case GETOPT_THEME_CHAR:
1115       if (optarg){
1116         if (strcmp(optarg, "\0")){
1117           strcpy(themeName, optarg);
1118           setenv("DFS_THEME_OVERRIDE", "TRUE", 1);
1119         }
1120       } else {
1121         printf("%s: The following themes are available:\n", argv[0]);
1122         listThemes();
1123         exit(2);
1124       }
1125       break;
1126     case 'd':
1127       dirOnly = 1;
1128       break;
1129     case 'f':
1130       strcpy(sortmode, "unsorted"); // This needs to be set to "unsorted" to allow the settings menu to render correctly.
1131       showhidden = 1;
1132       break;
1133     case 'l':
1134       break; // Allows for accidental -l from `ls` muscle memory commands. Does nothing.
1135     case 'S':
1136       strcpy(sortmode, "size");
1137       break;
1138     case 's':
1139       showSizeBlocks = 1;
1140       break;
1141     case GETOPT_TIMESTYLE_CHAR:
1142       strcpy(timestyle, optarg);
1143       if (!checkStyle(timestyle)){
1144         printf("%s: invalid argument '%s' for 'time style'\n", argv[0], timestyle);
1145         fputs (("\
1146 Valid arguments are:\n\
1147   - full-iso\n\
1148   - long-iso\n\
1149   - iso\n\
1150   - locale\n"), stdout);
1151         printf("Try '%s --help' for more information.\n", argv[0]);
1152         exit(2);
1153       }
1154       break;
1155     case GETOPT_FULLTIME_CHAR:
1156       strcpy(timestyle, "full-iso");
1157       break;
1158     case 't':
1159       strcpy(sortmode, "date");
1160       break;
1161     case 'g':
1162       ogavis--;
1163       break;
1164     case 'G':
1165       ogavis = ogavis - 2;
1166       break;
1167     case 'h':
1168       human = 1;
1169       break;
1170     case GETOPT_SI_CHAR:
1171       human = 1;
1172       si = 1;
1173       break;
1174     case 'r':
1175       reverse = 1;
1176       break;
1177     case 'U':
1178       strcpy(sortmode, "unsorted");
1179       break;
1180     case GETOPT_NODANGER_CHAR:
1181       danger = 0;
1182       break;
1183     case GETOPT_MARKED_CHAR:
1184       if (optarg){
1185         if ( setMarked(optarg) == -1 ){
1186           printf("%s: invalid argument '%s' for 'marked'\n", argv[0], optarg);
1187           fputs (("\
1188 Valid arguments are:\n\
1189   - always\n\
1190   - never\n\
1191   - auto\n"), stdout);
1192           printf("Try '%s --help' for more information.\n", argv[0]);
1193           exit(2);
1194         }
1195       }
1196       break;
1197     case GETOPT_HELP_CHAR:
1198       printHelp(argv[0]);
1199       exit(0);
1200       break;
1201     case GETOPT_VERSION_CHAR:
1202       printVersion(PROGRAM_NAME);
1203       exit(0);
1204       break;
1205     case GETOPT_ENVPAGER_CHAR:
1206       useEnvPager = 1;
1207       break;
1208     case GETOPT_SHOWONENTER_CHAR:
1209       enterAsShow = 1;
1210       break;
1211     case GETOPT_SHOWRUNNING_CHAR:
1212       if (checkRunningEnv() > 0){
1213         printf("There are currently %i running parent show application(s).\n\nUse 'exit' to return to Show.\n", checkRunningEnv());
1214         exit(0);
1215       } else {
1216         printf("There are no parent show applications currently running.\n");
1217         exit(0);
1218       }
1219       break;
1220     case GETOPT_THEMEEDIT_CHAR:
1221       launchThemeEditor = 1;
1222       break;
1223     case GETOPT_OPTIONSMENU_CHAR:
1224       launchSettingsMenu = 1;
1225       break;
1226     case 'Z':
1227       showContext = 1;
1228       break;
1229     case '1':
1230       oneLine = 1;
1231       break;
1232     case GETOPT_SKIPTOFIRST_CHAR:
1233       skipToFirstFile = 1;
1234       break;
1235     case '@':
1236       showXAttrs = 1;
1237       break;
1238     default:
1239       // abort();
1240       exit(2);
1241     }
1242   }
1243 
1244 
1245   // If all author is also requested, the padding needs adjusting.
1246   if ( ogavis == 7 ){
1247     ogapad = 2;
1248   }
1249 
1250 
1251   // Writing Menus
1252 
1253   generateDefaultMenus();
1254   set_escdelay(10);
1255 
1256   setlocale(LC_ALL, "");
1257 
1258   newterm(NULL, stderr, stdin);
1259   refreshMenuLabels();
1260 
1261   memset(&sa, 0, sizeof(struct sigaction));
1262   sa.sa_handler = sigwinchHandle;
1263   sigaction(SIGWINCH, &sa, NULL);
1264   if (!enableCtrlC){
1265     signal(SIGINT, sigintHandle);
1266   }
1267 
1268   start_color();
1269   setDefaultTheme();
1270   loadAppTheme(themeName);
1271   bkgd(COLOR_PAIR(DISPLAY_PAIR));
1272   cbreak();
1273   noecho();
1274   curs_set(FALSE); // Hide Curser (Will want to bring it back later)
1275   keypad(stdscr, TRUE);
1276 
1277 
1278   if (launchThemeEditor == 1){
1279     themeBuilder();
1280     theme_menu_inputs();
1281     exittoshell();
1282   } else if (launchSettingsMenu == 1) {
1283     settingsMenuView();
1284     exittoshell();
1285   } else {
1286     // Remaining arguments passed as working directory
1287     if (optind < argc){
1288       if (!check_first_char(argv[optind], "/")){
1289         // If the path given doesn't start with a / then assume we're dealing with a relative path.
1290         tmpPwd = malloc(sizeof(currentpwd));
1291         getcwd(tmpPwd, sizeof(currentpwd));
1292         sprintf(currentpwd, "%s/%s", tmpPwd, argv[optind]);
1293         free(tmpPwd);
1294       } else {
1295         strcpy(currentpwd, argv[optind]);
1296       }
1297       chdir(currentpwd);
1298     } else {
1299       getcwd(currentpwd, sizeof(currentpwd));
1300     }
1301 
1302     if (!check_dir(currentpwd)){
1303       invalidstart = 1;
1304       exitCode = 1;
1305       global_menu();
1306     }
1307   testSlash:
1308     if (check_last_char(currentpwd, "/") && strcmp(currentpwd, "/")){
1309       currentpwd[strlen(currentpwd) - 1] = '\0';
1310       goto testSlash;
1311     }
1312     directory_view(currentpwd);
1313   }
1314   return exitCode;
1315 }
1316