1 /* TomeNET account editor - evileye */
2 /* Quick account editor for server admin
3 It can be made more visually attractive later maybe.
4 I just didn't want to leave accounts unchangeable
5 while testing. */
6
7 #define HAVE_CRYPT 1
8
9 #include <curses.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <ctype.h>
13 #include <fcntl.h>
14 #include <unistd.h>
15 #include <errno.h>
16 #include <sys/file.h>
17
18 #include "account.h"
19
20 #ifndef MIN
21 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
22 #endif
23
24 static char *t_crypt(char *inbuf, const char *salt);
25
26 void editor(void);
27 void edit(void);
28 unsigned short ask(char *prompt);
29 void status(char *info);
30 void setupscreen(void);
31 unsigned short recwrite(struct account *rec, long filepos);
32 int ListAccounts(int fpos);
33 void statinput(char *prompt, char *string, int max);
34 void getstring(const char *prompt, char *string, int max);
35 int findacc(void);
36 void purge_duplicates(void);
37
38 FILE *fp;
39 WINDOW *listwin, *mainwin;
40
41 char *fname = "tomenet.acc";
42 char newpass[20];
43 char *crypass;
44
45 int tfpos;
46
main()47 int main() {
48 fp = fopen(fname, "rb");
49 if (fp == (FILE*)NULL) {
50 fprintf(stderr, "Cannot open %s\n", fname);
51 exit(20);
52 }
53 editor();
54 fclose(fp);
55 return(0);
56 }
57
setupscreen()58 void setupscreen() {
59 attron(A_STANDOUT);
60 move(0, 0);
61 clrtoeol();
62 mvprintw(0, COLS / 2 - 18, "TomeNET account editor - 2002 Evileye");
63 mvprintw(1, COLS / 2 - 16, "(Updated by Mikaelh and C. Blue)");
64 attroff(A_STANDOUT);
65 mvprintw(LINES - 3, COLS / 2 - 19, "N: next P: previous D: Delete");
66 mvprintw(LINES - 4, COLS / 2 - 19, "V: Validate A: Admin S: Score M: Multi");
67 mvprintw(LINES - 5, COLS / 2 - 19, "L: List/Long F: Find");
68 mainwin = newwin(LINES - 9, COLS, 3, 0);
69 listwin = newwin(LINES - 9, COLS, 3, 0);
70 refresh();
71 }
72
recwrite(struct account * rec,long filepos)73 unsigned short recwrite(struct account *rec, long filepos) {
74 int wfd;
75 #ifdef NETBSD
76 wfd = open("tomenet.acc", O_RDWR|O_EXLOCK); /* blocked open */
77 #else
78 wfd = open("tomenet.acc", O_RDWR);
79 #endif
80 if (wfd < 0) return(0);
81 #ifndef NETBSD
82 if ((flock(wfd, LOCK_EX)) != 0) return(0);
83 #endif
84 lseek(wfd, filepos, SEEK_SET);
85 if (write(wfd, rec, sizeof(struct account)) == -1)
86 fprintf(stderr, "write error occurred.");
87 #ifndef NETBSD
88 while((flock(wfd, LOCK_UN)) != 0);
89 #endif
90 close(wfd);
91 #ifdef NETBSD
92 fpurge(fp);
93 #else
94 fflush(fp);
95 #endif
96 fseek(fp, filepos + sizeof(struct account), SEEK_SET);
97 return(1);
98 }
99
100 /* short form list editor */
ListAccounts(int fpos)101 int ListAccounts(int fpos) {
102 int quit = 0;
103 char ch;
104 int ifpos = 0; /* internal file (LIST TOP) position */
105 int i = 0, x;
106 short reload = 1;
107 short redraw = 0;
108 struct account c_acc;
109 unsigned short change = 0;
110
111 touchwin(listwin);
112 mvwaddstr(listwin, 0, 5, "Name");
113 mvwaddstr(listwin, 0, 27, "Val");
114 mvwaddstr(listwin, 0, 31, "Adm");
115 mvwaddstr(listwin, 0, 35, "Sco");
116 mvwaddstr(listwin, 0, 39, "Mul");
117 mvwaddstr(listwin, 0, 43, "Res");
118 mvwaddstr(listwin, 0, 47, "Pri");
119 mvwaddstr(listwin, 0, 51, "PK");
120 mvwaddstr(listwin, 0, 55, "Qui");
121 mvwaddstr(listwin, 0, 59, "Ban");
122 mvwaddstr(listwin, 0, 64, "Account ID");
123 if (fpos > LINES-11) {
124 ifpos = fpos - (LINES - 11);
125 }
126 while (!quit) {
127 if (reload) {
128 fseek(fp, ifpos*sizeof(struct account), SEEK_SET);
129 for (i = 0; i < (LINES - 10); i++) {
130 x = fread(&c_acc, sizeof(struct account), 1, fp);
131 if (x == 0) break;
132 mvwprintw(listwin, i+1, 5, "%-22s%-4c%-4c%-4c%-4c%-4c%-4c%-4c%-4c%-4c%.10d%10s", c_acc.name,
133 c_acc.flags & ACC_TRIAL ? '.' : 'Y',
134 c_acc.flags & ACC_ADMIN ? 'Y' : '.',
135 c_acc.flags & ACC_NOSCORE ? '.' : 'Y',
136 c_acc.flags & ACC_MULTI ? 'Y' : '.',
137 c_acc.flags & ACC_VRESTRICTED ? 'V' : c_acc.flags & ACC_RESTRICTED ? 'Y' : '.',
138 c_acc.flags & ACC_VPRIVILEGED ? 'V' : c_acc.flags & ACC_PRIVILEGED ? 'Y' : '.',
139 c_acc.flags & ACC_PVP ? 'Y' : c_acc.flags & ACC_ANOPVP ? 'K' : c_acc.flags & ACC_NOPVP ? 'N' : '.',
140 c_acc.flags & ACC_VQUIET ? 'V' : c_acc.flags & ACC_QUIET ? 'Y' : '.',
141 c_acc.flags & ACC_BANNED ? 'Y' : '.',
142 c_acc.id, c_acc.flags & ACC_DELD ? "DELETED" : "");
143 }
144 reload = 0;
145 redraw = 1;
146 }
147 if (!change) {
148 fseek(fp, fpos*sizeof(struct account), SEEK_SET);
149 x = fread(&c_acc, sizeof(struct account), 1, fp);
150 }
151 if (redraw) {
152 mvwprintw(listwin, (fpos - ifpos) + 1, 5, "%-22s%-4c%-4c%-4c%-4c%-4c%-4c%-4c%-4c%-4c%.10d%10s", c_acc.name,
153 c_acc.flags & ACC_TRIAL ? '.' : 'Y',
154 c_acc.flags & ACC_ADMIN ? 'Y' : '.',
155 c_acc.flags & ACC_NOSCORE ? '.' : 'Y',
156 c_acc.flags & ACC_MULTI ? 'Y' : '.',
157 c_acc.flags & ACC_VRESTRICTED ? 'V' : c_acc.flags & ACC_RESTRICTED ? 'Y' : '.',
158 c_acc.flags & ACC_VPRIVILEGED ? 'V' : c_acc.flags & ACC_PRIVILEGED ? 'Y' : '.',
159 c_acc.flags & ACC_PVP ? 'Y' : c_acc.flags & ACC_ANOPVP ? 'K' : c_acc.flags & ACC_NOPVP ? 'N' : '.',
160 c_acc.flags & ACC_VQUIET ? 'V' : c_acc.flags & ACC_QUIET ? 'Y' : '.',
161 c_acc.flags & ACC_BANNED ? 'Y' : '.',
162 c_acc.id, c_acc.flags & ACC_DELD ? "DELETED" : "");
163 redraw = 0;
164 }
165 mvwaddch(listwin, (fpos - ifpos) + 1, 3, '>');
166 wrefresh(listwin);
167 ch = getch();
168 move(LINES - 1, 0);
169 clrtoeol();
170 switch (ch) {
171 case 'h':
172 case 'H':
173 getstring("New password: ", newpass, 20);
174 crypass = t_crypt(newpass, c_acc.name);
175 strncpy(c_acc.pass, crypass, 19);
176 change = 1;
177 break;
178 case 'l':
179 case 'L':
180 quit = 1;
181 break;
182 case 'f':
183 case 'F':
184 mvwaddch(listwin, (fpos - ifpos) + 1, 3, ' ');
185 if (change)
186 if (ask("This record was changed. Save?")){
187 if (recwrite(&c_acc, fpos * sizeof(struct account)))
188 change = 0;
189 else {
190 if (!ask("Could not write record. Continue anyway?"))
191 break;
192 }
193 }
194 tfpos = findacc();
195 if (tfpos >= 0) {
196 fpos = tfpos;
197 change = 0;
198 if (fpos > ifpos + (LINES - 11))
199 ifpos = fpos - (LINES - 11);
200 else if (fpos < ifpos)
201 ifpos = fpos;
202 reload = 1;
203 }
204 break;
205 case 'n':
206 case 'N':
207 if (change)
208 if (ask("This record was changed. Save?")) {
209 if (recwrite(&c_acc, fpos * sizeof(struct account)))
210 change = 0;
211 else {
212 if (!ask("Could not write record. Continue anyway?"))
213 break;
214 }
215 }
216 mvwaddch(listwin, (fpos - ifpos) + 1, 3, ' ');
217 if ((fpos - ifpos) < (i - 1)) {
218 fpos++;
219 change = 0;
220 } else {
221 if (i < (LINES - 11)) {
222 status("There are no more records");
223 break;
224 }
225 x = fread(&c_acc, sizeof(struct account), 1, fp);
226 if (x == 0)
227 status("There are no more records");
228 else {
229 ifpos++;
230 fpos++;
231 change = 0;
232 reload = 1;
233 }
234 }
235 break;
236 case 'p':
237 case 'P':
238 if (change)
239 if (ask("This record was changed. Save?")) {
240 if (recwrite(&c_acc, fpos * sizeof(struct account)))
241 change = 0;
242 else {
243 if (!ask("Could not write record. Continue anyway?"))
244 break;
245 }
246 }
247 mvwaddch(listwin, (fpos - ifpos) + 1, 3, ' ');
248 if (fpos > ifpos) {
249 fpos--;
250 change = 0;
251 } else {
252 if (ifpos > 0) {
253 ifpos--;
254 fpos--;
255 change = 0;
256 reload = 1;
257 }
258 else
259 status("This is the first record");
260 }
261 break;
262 case 'q':
263 case 'Q':
264 if(ask("Are you sure you want to quit?")){
265 quit = 1;
266 fpos = -1;
267 }
268 break;
269 case 'v':
270 case 'V':
271 change = 1;
272 redraw = 1;
273 c_acc.flags ^= ACC_TRIAL;
274 break;
275 case 'a':
276 case 'A':
277 change = 1;
278 redraw = 1;
279 c_acc.flags ^= ACC_ADMIN;
280 break;
281 case 'm':
282 case 'M':
283 change = 1;
284 redraw = 1;
285 c_acc.flags ^= ACC_MULTI;
286 break;
287 case 's':
288 case 'S':
289 change = 1;
290 redraw = 1;
291 c_acc.flags ^= ACC_NOSCORE;
292 break;
293 case 'c':
294 case 'C':
295 change = 1;
296 if (c_acc.flags & ACC_VQUIET) {
297 c_acc.flags &= ~(ACC_VQUIET | ACC_QUIET);
298 } else if (c_acc.flags & ACC_QUIET) {
299 c_acc.flags &= ~ACC_QUIET;
300 c_acc.flags |= ACC_VQUIET;
301 } else {
302 c_acc.flags |= ACC_QUIET;
303 }
304 break;
305 case 'b':
306 case 'B':
307 change = 1;
308 c_acc.flags ^= ACC_BANNED;
309 break;
310 case 'k':
311 case 'K':
312 change = 1;
313 if (c_acc.flags & ACC_ANOPVP) {
314 c_acc.flags &= ~(ACC_ANOPVP | ACC_NOPVP);
315 } else if (c_acc.flags & ACC_NOPVP) {
316 c_acc.flags &= ~ACC_NOPVP;
317 c_acc.flags |= ACC_ANOPVP;
318 } else if (c_acc.flags & ACC_PVP) {
319 c_acc.flags &= ~ACC_PVP;
320 c_acc.flags |= ACC_NOPVP;
321 } else {
322 c_acc.flags |= ACC_PVP;
323 }
324 break;
325 case 'r':
326 case 'R':
327 change = 1;
328 if (c_acc.flags & ACC_VRESTRICTED) {
329 c_acc.flags &= ~(ACC_VRESTRICTED | ACC_RESTRICTED);
330 } else if (c_acc.flags & ACC_RESTRICTED) {
331 c_acc.flags &= ~ACC_RESTRICTED;
332 c_acc.flags |= ACC_VRESTRICTED;
333 } else {
334 c_acc.flags |= ACC_RESTRICTED;
335 }
336 break;
337 case 'i':
338 case 'I':
339 change = 1;
340 if (c_acc.flags & ACC_VPRIVILEGED) {
341 c_acc.flags &= ~(ACC_VPRIVILEGED | ACC_PRIVILEGED);
342 } else if (c_acc.flags & ACC_PRIVILEGED) {
343 c_acc.flags &= ~ACC_PRIVILEGED;
344 c_acc.flags |= ACC_VPRIVILEGED;
345 } else {
346 c_acc.flags |= ACC_PRIVILEGED;
347 }
348 break;
349 case 'U':
350 purge_duplicates();
351 break;
352 default:
353 beep();
354 }
355 }
356 mvwaddch(listwin, (fpos - ifpos) + 1, 3, ' ');
357 return(fpos);
358 }
359
editor()360 void editor() {
361 int x;
362 int quit = 0;
363 char ch;
364 unsigned long fpos = 0;
365 struct account c_acc;
366 unsigned short change = 0;
367
368 x = fread(&c_acc, sizeof(struct account), 1, fp);
369 if (!x) {
370 printf("Cannot read from file\n");
371 return;
372 }
373
374 initscr();
375 cbreak();
376 noecho();
377 setupscreen();
378
379 while (!quit) {
380 mvwprintw(mainwin, 0, 4, "%-30s ID: %.10d", c_acc.name, c_acc.id);
381 mvwprintw(mainwin, 1, 4, "%-20s (%-30s)", c_acc.pass, c_acc.name_normalised);
382 mvwprintw(mainwin, 3, 4, "Trial (inval): %-4s", c_acc.flags & ACC_TRIAL ? "Yes " : "No ");
383 mvwprintw(mainwin, 4, 4, "Administrator: %-4s", c_acc.flags & ACC_ADMIN ? "*** Yes *** " : "No ");
384 mvwprintw(mainwin, 5, 4, "Scoreboard: %-4s", c_acc.flags & ACC_NOSCORE ? "No " : "Yes ");
385 mvwprintw(mainwin, 6, 4, "Multi-login: %-4s", c_acc.flags & ACC_MULTI ? "Yes " : "No ");
386 mvwprintw(mainwin, 7, 4, "Restricted: %-4s", c_acc.flags & ACC_VRESTRICTED ? "Very" : c_acc.flags & ACC_RESTRICTED ? "Yes " : "No ");
387 mvwprintw(mainwin, 8, 4, "Privileged: %-3s", c_acc.flags & ACC_VPRIVILEGED ? "Very" : c_acc.flags & ACC_PRIVILEGED ? "Yes " : "No ");
388 mvwprintw(mainwin, 9, 4, "May pkill: %-3s", c_acc.flags & ACC_PVP ? "Yes " : c_acc.flags & ACC_ANOPVP ? "_NO_" : c_acc.flags & ACC_NOPVP ? "No " : "std.");
389 mvwprintw(mainwin, 10, 4, "Muted chat: %-3s", c_acc.flags & ACC_VQUIET ? "Very" : c_acc.flags & ACC_QUIET ? "Yes " : "No ");
390 mvwprintw(mainwin, 11, 4, "Banned: %-3s", c_acc.flags & ACC_BANNED ? "** Yes ** " : "No ");
391 mvwprintw(mainwin, 3, 37, "%-7s", c_acc.flags & ACC_DELD ? "DELETED" : "");
392 wrefresh(mainwin);
393 do {
394 ch = getch();
395 move(LINES - 1, 0);
396 clrtoeol();
397 switch (ch) {
398 case 'h':
399 case 'H':
400 getstring("New password: ", newpass, 20);
401 crypass = t_crypt(newpass, c_acc.name);
402 strncpy(c_acc.pass, crypass, 19);
403 change = 1;
404 break;
405 case 'Q':
406 case 'q':
407 if (ask("Are you sure you want to quit?")){
408 if (change)
409 if (ask("This record was changed. Save?")){
410 recwrite(&c_acc, fpos * sizeof(struct account));
411 }
412 quit = 1;
413 }
414 break;
415 case 'l':
416 case 'L':
417 /* Short list of accounts */
418 fpos = ListAccounts(fpos);
419 if (fpos == (unsigned long) - 1){
420 quit = 1;
421 break;
422 }
423
424 fseek(fp, fpos * sizeof(struct account), SEEK_SET);
425 x = fread(&c_acc, sizeof(struct account),1, fp);
426 change = 0;
427 touchwin(mainwin);
428 continue;
429 break;
430 case 'f':
431 case 'F':
432 if (change)
433 if (ask("This record was changed. Save?")) {
434 if (recwrite(&c_acc, fpos * sizeof(struct account)))
435 change = 0;
436 else {
437 if (!ask("Could not write record. Continue anyway?"))
438 break;
439 }
440 }
441 tfpos = findacc();
442 if (tfpos >= 0) {
443 fpos = tfpos;
444 change = 0;
445 fseek(fp, fpos * sizeof(struct account), SEEK_SET);
446 x = fread(&c_acc, sizeof(struct account),1, fp);
447 }
448 break;
449 case 'n':
450 case 'N':
451 if (change)
452 if (ask("This record was changed. Save?")){
453 if (recwrite(&c_acc, fpos * sizeof(struct account)))
454 change = 0;
455 else {
456 if (!ask("Could not write record. Continue anyway?"))
457 break;
458 }
459 }
460 x = fread(&c_acc, sizeof(struct account),1, fp);
461 if (!x) {
462 status("No more records to edit.");
463 beep();
464 break;
465 }
466 fpos++;
467 change = 0;
468 break;
469 case 'p':
470 case 'P':
471 if (change)
472 if (ask("This record was changed. Save?")){
473 if (recwrite(&c_acc, fpos * sizeof(struct account)))
474 change = 0;
475 else {
476 if (!ask("Could not write record. Continue anyway?"))
477 break;
478 }
479 }
480 if (!fpos) {
481 status("This is the first record");
482 break;
483 }
484 fpos--;
485 fseek(fp, fpos * sizeof(struct account), SEEK_SET);
486 x = fread(&c_acc, sizeof(struct account),1, fp);
487 change = 0;
488 break;
489 case 'D':
490 if (ask("Are you sure you wish to delete this record?")){
491 change = 1;
492 c_acc.flags |= ACC_DELD;
493 }
494 break;
495 case 'v':
496 case 'V':
497 change = 1;
498 c_acc.flags ^= ACC_TRIAL;
499 break;
500 case 'a':
501 case 'A':
502 change = 1;
503 c_acc.flags ^= ACC_ADMIN;
504 break;
505 case 'm':
506 case 'M':
507 change = 1;
508 c_acc.flags ^= ACC_MULTI;
509 break;
510 case 's':
511 case 'S':
512 change = 1;
513 c_acc.flags ^= ACC_NOSCORE;
514 break;
515 case 'c':
516 case 'C':
517 change = 1;
518 if (c_acc.flags & ACC_VQUIET) {
519 c_acc.flags &= ~(ACC_VQUIET | ACC_QUIET);
520 } else if (c_acc.flags & ACC_QUIET) {
521 c_acc.flags &= ~ACC_QUIET;
522 c_acc.flags |= ACC_VQUIET;
523 } else {
524 c_acc.flags |= ACC_QUIET;
525 }
526 break;
527 case 'b':
528 case 'B':
529 change = 1;
530 c_acc.flags ^= ACC_BANNED;
531 break;
532 case 'k':
533 case 'K':
534 change = 1;
535 if (c_acc.flags & ACC_ANOPVP) {
536 c_acc.flags &= ~(ACC_ANOPVP | ACC_NOPVP);
537 } else if (c_acc.flags & ACC_NOPVP) {
538 c_acc.flags &= ~ACC_NOPVP;
539 c_acc.flags |= ACC_ANOPVP;
540 } else if (c_acc.flags & ACC_PVP) {
541 c_acc.flags &= ~ACC_PVP;
542 c_acc.flags |= ACC_NOPVP;
543 } else {
544 c_acc.flags |= ACC_PVP;
545 }
546 break;
547 case 'r':
548 case 'R':
549 change = 1;
550 if (c_acc.flags & ACC_VRESTRICTED) {
551 c_acc.flags &= ~(ACC_VRESTRICTED | ACC_RESTRICTED);
552 } else if (c_acc.flags & ACC_RESTRICTED) {
553 c_acc.flags &= ~ACC_RESTRICTED;
554 c_acc.flags |= ACC_VRESTRICTED;
555 } else {
556 c_acc.flags |= ACC_RESTRICTED;
557 }
558 break;
559 case 'i':
560 case 'I':
561 change = 1;
562 if (c_acc.flags & ACC_VPRIVILEGED) {
563 c_acc.flags &= ~(ACC_VPRIVILEGED | ACC_PRIVILEGED);
564 } else if (c_acc.flags & ACC_PRIVILEGED) {
565 c_acc.flags &= ~ACC_PRIVILEGED;
566 c_acc.flags |= ACC_VPRIVILEGED;
567 } else {
568 c_acc.flags |= ACC_PRIVILEGED;
569 }
570 break;
571 case 'U':
572 purge_duplicates();
573 break;
574 default:
575 ch = ' ';
576 beep();
577 }
578 } while (ch == ' ');
579 }
580 echo();
581 nocbreak();
582 endwin();
583 }
584
585 /* account finder */
findacc()586 int findacc() {
587 int x, i = 0;
588 char sname[30];
589 struct account c_acc;
590
591 statinput("Find which name: ", sname, 30);
592 fseek(fp, 0L, SEEK_SET);
593 /* its always upper, and admins can be lazy */
594 sname[0] = toupper(sname[0]);
595 while ((x = fread(&c_acc, sizeof(struct account),1, fp))) {
596 if (!strncmp(c_acc.name, sname, 30)) {
597 return(i);
598 }
599 i++;
600 } while(x);
601 status("Could not find that account");
602
603 return(-1);
604 }
605
status(char * info)606 void status(char *info) {
607 mvprintw(LINES - 1, 0, info);
608 beep();
609 }
610
statinput(char * prompt,char * string,int max)611 void statinput(char *prompt, char *string, int max) {
612 char ch;
613 int pos = 0;
614 mvprintw(LINES - 1, 0, prompt);
615 do {
616 ch = getch();
617 if (ch == '\n') break;
618 if (ch == '\b') {
619 if (pos) {
620 string[--pos] = '\0';
621 mvdelch(LINES - 1, strlen(prompt) + pos);
622 }
623 else
624 beep();
625 }
626 else{
627 if (pos < (max - 1)) {
628 string[pos++] = ch;
629 addch(ch);
630 }
631 else
632 beep();
633 }
634 refresh();
635 } while (ch != '\n');
636 string[pos] = '\0';
637 move(LINES - 1, 0);
638 clrtoeol();
639 }
640
getstring(const char * prompt,char * string,int max)641 void getstring(const char *prompt, char *string, int max) {
642 char ch;
643 int i = 0;
644 mvprintw(LINES - 1, 0, prompt);
645 do {
646 ch = getch();
647 if (ch == '\b' && i > 0)
648 i--;
649 if (ch == '\r' || ch == '\n') {
650 string[i] = '\0';
651 move(LINES - 1, 0);
652 clrtoeol();
653 return;
654 }
655 else {
656 string[i++] = ch;
657 addch(ch);
658 if (i == max) {
659 string[i] = '\0';
660 move(LINES - 1, 0);
661 clrtoeol();
662 return;
663 }
664 }
665 } while(1);
666 }
667
668 /* our password encryptor */
t_crypt(char * inbuf,const char * salt)669 static char *t_crypt(char *inbuf, const char *salt) {
670 #ifdef HAVE_CRYPT
671 static char out[64];
672 #if 0 /* doesn't do anything */
673 char setting[9];
674 setting[0] = '_';
675 strncpy(&setting[1], salt, 8);
676 #endif
677 #if 1 /* fix for len-1 names */
678 char setting[3];
679 /* only 1 character long salt? expand to 2 chars length */
680 if (!salt[1]) {
681 setting[0] = '.';
682 setting[1] = salt[0];
683 setting[2] = 0;
684 strcpy(out, (char*)crypt(inbuf, setting));
685 } else
686 #endif
687 #if 1 /* SPACE _ ! - ' , and probably more as _2nd character_ cause crypt() to return a null pointer ('.' is ok) */
688 #define ACCOUNTNAME_LEN 16
689 if (!((salt[1] >= 'A' && salt[1] <= 'Z') ||
690 (salt[1] >= 'a' && salt[1] <= 'z') ||
691 (salt[1] >= '0' && salt[1] <= '9') ||
692 salt[1] == '.')) {
693 char fixed_name[ACCOUNTNAME_LEN];
694 strcpy(fixed_name, salt);
695 fixed_name[1] = '.';
696 strcpy(out, (char*)crypt(inbuf, fixed_name));
697 } else
698 #endif
699 strcpy(out, (char*)crypt(inbuf, salt));
700 return(out);
701 #else
702 return(inbuf);
703 #endif
704 }
705
ask(char * prompt)706 unsigned short ask(char *prompt) {
707 char ch;
708 mvprintw(LINES - 1, 0, prompt);
709 do {
710 ch = getch();
711 if (ch == 'Y' || ch == 'y') break;
712 if (ch == 'N' || ch == 'n') break;
713 } while(1);
714 move(LINES - 1, 0);
715 clrtoeol();
716 return ((ch == 'Y' || ch == 'y'));
717 }
718
purge_duplicates(void)719 void purge_duplicates(void) {
720 //char accname[];
721 }
722