]> andersk Git - moira.git/blob - clients/mailmaint/mailmaint.c
7c150cffe6537fd49c16079db43b17ea3c6078b8
[moira.git] / clients / mailmaint / mailmaint.c
1 /*
2  *      $Source$
3  *      $Header$
4  */
5
6 #ifndef lint
7 static char rcsid_mailmaint_c[] = "$Header$";
8
9 #endif lint
10
11 /***********************************************************************/
12 /*  mailmaint.c - pjlevine - 20 August 1987 
13     
14 */
15 /***********************************************************************/
16 #include <stdio.h>
17 #include <pwd.h>
18 #include <menu.h>
19 #include <signal.h>
20 #include <strings.h>
21 #include <curses.h>
22 #include <sys/types.h>
23 #include <ctype.h>
24 #include "mit-copyright.h"
25
26 #define STARTCOL 0
27 #define STARTROW 3
28 #define SECONDCOL 30
29 #define DISPROW 15
30 #define LISTMAX 50
31 #define LISTSIZE 32
32 #define CTL(ch)  ((ch) & 037)
33 #define MAX(A,B) ((A) > (B) ? (A) : (B))
34
35 static char *whoami;
36 static int status;
37 static void scream();
38 char *ds();
39
40 typedef struct list_info {
41     char *acl;
42     char *desc;
43     char *expdate;
44 }         List_info;
45
46 static char *ascbuff = {"0123456789"};
47 static int 
48 print_2(), print_1();
49 static List_info *current_li = (List_info *) NULL;
50 static int get_list_info();
51 static int fetch_list_info();
52
53 char *malloc();
54 char *rindex();
55 char *strcpy();
56 char *getlogin();
57 char *strsave();
58 char *getenv();
59 char *calloc();
60
61 uid_t getuid();
62
63 typedef struct _menu {
64     int num_items;
65     char *title;
66     char **items;
67 }     MENU;
68
69 MENU *main_menu, *help_menu;
70
71 int position[2], oldpos[2];
72 int level, found_some, currow, page, num_members;
73 int moreflg, toggle, first_time;
74 char *uname;
75
76
77 /****************************************************/
78 /*ARGSUSED*/
79 main(argc, argv)
80     int argc;
81     char *argv[];
82
83 {
84
85     int use_menu = 1;
86     char buf[BUFSIZ];
87
88     init_sms_err_tbl();
89     init_krb_err_tbl();
90
91     if ((whoami = rindex(argv[0], '/')) == NULL)
92         whoami = argv[0];
93     else
94         whoami++;
95     uname = calloc(20, 1);
96     if ((current_li = (List_info *) malloc(sizeof(List_info)))
97         == (List_info *) NULL) {
98         (void) sprintf(buf, ": allocating list info");
99         goto punt;
100     }
101     else {
102         current_li->acl = (char *) NULL;
103         current_li->desc = (char *) NULL;
104         current_li->expdate = (char *) NULL;
105     }
106     if ((uname = getlogin()) == NULL) {
107         struct passwd *getpwuid();
108
109         uname = getpwuid((int) getuid())->pw_name;
110     }
111     uname = (uname && strlen(uname)) ? ds(uname) : "";
112
113     printf("Connecting to database for %s...please hold on.\n", uname);
114
115     status = sms_connect();
116     if (status) {
117         (void) sprintf(buf, "\nConnection to SMS server failed");
118         goto punt;
119     }
120
121     status = sms_auth();
122     if (status) {
123         (void) sprintf(buf, "\nAuthorization failed.\n");
124         goto punt;
125     }
126
127     if (use_menu) {
128         (void) initscr();
129         if ((LINES < 24) || (COLS < 60)) {
130             Put_message("Display window too small.\n\n");
131             (void) sprintf(buf, "Current window parameters are (%d \
132 lines, %d columns)\n", LINES, COLS);
133             Put_message(buf);
134             Put_message("Please resize your window\n");
135             Put_message("to at least 24 lines and 60 columns.\n");
136             exit(0);
137         }
138         raw();
139         noecho();
140         position[0] = oldpos[0] = 1;
141         level = 0;
142         pack_main_menu();
143         pack_help_menu();
144         display_menu(main_menu);
145         get_main_input();
146         cls();
147         endwin();
148     }
149     exit(0);
150
151 punt:
152     com_err(whoami, status, buf);
153     exit(1);
154 }
155
156 /****************************************************/
157 get_main_input()
158 {
159     int c;
160     int retflg;
161
162     while (1) {
163         oldpos[level] = position[level];
164         retflg = 0;
165         currow = DISPROW + 2;
166         page = 1;
167         toggle = num_members = moreflg = 0;
168         c = getchar();
169         if (c == 13) {
170             if (position[level] == 7)
171                 c = 'q';
172             else
173                 c = ascbuff[position[level]];
174             retflg = 1;
175         }
176         switch (c) {
177         case 'L' & 037: /* clear screen */
178             display_menu(main_menu);
179             break;
180         case 'q':
181         case 'Q':               /* quit */
182             position[level] = 7;
183             highlight(main_menu);
184             if (retflg) {
185                 cls();
186                 return;
187             }
188             break;
189         case '1':               /* show all lists */
190             position[level] = 1;
191             if (retflg) {
192                 show_all();
193             }
194             break;
195         case '2':               /* get all members of a list */
196             position[level] = 2;
197             if (retflg) {
198                 (void) list_members();
199             }
200             break;
201         case '3':               /* display list which user is a recipient */
202             position[level] = 3;
203             if (retflg) {
204                 list_by_member();
205             }
206             break;
207         case '4':               /* show description */
208             position[level] = 4;
209             if (retflg) {
210                 show_list_info();
211             }
212             break;
213         case '5':               /* add to list */
214             position[level] = 5;
215             if (retflg) {
216                 add_member();
217             }
218             break;
219         case '6':               /* delete */
220             position[level] = 6;
221             if (retflg) {
222                 delete_member();
223             }
224             break;
225         case 27:                /* up arrow */
226             c = getchar();
227             if (c == 91) {
228                 c = getchar();
229                 if (c == 65) {
230                     position[level]--;
231                     if (!position[level])
232                         position[level] = 7;
233                 }
234                 else {
235                     if (c == 66) {
236                         position[level]++;
237                         if (position[level] > 7)
238                             position[level] = 1;
239                     }
240                 }
241             }
242             break;
243         default:
244             printf("%c", 7);
245             break;
246         }
247         highlight(main_menu);
248     }
249 }
250
251 /****************************************************/
252 show_list_info()
253 {
254     char *buf;
255     char c;
256
257     show_text(DISPROW, STARTCOL, "Show information about a list.\n\r");
258     buf = calloc((unsigned)1024, 1);
259     if (Prompt("Enter List Name: ", buf, LISTSIZE) == 1) {
260         Put_message("\n\r");
261         if (fetch_list_info(buf, current_li) == 0) {
262             (void) sprintf(buf, "Description: %s\n\r", current_li->desc);
263             if (strlen(buf) > 60)
264                 (void) display_buff(buf);
265             else
266                 show_text(currow, STARTCOL, buf);
267             currow++;
268             (void) sprintf(buf, "List Administrator: %s", current_li->acl);
269             show_text(currow, STARTCOL, buf);
270             currow++;
271             (void) sprintf(buf, "Expiration date: %s", current_li->expdate);
272             show_text(currow, STARTCOL, buf);
273             currow++;
274         }
275         else {
276             show_text(currow, STARTCOL, "madm: No such list found.");
277             currow++;
278         }
279         show_text(currow, STARTCOL, "Press any Key to continue...");
280         (void) getchar();
281     }
282     clrwin(DISPROW);
283 }
284
285 /****************************************************/
286 display_buff(buf)
287     char *buf;
288 {
289     int i, cnt;
290     char *printbuf;
291     int maxcol;
292
293     maxcol = COLS;
294     if (maxcol >= 80)
295         maxcol = 80;
296
297     cnt = 0;
298     printbuf = calloc((unsigned)maxcol, 1);
299     for (i = 0; i <= strlen(buf); i++) {
300         printbuf[cnt] = buf[i];
301         cnt++;
302         if (cnt >= maxcol) {
303             (void) start_display_buff(printbuf);
304             cnt = 0;
305             free(printbuf);
306             printbuf = calloc((unsigned)maxcol, 1);
307         }
308     }
309     if (strlen(buf) % maxcol != 0) {
310         (void) start_display_buff(printbuf);
311         free(printbuf);
312     }
313     return (0);
314 }
315
316 /****************************************************/
317 start_display_buff(buff)
318     char *buff;
319 {
320     char buffer[5];
321
322     num_members++;
323     if (moreflg)
324         return (0);
325     if (currow >= LINES - 2) {
326         page++;
327         currow++;
328         mvcur(0, 0, currow, STARTCOL);
329         refresh();
330         if (Prompt("--RETURN for more, ctl-c to exit--", buffer, 1) == 0) {
331             Put_message("Flushing query...");
332             moreflg = 1;
333             return (0);
334         }
335         clrwin(DISPROW + 2);
336         currow = DISPROW + 2;
337         show_text(currow, STARTCOL, "continued");
338         currow++;
339     }
340     show_text(currow, STARTCOL, buff);
341     currow++;
342     return (0);
343 }
344
345 /****************************************************/
346 add_member()
347 {
348     static char *argv[] = {
349         "add_member_to_list",
350         0,
351         0,
352         0
353         };
354     char *buf;
355     char c;
356
357     show_text(DISPROW, STARTCOL, "Add yourself to a list\n\r");
358     buf = calloc(LISTMAX, 1);
359     if (Prompt("Enter List Name: ", buf, LISTSIZE) == 1) {
360         Put_message("\r\n");
361         argv[1] = strsave(buf);
362         argv[2] = strsave("user");
363         argv[3] = strsave(uname);
364         if (status = sms_query_internal(3, argv, scream, (char *) NULL)) {
365             Put_message("\r\n");
366             com_err(whoami, status, " found.\n");
367         }
368         else {
369             (void) sprintf(buf, "User %s added to list\r", uname);
370             show_text(DISPROW + 3, STARTCOL, buf);
371         }
372         currow = DISPROW + 4;
373         show_text(DISPROW + 4, STARTCOL, "Press any Key to continue...");
374         (void) getchar();
375     }
376     clrwin(DISPROW);
377 }
378
379 /****************************************************/
380 delete_member()
381 {
382     static char *argv[] = {
383         "delete_member_from_list",
384         0,
385         0,
386         0
387         };
388     char *buf;
389     char c;
390
391     show_text(DISPROW, STARTCOL, "Remove yourself from a list\n\r");
392     buf = calloc(LISTMAX, 1);
393     if (Prompt("Enter List Name: ", buf, LISTSIZE) == 1) {
394         Put_message("\r\n");
395         argv[1] = strsave(buf);
396         argv[2] = strsave("user");
397         argv[3] = strsave(uname);
398         if (status = sms_query_internal(3, argv, scream, (char *) NULL)) {
399             Put_message("\r\n");
400             com_err(whoami, status, " found.\n");
401         }
402         else {
403             (void) sprintf(buf, "User %s deleted from list\r", uname);
404             show_text(DISPROW + 3, STARTCOL, buf);
405         }
406         currow = DISPROW + 4;
407         show_text(DISPROW + 4, STARTCOL, "Press any Key to continue...");
408         (void) getchar();
409     }
410     clrwin(DISPROW);
411 }
412
413 /****************************************************/
414 list_by_member()
415 {
416     char *nargv[3];
417     char *buf;
418     char c;
419
420     nargv[1] = strsave("user");
421     nargv[2] = strsave(uname);
422     buf = calloc(BUFSIZ, 1);
423     (void) sprintf(buf, "%s is on the following lists:\r", uname);
424     show_text(DISPROW, STARTCOL, buf);
425     mvcur(0, 0, currow, STARTCOL);
426     refresh();
427     if (status = sms_query("get_lists_of_member", 2, nargv + 1,
428                            print_1, (char *) NULL)) {
429         Put_message("\r\n");
430         com_err(whoami, status, " in get_lists_of_member");
431     }
432     show_text(currow, STARTCOL, "Press any Key to continue...");
433     (void) getchar();
434     clrwin(DISPROW);
435     return;
436 }
437
438 /****************************************************/
439 show_all()
440 {
441     char c;
442
443     show_text(DISPROW, STARTCOL, "This function may take a while...proceed[y]?");
444     c = getchar();
445     if (c == 'n' || c == 'N') {
446         erase_line(DISPROW, STARTCOL);
447         return;
448     }
449     move(DISPROW + 1, STARTCOL);
450     addstr("Processing query...please hold");
451     refresh();
452     (void) list_all_groups();
453 }
454
455 /****************************************************/
456 /*ARGSUSED*/
457 static int
458 print_1(argc, argv, callback)
459     int argc;
460     char *argv[], *callback;
461 {
462     char buf[BUFSIZ];
463
464     /* no newline 'cause Put_message adds one */
465     (void) sprintf(buf, "%s\r", argv[0]);
466     (void) start_display(buf);
467
468     return (0);
469 }
470
471 /****************************************************/
472 /*ARGSUSED*/
473 static int
474 print_all(argc, argv, callback)
475     int argc;
476     char *argv[], *callback;
477 {
478     char buf[BUFSIZ];
479
480     if (moreflg)
481         return (0);
482     if (first_time) {
483         erase_line(DISPROW + 1, STARTCOL);
484         show_text(DISPROW + 1, STARTCOL, "All mailing lists:");
485         first_time = 0;
486     }
487     (void) sprintf(buf, "%s\r", argv[0]);
488     (void) start_display(buf);
489
490     return (0);
491 }
492
493 /****************************************************/
494 list_all_groups()
495 {
496
497     first_time = 1;
498     if (status = sms_query("get_all_visible_maillists", 0, (char **) NULL,
499                            print_all, (char *) NULL)) {
500         Put_message("\r\n");
501         com_err(whoami, status, " in list_all_groups\n");
502     }
503     end_display();
504
505     return (DM_NORMAL);         /* HA! */
506 }
507
508 /****************************************************/
509 list_members()
510 {
511     char *argv[1];
512     char *buf;
513     char buffer[80];
514
515     found_some = 0;
516     move(DISPROW, STARTCOL);
517     mvcur(0, 0, DISPROW, STARTCOL);
518     refresh();
519     buf = calloc(LISTMAX, 1);
520     if (Prompt("Enter List Name: ", buf, LISTSIZE) == 1) {
521         (void) sprintf(buffer, "The members of list '%s' are:", buf);
522         show_text(DISPROW + 1, STARTCOL, buffer);
523         argv[0] = buf;
524         if (status = sms_query("get_members_of_list", 1, argv,
525                                print_2, (char *) NULL)) {
526             Put_message("\r\n");
527             com_err(whoami, status, " found.\n");
528             currow++;
529         }
530         if (!found_some) {
531             show_text(currow, STARTCOL, "List is empty (no members).");
532             currow++;
533         }
534         end_display();
535         return(0);
536     }
537     clrwin(DISPROW);
538     return (DM_NORMAL);         /* HA! */
539 }
540
541 /****************************************************/
542 /*ARGSUSED*/
543 static int
544 print_2(argc, argv, callback)
545     int argc;
546     char *argv[], *callback;
547 {
548     char buf[BUFSIZ];
549
550     found_some = 1;
551     (void) sprintf(buf, "%s %s", argv[0], argv[1]);
552     (void) start_display(buf);
553
554     return (0);
555 }
556
557 /****************************************************/
558 start_display(buff)
559     char *buff;
560 {
561     char *buffer;
562
563     num_members++;
564     if (moreflg)
565         return(0);
566     buffer = calloc(50, 1);
567     if (currow >= LINES - 2) {
568         page++;
569         currow++;
570         mvcur(0, 0, currow, STARTCOL);
571         refresh();
572         if (Prompt("--RETURN for more, ctl-c to exit--", buffer, 1) == 0) {
573             Put_message("Flushing query...");
574             moreflg = 1;
575             return (0);
576         }
577         clrwin(DISPROW + 2);
578         currow = DISPROW + 2;
579         (void) sprintf(buffer, "Continued (Page %d)", page);
580         show_text(currow, STARTCOL, buffer);
581         currow++;
582         toggle = 0;
583     }
584     if (!toggle)
585         show_text(currow, STARTCOL, buff);
586     else {
587         show_text(currow, SECONDCOL, buff);
588         currow++;
589     }
590     toggle = !toggle;
591     return(0);
592 }
593
594 /****************************************************/
595 end_display()
596 {
597     char *buffer, c;
598
599     if (moreflg) {
600         clrwin(DISPROW);
601         return;
602     }
603
604     buffer = calloc(50, 1);
605     currow++;
606     (void) sprintf(buffer, "End of List. %d Total Members\r", num_members);
607     show_text(currow, STARTCOL, buffer);
608     currow++;
609     show_text(currow, STARTCOL, "Press any key to continue...");
610     (void) getchar();
611     clrwin(DISPROW);
612
613 }
614
615 /****************************************************/
616 display_menu(menu)
617     MENU *menu;
618 {
619     int i;
620
621     cls();
622     title(menu->title);
623     mvcur(0, 0, STARTROW, STARTCOL);
624     refresh();
625     for (i = 0; i <= menu->num_items - 1; i++) {
626         move(STARTROW + i, STARTCOL);
627         standend();
628         addstr(menu->items[i]);
629         refresh();
630     }
631     center_text(STARTROW + menu->num_items + 2,
632                 "Enter a number, <up arrow>, or <down arrow>.");
633     if (!level)
634         center_text(STARTROW + menu->num_items + 3,
635                     "Press 'q' to exit, <return> to confirm choice.");
636     else
637         center_text(STARTROW + menu->num_items + 3,
638         "Press 'q' to exit, 'r' for main menu, <return> to confirm choice.");
639
640     if (!level)
641         highlight(main_menu);
642 }
643
644 /****************************************************/
645 pack_main_menu()
646 {
647     char *buf;
648
649     main_menu = (MENU *) malloc((unsigned) sizeof(MENU));
650     main_menu->num_items = 7;
651     main_menu->items = (char **) malloc((unsigned) sizeof(char *) * main_menu->num_items);
652
653     buf = calloc(50, 1);
654     (void) sprintf(buf, "Mail List Program for %s", uname);
655     main_menu->title = strsave(buf);
656     main_menu->items[0] = strsave("1.  Show all mailing lists.");
657     main_menu->items[1] = strsave("2.  Get all members of a mailing list.");
658     main_menu->items[2] = strsave("3.  Display lists of which you are a member.");
659     main_menu->items[3] = strsave("4.  Show description of list.");
660     main_menu->items[4] = strsave("5.  Add yourself to a mailing list.");
661     main_menu->items[5] = strsave("6.  Delete yourself from a mailing list.");
662     main_menu->items[6] = strsave("q.  Quit.");
663 }
664
665 /****************************************************/
666 pack_help_menu()
667 {
668     help_menu = (MENU *) malloc((unsigned) sizeof(MENU));
669     help_menu->num_items = 5;
670     help_menu->items = (char **) malloc((unsigned) sizeof(char *) * help_menu->num_items);
671
672     help_menu->title = strsave("madm is designed as a basic mail list administration program.");
673     help_menu->items[0] = strsave("if you need to perform more advanced list manipulation like");
674     help_menu->items[1] = strsave("adding lists, or changing list characteristics, refer to the");
675     help_menu->items[2] = strsave("program listmaint.");
676     help_menu->items[3] = strsave(" ");
677     help_menu->items[4] = strsave("Press any key to continue.");
678 }
679
680 /****************************************************/
681 highlight(menu)
682     MENU *menu;
683 {
684
685
686     if (oldpos[level] != position[level]) {
687         move(STARTROW + oldpos[level] - 1, STARTCOL);
688         standend();
689         addstr(menu->items[oldpos[level] - 1]);
690         refresh();
691     }
692
693     move(STARTROW + position[level] - 1, STARTCOL);
694     standout();
695     addstr(menu->items[position[level] - 1]);
696     refresh();
697     standend();
698     refresh();
699 }
700
701 /****************************************************/
702 title(buff)
703     char *buff;
704 {
705     move(0, MAX(0, (COLS - strlen(buff)) >> 1));
706     standout();
707     addstr(buff);
708     refresh();
709     standend();
710 }
711
712 /****************************************************/
713 center_text(row, buff)
714     int row;
715     char *buff;
716 {
717     move(row, MAX(0, (COLS - strlen(buff)) >> 1));
718     addstr(buff);
719     refresh();
720 }
721
722 /****************************************************/
723 show_text(row, col, buff)
724     int row, col;
725     char *buff;
726 {
727     mvcur(0, 0, row, col);
728     refresh();
729     printf("%s", buff);
730 }
731
732 /****************************************************/
733 erase_line(row, col)
734     int row, col;
735 {
736     char *buff;
737     int i;
738
739     buff = calloc((unsigned)COLS, 1);
740     for (i = 0; i <= COLS - 2; i++)
741         buff[i] = ' ';
742     buff[i] = 0;                /* just to be sure ! */
743     move(row, col);
744     mvcur(0, 0, row, col);
745     printf("%s", buff);
746     refresh();
747 }
748
749 /****************************************************/
750 cls()
751 {
752     clear();
753     refresh();
754 }
755
756 /****************************************************/
757 clrwin(erase_row)
758     int erase_row;
759 {
760     int i;
761     char *buff;
762     int maxcol;
763
764     maxcol = COLS;
765     if (maxcol > 80)
766         maxcol = 80;            /* limit width */
767
768     buff = calloc((unsigned)maxcol + 1, 1);
769     for (i = 0; i <= maxcol - 1; i++)
770         buff[i] = ' ';
771     buff[i] = 0;                /* just to be sure ! */
772     mvcur(0, 0, erase_row, STARTCOL);
773     refresh();
774     for (i = erase_row; i <= currow - 1; i++) {
775         printf("%s\n\r", buff);
776     }
777     printf("%s", buff);
778     mvcur(erase_row, STARTCOL, STARTROW + oldpos[level] - 1, STARTCOL);
779     refresh();
780 }
781
782 /****************************************************/
783 char *
784 strsave(s)
785     char *s;
786 {
787     char *p;
788
789     if ((p = calloc((unsigned)1, (unsigned)(strlen(s) + 1))) != NULL) {
790         (void) strcpy(p, s);
791     }
792     else
793         Put_message("error in alloc\n\r");
794     return (p);
795 }
796
797 /****************************************************/
798 /* jean's routine ??? */
799 static void 
800 scream()
801 {
802     com_err(whoami, status, "\nAn SMS update returned a value -- programmer \
803 botch\n");
804     sms_disconnect();
805     exit(1);
806 }
807
808 /****************************************************/
809 /*ARGSUSED*/
810 static int 
811 fetch_list_info(list, li)
812     char *list;
813     List_info *li;
814 {
815     char *argv[1];
816
817     argv[0] = list;
818     if ((status = sms_query("get_list_info", 1, argv,
819                             get_list_info, (char *) NULL)) == 0) {
820         return status;
821     }
822     else {
823         com_err(whoami, status, " found.\n");
824         return status;
825     }
826 }
827
828 /* ARGSUSED */
829 static int 
830 get_list_info(argc, argv)
831     int argc;
832     char **argv;
833 {
834
835     if (current_li->acl)
836         free(current_li->acl);
837     current_li->acl = strsave(argv[2]);
838     if (current_li->desc)
839         free(current_li->desc);
840     current_li->desc = strsave(argv[3]);
841     if (current_li->expdate)
842         free(current_li->expdate);
843     current_li->expdate = strsave(argv[4]);
844     return (0);
845 }
846
847
848
849
850 /****************************************************/
851 /* Prompt the user for input */
852 int 
853 Prompt(prompt, buf, buflen)
854     char *prompt;
855     char *buf;
856     int buflen;
857 {
858     int c;
859     char *p;
860     int x, oldx;
861
862     printf("%s", prompt);
863     refresh();
864     for (p = buf; abs(strlen(p) - strlen(buf)) <= buflen;) {
865         refresh();
866         c = getchar();
867         switch (c) {
868         case CTL('C'):
869             return 0;
870         case CTL('Z'):
871             return 0;
872         case CTL('L'):
873             cls();
874             display_menu(main_menu);
875             return (0);
876         case '\n':
877         case '\r':
878             Put_message("\r");
879             *p = '\0';
880             if (strlen(buf) < 1)/* only \n or \r in buff */
881                 return (-1);
882             else
883                 return (1);
884         case '\b':
885         case '\177':
886             if (p > buf) {
887                 p--;
888                 x--;
889                 Put_message("\b");
890                 Put_message(" ");
891                 Put_message("\b");
892             }
893             break;
894         case CTL('U'):
895         case CTL('G'):
896         case CTL('['):
897             x = oldx;
898             p = buf;
899             break;
900         default:
901             if (abs(strlen(p) - strlen(buf)) >= buflen) {
902                 printf("%c", 7);
903                 break;
904             }
905             if (isprint(c)) {
906                 (void) addch(c);
907                 *p++ = c;
908                 x++;
909             }
910             else
911                 (void) putchar(CTL('G'));
912             break;
913         }
914     }
915     return(0);
916 }
917
918 /*
919  * duplicate string 
920  */
921 char *
922 ds(str)
923     char *str;
924 {
925     register char *newstr = malloc((unsigned) strlen(str) + 1);
926
927     if (newstr == (char *) NULL)
928         return ((char *) NULL);
929     else
930         return (strcpy(newstr, str));
931 }
932
933 /*
934  * Local Variables:
935  * mode: c
936  * c-indent-level: 4
937  * c-continued-statement-offset: 4
938  * c-brace-offset: -4
939  * c-argdecl-indent: 4
940  * c-label-offset: -4
941  * End: 
942  */
This page took 0.095242 seconds and 3 git commands to generate.