1 /*
2 * Syntax of file ~/.deco
3 *
4 * # comment
5 * pattern1 pattern2 ... patternN
6 * command
7 * pattern1 pattern2 ... patternN
8 * command
9 * ...
10 */
11
12 /*
13 * Syntax of file ./.menu
14 *
15 * # comment
16 * key1 string1
17 * command1
18 * key1 string1
19 * command1
20 * ...
21 *
22 * Keys are:
23 *
24 * a-z, A-Z, 0-9 - simple characters
25 * F1-F10 - function keys
26 */
27
28 /*
29 * Command may contain macro characters:
30 *
31 * %f - current file name
32 * %b - base name
33 * %d - directory name
34 * %c - full directory name
35 * %h - full home directory name
36 * %u - user name
37 * %g - group name
38 * %t - list of tagged files or current file name
39 * %% - symbol '%'
40 */
41
42 #include <stdlib.h>
43 #include <string.h>
44 #if HAVE_UNISTD_H
45 # include <unistd.h>
46 #endif
47 #if HAVE_FCNTL_H
48 # include <fcntl.h>
49 #endif
50 #include "dir.h"
51 #include "deco.h"
52 #include "scr.h"
53
54 #define EXSZ 64
55 #define BUFSZ 2048
56 #define STRSZ 256
57 #define EXFILE ".deco"
58 #define MENUSZ 16
59 #define UMFILE ".menu"
60 #define INITFILE ".decoini"
61 #define ULDINITFILE "/usr/lib/deco/initfile"
62 #define ULLDINITFILE "/usr/local/share/deco/initfile"
63 #define ULDUMFILE "/usr/lib/deco/menu"
64 #define ULLDUMFILE "/usr/local/share/deco/menu"
65 #define ULDEXFILE "/usr/lib/deco/profile"
66 #define ULLDEXFILE "/usr/local/share/deco/profile"
67
68 struct ex {
69 char *pat;
70 char *cmd;
71 };
72
73 struct umenu {
74 char key;
75 char hist;
76 char wait;
77 char menu;
78 char *str;
79 char *cmd;
80 char *cex;
81 };
82
83 static struct umenu um [EXSZ];
84 static nm, menuwid, menucol, menurow;
85 static struct ex ex [EXSZ];
86 static nex = -1;
87 static char *bufp;
88
skip()89 static void skip ()
90 {
91 while (*bufp==' ' || *bufp=='\t')
92 ++bufp;
93 }
94
skipln()95 static void skipln ()
96 {
97 do {
98 while (bufp && *bufp != '\n')
99 ++bufp;
100 if (! bufp)
101 return;
102 ++bufp;
103 } while (*bufp == '#');
104 }
105
getex()106 static char *getex ()
107 {
108 char pat [PATSZ];
109 char *p;
110
111 while (*bufp==' ' || *bufp=='\t' || *bufp=='\n')
112 skipln ();
113 if (! *bufp)
114 return (0);
115 for (p=pat; *bufp!=' ' && *bufp!='\t' && *bufp!='\n'; ++p, ++bufp) {
116 if (! *bufp)
117 break;
118 if (p >= pat+PATSZ-1) {
119 while (bufp && *bufp!=' ' && *bufp!='\t' && *bufp!='\n')
120 ++bufp;
121 break;
122 }
123 *p = *bufp;
124 }
125 skip ();
126 if (*bufp == '\n')
127 skipln ();
128 *p = 0;
129 p = malloc (p - pat + 1);
130 strcpy (p, pat);
131 return (p);
132 }
133
getkey()134 static int getkey ()
135 {
136 int key;
137
138 while (*bufp==' ' || *bufp=='\t' || *bufp=='\n')
139 skipln ();
140 if (! *bufp)
141 return (0);
142 if (*bufp == 'F' && bufp[1] >= '1' && bufp[1] <= '9')
143 key = bufp [1] - '0';
144 else if ((*bufp >= 'a' && *bufp <= 'z') ||
145 (*bufp >= 'A' && *bufp <= 'Z') ||
146 (*bufp >= '0' && *bufp <= '9'))
147 key = *bufp;
148 else
149 key = '?';
150 while (bufp && *bufp!=' ' && *bufp!='\t' && *bufp!='\n')
151 ++bufp;
152 skip ();
153 return (key);
154 }
155
getstr()156 static char *getstr ()
157 {
158 char cmd [STRSZ];
159 char *p;
160
161 if (! *bufp)
162 return (0);
163 for (p=cmd; *bufp!='\n'; ++p, ++bufp) {
164 if (! *bufp)
165 break;
166 if (p >= cmd+STRSZ-1) {
167 skipln ();
168 break;
169 }
170 *p = *bufp;
171 }
172 if (*bufp == '\n')
173 skipln ();
174 *p = 0;
175 p = malloc (p - cmd + 1);
176 strcpy (p, cmd);
177 return (p);
178 }
179
getcmd()180 static char *getcmd ()
181 {
182 if (*bufp!=' ' && *bufp!='\t')
183 return (0);
184 skip ();
185 return (getstr ());
186 }
187
readex()188 static void readex ()
189 {
190 register char *cp, *ep;
191
192 for (nex=0; (ep=getex()); ++nex) {
193 if (nex >= EXSZ-1)
194 break;
195 ex[nex].pat = ep;
196 if ((cp = getcmd ()))
197 ex[nex].cmd = cp;
198 }
199 while (nex>0 && ! ex[nex-1].cmd) {
200 --nex;
201 free (ex[nex].pat);
202 }
203 ex[nex].pat = 0;
204 }
205
initex()206 static void initex ()
207 {
208 register fd, n;
209 char fname [80];
210 char buf [BUFSZ];
211
212 /* look for ~/.deco */
213 strcpy (fname, home);
214 strcat (fname, "/");
215 strcat (fname, EXFILE);
216 fd = open (fname, 0);
217 if (fd < 0) {
218 /* look for /usr/local/lib/deco/profile */
219 fd = open (ULLDEXFILE, 0);
220 if (fd < 0) {
221 /* look for /usr/lib/deco/profile */
222 fd = open (ULDEXFILE, 0);
223 if (fd < 0)
224 return;
225 }
226 }
227 bufp = buf;
228 n = read (fd, buf, sizeof (buf) - 1);
229 close (fd);
230 if (n <= 0)
231 return;
232 buf [n] = 0;
233 bufp = buf;
234 if (*bufp == '#')
235 skipln ();
236
237 readex ();
238
239 for (n=nex-2; n>=0; --n)
240 if (! ex[n].cmd)
241 ex[n].cmd = ex[n+1].cmd;
242 }
243
expandtagged(char * cp)244 int expandtagged (char *cp)
245 {
246 register i, n;
247 register char *s;
248
249 for (i=n=0; i<cur->num; ++i)
250 if (cur->cat[i].tag) {
251 s = cur->cat[i].name;
252 while (*s)
253 *cp++ = *s++;
254 *cp++ = ' ';
255 ++n;
256 }
257 *cp = 0;
258 return (n);
259 }
260
expand(char * cp,char * cmd,char * fname)261 static void expand (char *cp, char *cmd, char *fname)
262 {
263 register char *s;
264
265 for (; *cmd; ++cmd) {
266 if (*cmd != '%') {
267 *cp++ = *cmd;
268 continue;
269 }
270 switch (*++cmd) {
271 default:
272 *cp++ = *cmd;
273 continue;
274 case 't': /* list of tagged files */
275 if (expandtagged (cp)) {
276 for (; *cp; ++cp);
277 continue;
278 }
279 case 'f': /* current file name */
280 s = fname;
281 break;
282 case 'b': /* base name */
283 s = basename (fname);
284 break;
285 case 'd': /* directory name */
286 s = basename (cur->cwd);
287 break;
288 case 'c': /* full directory name */
289 s = cur->cwd;
290 break;
291 case 'h': /* full home directory name */
292 s = home;
293 break;
294 case 'u': /* user name */
295 s = user;
296 break;
297 case 'g': /* group name */
298 s = group;
299 break;
300 }
301 if (! s)
302 continue;
303 while (*s)
304 *cp++ = *s++;
305 }
306 *cp = 0;
307 }
308
excommand(char * cp,char * fname)309 void excommand (char *cp, char *fname)
310 {
311 register struct ex *ep;
312
313 if (nex == -1)
314 initex ();
315 for (ep=ex; ep->pat; ++ep) {
316 if (match (fname, ep->pat)) {
317 expand (cp, ep->cmd, fname);
318 return;
319 }
320 }
321 *cp = 0;
322 }
323
freeudm()324 static void freeudm ()
325 {
326 register n;
327
328 for (n=0; n<nm; ++n) {
329 if (um[n].str)
330 free (um[n].str);
331 if (um[n].cmd)
332 free (um[n].cmd);
333 }
334 }
335
printudm()336 static void printudm ()
337 {
338 register n;
339
340 for (n=0; n<nm; ++n) {
341 VMove (menurow+n, menucol+1);
342 switch (um[n].key) {
343 case 1: VPutString ("F1"); break;
344 case 2: VPutString ("F2"); break;
345 case 3: VPutString ("F3"); break;
346 case 4: VPutString ("F4"); break;
347 case 5: VPutString ("F5"); break;
348 case 6: VPutString ("F6"); break;
349 case 7: VPutString ("F7"); break;
350 case 8: VPutString ("F8"); break;
351 case 9: VPutString ("F9"); break;
352 default: VPutChar (um[n].key); break;
353 }
354 if (um[n].menu)
355 VMPutString (menurow+n, menucol+3, "->");
356 if (um[n].str)
357 VMPutString (menurow+n, menucol+5, um[n].str);
358 }
359 }
360
openmenu(char * filename)361 static int openmenu (char *filename)
362 {
363 register fd;
364 char fname [80];
365
366 if (filename)
367 return (open (filename, 0));
368 /* look for ./.menu */
369 fd = open (UMFILE, 0);
370 if (fd < 0) {
371 /* look for ~/.menu */
372 strcpy (fname, home);
373 strcat (fname, "/");
374 strcat (fname, UMFILE);
375 fd = open (fname, 0);
376 if (fd < 0) {
377 /* look for /usr/local/lib/deco/menu */
378 fd = open (ULLDUMFILE, 0);
379 if (fd < 0)
380 /* look for /usr/lib/deco/menu */
381 fd = open (ULDUMFILE, 0);
382 }
383 }
384 return (fd);
385 }
386
initudm(char * filename,char * scale)387 static int initudm (char *filename, char *scale)
388 {
389 register n;
390 register char *p;
391 int fd;
392 char buf [BUFSZ];
393
394 fd = openmenu (filename);
395 if (fd < 0) {
396 error ("Menu not found");
397 return (0);
398 }
399 nm = 0;
400 bufp = buf;
401 n = read (fd, buf, sizeof (buf) - 1);
402 close (fd);
403 if (n <= 0) {
404 error ("Cannot read menu");
405 return (0);
406 }
407 buf [n] = 0;
408 bufp = buf;
409 if (*bufp == '#')
410 skipln ();
411
412 for (n=0; n<128; ++n)
413 scale [n] = MENUSZ+1;
414
415 menuwid = 1;
416 for (nm=0; nm<MENUSZ && (n = getkey ()); ++nm) {
417 scale [n] = nm;
418 um[nm].key = n;
419 um[nm].wait = um[nm].hist = 1;
420 um[nm].menu = 0;
421 um[nm].str = getstr ();
422 if (um[nm].str && (n = strlen (um[nm].str)) > menuwid)
423 menuwid = n;
424 um[nm].cmd = getcmd ();
425 if (um[nm].cmd) {
426 p = um[nm].cmd;
427 /* if ((n = strlen (um[nm].cmd)) > menuwid) */
428 /* menuwid = n; */
429 if (*p == '!') {
430 um[nm].menu = 1;
431 ++p;
432 }
433 if (*p == '-') {
434 um[nm].wait = 0;
435 ++p;
436 }
437 if (*p == '@') {
438 um[nm].hist = 0;
439 ++p;
440 }
441 um[nm].cex = p;
442 }
443 }
444 if (! nm) {
445 error ("Menu is empty");
446 return (0);
447 }
448 menuwid += 6;
449 if (menuwid > 70)
450 menuwid = 70;
451 menurow = (LINES-nm) / 2;
452 menucol = (79-menuwid) / 2;
453 return (1);
454 }
455
runudm(char * scale)456 static char *runudm (char *scale)
457 {
458 /* user defined menu */
459 register key, cm;
460 BOX *box, *curbox;
461
462 box = VGetBox (menurow-2, menucol-4, nm+4, menuwid+8);
463 VSetDim ();
464 VStandOut ();
465 VFillBox (menurow-2, menucol-4, nm+4, menuwid+8, ' ');
466 VDrawBox (menurow-1, menucol-1, nm+2, menuwid+2);
467 mvcaddstr (menurow-1, 40, " User Menu ");
468 printudm ();
469 VSetNormal ();
470 VStandEnd ();
471 cm = 0;
472 for (;;) {
473 curbox = VGetBox (menurow+cm, menucol, 1, menuwid);
474 VPrintBox (curbox);
475 hidecursor ();
476 VSync ();
477 key = KeyGet ();
478 VUngetBox (curbox);
479 VFreeBox (curbox);
480 switch (key) {
481 default:
482 findmenu:
483 if (key>0 && key<0200 && scale [key] < MENUSZ) {
484 cm = scale [key];
485 break;
486 }
487 VBeep ();
488 continue;
489 case meta ('A'): key = 1; goto findmenu;
490 case meta ('B'): key = 2; goto findmenu;
491 case meta ('C'): key = 3; goto findmenu;
492 case meta ('D'): key = 4; goto findmenu;
493 case meta ('E'): key = 5; goto findmenu;
494 case meta ('F'): key = 6; goto findmenu;
495 case meta ('G'): key = 7; goto findmenu;
496 case meta ('H'): key = 8; goto findmenu;
497 case meta ('I'): key = 9; goto findmenu;
498 case cntrl (']'): /* redraw screen */
499 VRedraw ();
500 continue;
501 case cntrl ('M'):
502 case cntrl ('J'):
503 break;
504 case cntrl ('C'):
505 case cntrl ('['):
506 case meta ('J'): /* f0 */
507 cm = -1;
508 break;
509 case meta ('u'): /* up */
510 if (--cm < 0)
511 cm = nm-1;
512 continue;
513 case meta ('d'): /* down */
514 if (++cm >= nm)
515 cm = 0;
516 continue;
517 }
518 break;
519 }
520 VUngetBox (box);
521 VFreeBox (box);
522 if (cm >= 0 && um[cm].cex) {
523 if (um[cm].menu)
524 return (um[cm].cex);
525 /* execute command from menu */
526 expand (command, um[cm].cex, cur->cat[cur->curfile].name);
527 cpos = strlen (command);
528 if (command [0])
529 execmd (um[cm].wait, um[cm].hist);
530 }
531 return ((char *) 0);
532 }
533
usermenu()534 void usermenu () /* user defined menu */
535 {
536 char scale [128], filename [80];
537 register char *p;
538
539 p = 0;
540 while (initudm (p, scale)) {
541 p = runudm (scale);
542 freeudm ();
543 if (! p)
544 break;
545 expand (filename, p, cur->cat[cur->curfile].name);
546 p = filename;
547 }
548 }
549
getlin()550 static char *getlin ()
551 {
552 register char *p, *s;
553
554 if (! *bufp)
555 return (0);
556 for (s=p=bufp; *p && *p != '\n'; ++p);
557 if (*p == '\n')
558 *p++ = 0;
559 bufp = p;
560 return (s);
561 }
562
readinitfile()563 void readinitfile ()
564 {
565 register fd, n;
566 register char *line;
567 struct dir *d;
568 char fname [80];
569 char buf [BUFSZ];
570
571 /* look for ~/.decoini */
572 strcpy (fname, home);
573 strcat (fname, "/");
574 strcat (fname, INITFILE);
575 fd = open (fname, 0);
576 if (fd < 0) {
577 /* look for /usr/local/lib/deco/initfile */
578 fd = open (ULLDINITFILE, 0);
579 if (fd < 0) {
580 /* look for /usr/lib/deco/initfile */
581 fd = open (ULDINITFILE, 0);
582 if (fd < 0)
583 return;
584 }
585 }
586 bufp = buf;
587 n = read (fd, buf, sizeof (buf) - 1);
588 close (fd);
589 if (n <= 0)
590 return;
591 buf [n] = 0;
592 bufp = buf;
593
594 while ((line = getlin ())) {
595 switch (line [0]) {
596 case 'r': /* right panel */
597 d = &right;
598 goto initdir;
599 case 'l': /* left panel */
600 d = &left;
601 initdir:
602 switch (line [1]) {
603 case 'o': /* Sort */
604 switch (line [2]) {
605 case 'n': d->sort = SORTNAME; break;
606 case 'x': d->sort = SORTEXT; break;
607 case 't': d->sort = SORTTIME; break;
608 case 'z': d->sort = SORTSIZE; break;
609 case 'u': d->sort = SORTSKIP; break;
610 }
611 break;
612 case 'l': /* Long */
613 d->view = VIEW_LONG;
614 break;
615 case 'w': /* Wide */
616 d->view = VIEW_WIDE;
617 break;
618 case 'f': /* Full */
619 d->view = VIEW_FULL;
620 break;
621 case 'i': /* Info */
622 d->view = VIEW_INFO;
623 break;
624 case 's': /* Status */
625 d->status = 1;
626 break;
627 case 'p': /* pattern */
628 strcpy (d->pattern, line+2);
629 break;
630 case 'a': /* not align extensions */
631 d->alignext = 0;
632 break;
633 case 't': /* no type sorting */
634 d->typesort = 0;
635 break;
636 case 'r': /* reverse sorting */
637 d->revsort = 1;
638 break;
639 }
640 break;
641 case 'c': /* use cshell */
642 usecshell = 1;
643 break;
644 case 'f': /* full screen */
645 H = LINES-7;
646 break;
647 case 'w': /* double width */
648 widewin = 1;
649 break;
650 case 'h': /* show hidden files */
651 showhidden ^= 1;
652 break;
653 case 'v': /* viewer */
654 switch (line [1]) {
655 case 'b': /* built-in */
656 userview = 1;
657 break;
658 case 'n': /* name */
659 strcpy (viewname, line+2);
660 break;
661 }
662 break;
663 case 'e': /* editor */
664 switch (line [1]) {
665 case 'b': /* built-in */
666 useredit = 1;
667 break;
668 case 'n': /* name */
669 strcpy (editname, line+2);
670 break;
671 case 'r': /* raw */
672 viewraw = 1;
673 break;
674 case 'h': /* hex */
675 viewhex = 1;
676 break;
677 case 't': /* tabs */
678 viewtabs = 1;
679 break;
680 }
681 break;
682 case 'p': /* palette */
683 switch (line [1]) {
684 case 'n': /* normal */
685 switch (line [2]) {
686 case 'f': /* foreground */
687 palette.fg = strtol (line+3, 0, 0);
688 dflt_palette.fg = -1;
689 break;
690 case 'b': /* background */
691 palette.bg = strtol (line+3, 0, 0);
692 dflt_palette.bg = -1;
693 break;
694 case 'r': /* reverse */
695 switch (line [3]) {
696 case 'f': /* foreground */
697 palette.revfg = strtol (line+4, 0, 0);
698 dflt_palette.revfg = -1;
699 break;
700 case 'b': /* background */
701 palette.revbg = strtol (line+4, 0, 0);
702 dflt_palette.revbg = -1;
703 break;
704 }
705 break;
706 }
707 break;
708 case 'b': /* bold */
709 switch (line [2]) {
710 case 'f': /* foreground */
711 palette.boldfg = strtol (line+3, 0, 0);
712 dflt_palette.boldfg = -1;
713 break;
714 case 'b': /* background */
715 palette.boldbg = strtol (line+3, 0, 0);
716 dflt_palette.boldbg = -1;
717 break;
718 case 'r': /* reverse */
719 switch (line [3]) {
720 case 'f': /* foreground */
721 palette.boldrevfg = strtol (line+4, 0, 0);
722 dflt_palette.boldrevfg = -1;
723 break;
724 case 'b': /* background */
725 palette.boldrevbg = strtol (line+4, 0, 0);
726 dflt_palette.boldrevbg = -1;
727 break;
728 }
729 break;
730 }
731 break;
732 case 'd': /* dim */
733 switch (line [2]) {
734 case 'f': /* foreground */
735 palette.dimfg = strtol (line+3, 0, 0);
736 dflt_palette.dimfg = -1;
737 break;
738 case 'b': /* background */
739 palette.dimbg = strtol (line+3, 0, 0);
740 dflt_palette.dimbg = -1;
741 break;
742 case 'r': /* reverse */
743 switch (line [3]) {
744 case 'f': /* foreground */
745 palette.dimrevfg = strtol (line+4, 0, 0);
746 dflt_palette.dimrevfg = -1;
747 break;
748 case 'b': /* background */
749 palette.dimrevbg = strtol (line+4, 0, 0);
750 dflt_palette.dimrevbg = -1;
751 break;
752 }
753 break;
754 }
755 break;
756 }
757 break;
758 }
759 }
760 }
761
writeinitfile()762 void writeinitfile ()
763 {
764 register fd;
765 char fname [80];
766 char buf [BUFSZ];
767
768 /* look for ~/.decoini */
769 strcpy (fname, home);
770 strcat (fname, "/");
771 strcat (fname, INITFILE);
772 fd = creat (fname, 0600);
773 if (fd < 0) {
774 error ("Cannot create %s", fname);
775 return;
776 }
777 bufp = buf;
778
779 if (left.view == VIEW_LONG)
780 *bufp++ = 'l', *bufp++ = 'l', *bufp++ = '\n';
781 else if (left.view == VIEW_WIDE)
782 *bufp++ = 'l', *bufp++ = 'w', *bufp++ = '\n';
783 else if (left.view == VIEW_FULL)
784 *bufp++ = 'l', *bufp++ = 'f', *bufp++ = '\n';
785 else if (left.view == VIEW_INFO)
786 *bufp++ = 'l', *bufp++ = 'i', *bufp++ = '\n';
787 if (right.view == VIEW_LONG)
788 *bufp++ = 'r', *bufp++ = 'l', *bufp++ = '\n';
789 else if (right.view == VIEW_WIDE)
790 *bufp++ = 'r', *bufp++ = 'w', *bufp++ = '\n';
791 else if (right.view == VIEW_FULL)
792 *bufp++ = 'r', *bufp++ = 'f', *bufp++ = '\n';
793 else if (right.view == VIEW_INFO)
794 *bufp++ = 'r', *bufp++ = 'i', *bufp++ = '\n';
795 if (left.status)
796 *bufp++ = 'l', *bufp++ = 's', *bufp++ = '\n';
797 if (right.status)
798 *bufp++ = 'r', *bufp++ = 's', *bufp++ = '\n';
799 switch (left.sort) {
800 case SORTEXT: break;
801 case SORTNAME: *bufp++ = 'l'; *bufp++ = 'o'; *bufp++ = 'n'; *bufp++ = '\n'; break;
802 case SORTTIME: *bufp++ = 'l'; *bufp++ = 'o'; *bufp++ = 't'; *bufp++ = '\n'; break;
803 case SORTSIZE: *bufp++ = 'l'; *bufp++ = 'o'; *bufp++ = 'z'; *bufp++ = '\n'; break;
804 default: *bufp++ = 'l'; *bufp++ = 'o'; *bufp++ = 'u'; *bufp++ = '\n'; break;
805 }
806 switch (right.sort) {
807 case SORTEXT: break;
808 case SORTNAME: *bufp++ = 'r'; *bufp++ = 'o'; *bufp++ = 'n'; *bufp++ = '\n'; break;
809 case SORTTIME: *bufp++ = 'r'; *bufp++ = 'o'; *bufp++ = 't'; *bufp++ = '\n'; break;
810 case SORTSIZE: *bufp++ = 'r'; *bufp++ = 'o'; *bufp++ = 'z'; *bufp++ = '\n'; break;
811 default: *bufp++ = 'r'; *bufp++ = 'o'; *bufp++ = 'u'; *bufp++ = '\n'; break;
812 }
813 if (left.pattern [0]) {
814 *bufp++ = 'l';
815 *bufp++ = 'p';
816 strcpy (bufp, left.pattern);
817 while (*bufp++);
818 bufp [-1] = '\n';
819 }
820 if (right.pattern [0]) {
821 *bufp++ = 'r';
822 *bufp++ = 'p';
823 strcpy (bufp, right.pattern);
824 while (*bufp++);
825 bufp [-1] = '\n';
826 }
827 if (usecshell)
828 *bufp++ = 'c', *bufp++ = '\n';
829 if (H == LINES-7)
830 *bufp++ = 'f', *bufp++ = '\n';
831 if (widewin)
832 *bufp++ = 'w', *bufp++ = '\n';
833 if (! showhidden)
834 *bufp++ = 'h', *bufp++ = '\n';
835 if (viewraw)
836 *bufp++ = 'e', *bufp++ = 'r', *bufp++ = '\n';
837 if (viewhex)
838 *bufp++ = 'e', *bufp++ = 'h', *bufp++ = '\n';
839 if (viewtabs)
840 *bufp++ = 'e', *bufp++ = 't', *bufp++ = '\n';
841 if (userview)
842 *bufp++ = 'v', *bufp++ = 'b', *bufp++ = '\n';
843 if (useredit)
844 *bufp++ = 'e', *bufp++ = 'b', *bufp++ = '\n';
845 if (! left.alignext)
846 *bufp++ = 'l', *bufp++ = 'a', *bufp++ = '\n';
847 if (! right.alignext)
848 *bufp++ = 'r', *bufp++ = 'a', *bufp++ = '\n';
849 if (! left.typesort)
850 *bufp++ = 'l', *bufp++ = 't', *bufp++ = '\n';
851 if (! right.typesort)
852 *bufp++ = 'r', *bufp++ = 't', *bufp++ = '\n';
853 if (left.revsort)
854 *bufp++ = 'l', *bufp++ = 'r', *bufp++ = '\n';
855 if (right.revsort)
856 *bufp++ = 'r', *bufp++ = 'r', *bufp++ = '\n';
857 if (viewname [0]) {
858 *bufp++ = 'v';
859 *bufp++ = 'n';
860 strcpy (bufp, viewname);
861 while (*bufp++);
862 bufp [-1] = '\n';
863 }
864 if (editname [0]) {
865 *bufp++ = 'e';
866 *bufp++ = 'n';
867 strcpy (bufp, editname);
868 while (*bufp++);
869 bufp [-1] = '\n';
870 }
871
872 if (palette.fg != dflt_palette.fg) {
873 *bufp++ = 'p';
874 *bufp++ = 'n';
875 *bufp++ = 'f';
876 *bufp++ = '0' + palette.fg / 10;
877 *bufp++ = '0' + palette.fg % 10;
878 *bufp++ = '\n';
879 }
880 if (palette.bg != dflt_palette.bg) {
881 *bufp++ = 'p';
882 *bufp++ = 'n';
883 *bufp++ = 'b';
884 *bufp++ = '0' + palette.bg / 10;
885 *bufp++ = '0' + palette.bg % 10;
886 *bufp++ = '\n';
887 }
888 if (palette.revfg != dflt_palette.revfg) {
889 *bufp++ = 'p';
890 *bufp++ = 'n';
891 *bufp++ = 'r';
892 *bufp++ = 'f';
893 *bufp++ = '0' + palette.revfg / 10;
894 *bufp++ = '0' + palette.revfg % 10;
895 *bufp++ = '\n';
896 }
897 if (palette.revbg != dflt_palette.revbg) {
898 *bufp++ = 'p';
899 *bufp++ = 'n';
900 *bufp++ = 'r';
901 *bufp++ = 'b';
902 *bufp++ = '0' + palette.revbg / 10;
903 *bufp++ = '0' + palette.revbg % 10;
904 *bufp++ = '\n';
905 }
906
907 if (palette.boldfg != dflt_palette.boldfg) {
908 *bufp++ = 'p';
909 *bufp++ = 'b';
910 *bufp++ = 'f';
911 *bufp++ = '0' + palette.boldfg / 10;
912 *bufp++ = '0' + palette.boldfg % 10;
913 *bufp++ = '\n';
914 }
915 if (palette.boldbg != dflt_palette.boldbg) {
916 *bufp++ = 'p';
917 *bufp++ = 'b';
918 *bufp++ = 'b';
919 *bufp++ = '0' + palette.boldbg / 10;
920 *bufp++ = '0' + palette.boldbg % 10;
921 *bufp++ = '\n';
922 }
923 if (palette.boldrevfg != dflt_palette.boldrevfg) {
924 *bufp++ = 'p';
925 *bufp++ = 'b';
926 *bufp++ = 'r';
927 *bufp++ = 'f';
928 *bufp++ = '0' + palette.boldrevfg / 10;
929 *bufp++ = '0' + palette.boldrevfg % 10;
930 *bufp++ = '\n';
931 }
932 if (palette.boldrevbg != dflt_palette.boldrevbg) {
933 *bufp++ = 'p';
934 *bufp++ = 'b';
935 *bufp++ = 'r';
936 *bufp++ = 'b';
937 *bufp++ = '0' + palette.boldrevbg / 10;
938 *bufp++ = '0' + palette.boldrevbg % 10;
939 *bufp++ = '\n';
940 }
941
942 if (palette.dimfg != dflt_palette.dimfg) {
943 *bufp++ = 'p';
944 *bufp++ = 'd';
945 *bufp++ = 'f';
946 *bufp++ = '0' + palette.dimfg / 10;
947 *bufp++ = '0' + palette.dimfg % 10;
948 *bufp++ = '\n';
949 }
950 if (palette.dimbg != dflt_palette.dimbg) {
951 *bufp++ = 'p';
952 *bufp++ = 'd';
953 *bufp++ = 'b';
954 *bufp++ = '0' + palette.dimbg / 10;
955 *bufp++ = '0' + palette.dimbg % 10;
956 *bufp++ = '\n';
957 }
958 if (palette.dimrevfg != dflt_palette.dimrevfg) {
959 *bufp++ = 'p';
960 *bufp++ = 'd';
961 *bufp++ = 'r';
962 *bufp++ = 'f';
963 *bufp++ = '0' + palette.dimrevfg / 10;
964 *bufp++ = '0' + palette.dimrevfg % 10;
965 *bufp++ = '\n';
966 }
967 if (palette.dimrevbg != dflt_palette.dimrevbg) {
968 *bufp++ = 'p';
969 *bufp++ = 'd';
970 *bufp++ = 'r';
971 *bufp++ = 'b';
972 *bufp++ = '0' + palette.dimrevbg / 10;
973 *bufp++ = '0' + palette.dimrevbg % 10;
974 *bufp++ = '\n';
975 }
976
977 message (" Setup ", "Saving setup in %s ...", fname);
978 write (fd, buf, (unsigned) (bufp - buf));
979 close (fd);
980 endmesg ();
981 }
982