home *** CD-ROM | disk | FTP | other *** search
/ GRIPS 2: Government Rast…rocessing Software & Data / GRIPS_2.cdr / dos / ncsa_tel / contribu / byu_tel2.hqx / telpass / tel1.c next >
C/C++ Source or Header  |  1988-07-07  |  20KB  |  890 lines

  1.  
  2. /*
  3. *  NCSA Telnet source code
  4. *  National Center for Supercomputing Applications
  5. *  January 31, 1988
  6. *  (C) Copyright 1988 Board of Trustees of the University of Illinois
  7. *
  8. *  Permission is granted to any individual or institution to use, copy,
  9. *  modify, or redistribute this software and its documentation provided
  10. *  this notice and the copyright notices are retained.  This software
  11. *  may not be distributed for profit, either in original form or in
  12. *  derivative works.  The University of Illinois makes no representations
  13. *  about the suitability of this software for any purpose.  
  14. *  THE UNIVERSITY OF ILLINOIS GIVES NO WARRANTY,
  15. *  EITHER EXPRESS OR IMPLIED, FOR THE PROGRAM AND/OR DOCUMENTATION PROVIDED,
  16. *  INCLUDING, WITHOUT LIMITATION, WARRANTY OF MERCHANTABILITY AND WARRANTY
  17. *  OF FITNESS FOR A PARTICULAR PURPOSE.
  18. */
  19. /*
  20.  * File Telpass.c
  21.  *
  22.  * Tim Krauskopf
  23.  * Copyright ⌐ 1988 Board of Trustees of the University of Illinois
  24.  *
  25.  * Portions Copyright Apple Computer, Inc. 1985, 1986
  26.  * All rights reserved.
  27.  *
  28.  * Edit passwords for NCSA telnet.  Passwords stored in the data fork of an independent
  29.  * password file.
  30.  *
  31.  */
  32.  
  33. # include <types.h>                 /* Nearly always required */
  34. # include <quickdraw.h>             /* To access the qd globals */
  35. # include <toolutils.h>             /* CursHandle and iBeamCursor */
  36. # include <fonts.h>                 /* Only for InitFonts() trap */
  37. # include <events.h>                /* GetNextEvent(), ... */
  38. # include <windows.h>                /* GetNewWindow(), ... */
  39. # include <controls.h>
  40. # include <lists.h>
  41. # include <files.h>
  42. # include <fcntl.h>
  43. # include <packages.h>
  44. # include <dialogs.h>                /* InitDialogs() and GetNewDialog() */
  45. # include <menus.h>                 /* EnableItem(), DisableItem() */
  46. # include <desk.h>                    /* SystemTask(), SystemClick() */
  47. # include <textedit.h>                /* TENew() */
  48. # include <scrap.h>                 /* ZeroScrap() */
  49. # include <segload.h>                /* UnloadSeg() */
  50. # include <StdIO.h>
  51. extern _DataInit();
  52.  
  53. /*
  54.  * Resource ID constants.
  55.  */
  56. # define appleID        128             /* This is a resource ID */
  57. # define fileID         129             /* ditto */
  58. # define editID         130             /* ditto */
  59.  
  60. # define appleMenu        0                /* MyMenus[] array indexes */
  61. # define    aboutMeCommand    1
  62.  
  63. # define fileMenu        1
  64. # define    newCommand  1
  65. # define    openCommand 2
  66. # define    saveCommand 3
  67. # define    saveasCommand 4
  68. # define    quitCommand 5
  69.  
  70. # define editMenu        2
  71. # define    undoCommand     1
  72. # define    cutCommand        3
  73. # define    copyCommand     4
  74. # define    pasteCommand    5
  75. # define    clearCommand    6
  76.  
  77. # define menuCount     3
  78. /*
  79.  * For the one and only text window
  80.  */
  81. # define windowID        128
  82. #define drawinID  129
  83. /*
  84.  * For the About Sample... DLOG
  85.  */
  86. # define aboutMeDLOG    128
  87. # define newuDLOG  129
  88. # define newpDLOG  130
  89. # define delDLOG 131
  90.  
  91. # define    okButton        1
  92. /*
  93. *  For the controls
  94. */
  95. #define Cnewuser 129
  96. #define Cdelete 130
  97. #define Cpasswd 131
  98. #define NCS 3
  99.  
  100. # define SETRECT(rectp, _top, _left,  _bottom, _right)    \
  101.     (rectp)->left = (_left), (rectp)->top = (_top),     \
  102.     (rectp)->right = (_right), (rectp)->bottom = (_bottom)
  103.  
  104. /*
  105.  * HIWORD and LOWORD macros, for readability.
  106.  */
  107. # define HIWORD(aLong)        (((aLong) >> 16) & 0xFFFF)
  108. # define LOWORD(aLong)        ((aLong) & 0xFFFF)
  109.  
  110. /*
  111.  * Global Data objects, used by routines external to main().
  112.  */
  113. MenuHandle        MyMenus[menuCount];     /* The menu handles */
  114. Boolean         DoneFlag;                /* Becomes TRUE when File/Quit chosen */
  115.  
  116. char *lines[500],*malloc();                /* for password storage */
  117.     register
  118.         WindowPtr    myWindow;            /* Referenced often */
  119.         ControlHandle mycontrol[NCS];
  120.         ListHandle mylist=NULL;
  121.           SFReply reply;
  122.          SFTypeList tlst;
  123.          Point wh;
  124.          
  125. long mycreator = 'NCSp',mytype = 'pass';
  126. /*
  127. *  data structure for timk
  128. */
  129.     Point lastPt = {0,0},    /* last point */
  130.         csize = { 15,200 };
  131.         
  132.     Rect r1,r2,r3;
  133.     Rect rview , rframe,
  134.         dbounds ;
  135.     AppFile theFile;
  136.     char s[256],currentfile[256]={""};
  137.     
  138. int
  139. main()
  140. {
  141.     extern void     setupMenus();
  142.     extern void     doCommand();
  143.     Rect            screenRect, dragRect, txRect;
  144.     Point            mousePt;
  145.     CursHandle        ibeamHdl;
  146.     EventRecord     myEvent;
  147.     WindowRecord    wRecord;
  148.     WindowPtr        theActiveWindow, whichWindow;
  149.     int i;
  150.     short int shorti,shortj;
  151.     ListPtr l;        /* temp use */
  152.     /*
  153.      * Initialization traps
  154.      */
  155.     UnloadSeg(_DataInit);
  156.     InitGraf(&qd.thePort);
  157.     InitFonts();
  158.     FlushEvents(everyEvent, 0);
  159.     InitWindows();
  160.     InitMenus();
  161.     TEInit();
  162.     InitDialogs(nil);
  163.     InitCursor();
  164.     /*
  165.      * setupMenus is execute-once code, so we can unload it now.
  166.      */
  167.     setupMenus();            /* Local procedure, below */
  168.     UnloadSeg(setupMenus);
  169.     /*
  170.      * Calculate the drag rectangle in advance.
  171.      * This will be used when dragging a window frame around.
  172.      * It constrains the area to within 4 pixels from the screen edge
  173.      * and below the menu bar, which is 20 pixels high.
  174.      */
  175.     screenRect = qd.screenBits.bounds;
  176.     SETRECT(&dragRect, 20 + 4, 4, screenRect.bottom-4, screenRect.right-4);
  177.     myWindow = GetNewWindow(windowID, &wRecord, (WindowPtr) -1);
  178.     SetPort(myWindow);
  179. /*
  180. *  get controls
  181. */
  182.     for (i=0; i<NCS; i++)
  183.         mycontrol[i] = GetNewControl(i+129,myWindow);
  184.     HiliteControl(mycontrol[Cdelete-129], 255);
  185.     HiliteControl(mycontrol[Cpasswd-129], 255);
  186.     DrawControls(myWindow);
  187. /*
  188. *  start list manager
  189. */
  190.     SETRECT(&rview, 50,30,200,150);
  191.     SETRECT(&rframe, 49,29,201,166);
  192.     SETRECT(&dbounds, 0,0,0,1 );
  193.     
  194. mylist = LNew( &rview,&dbounds, &csize, 0, myWindow, true,false,false,true);
  195.     l = *mylist;
  196.     l->selFlags |= lOnlyOne;                        /* only one selection at a time */
  197.     FrameRect(&rframe);                                /* draw around it */
  198. /*
  199. *  if we have a selection, load it at start
  200. */
  201.     CountAppFiles( &shorti, &shortj);
  202.     if (!shorti && shortj > 0) {
  203.         GetAppFiles( shortj, &theFile);            /* get file name */
  204.         theFile.fName.text[theFile.fName.length] = 0;
  205.         passlist(theFile.fName.text);
  206.         ClrAppFiles(shortj);
  207.         strcpy(s,"Telpass: ");
  208.         strcat(s,theFile.fName.text);
  209.         SetWTitle( myWindow, s);
  210.     }
  211.     /*
  212.      * Ready to go.
  213.      * Start with a clean event slate, and cycle the main event loop
  214.      * until the File/Quit menu item sets DoneFlag.
  215.      *
  216.      */
  217.     DoneFlag = false;
  218.     for ( ;; ) {
  219.         if (DoneFlag) {
  220.             if (!currentfile[0])    /* if untitled, save it */
  221.                 saveit();
  222.             else
  223.                 passwrite(currentfile);
  224.             LDispose(mylist);
  225.             break;        /* from main event loop */
  226.         }
  227.         /*
  228.          * Main Event tasks:
  229.          */
  230.         SystemTask();
  231.         theActiveWindow = FrontWindow();        /* Used often, avoid repeated calls */
  232.         if (myWindow == theActiveWindow) {
  233.             GetMouse(&mousePt);
  234.         }
  235.         if ( ! GetNextEvent(everyEvent, &myEvent)) {
  236.             /*
  237.              * A null or system event, not for me.
  238.              * Here is a good place for heap cleanup and/or
  239.              * segment unloading if I want to.
  240.              */
  241.             continue;
  242.         }
  243.         /*
  244.          * In the unlikely case that the active desk accessory does not
  245.          * handle mouseDown, keyDown, or other events, GetNextEvent() will
  246.          * give them to us!  So before we perform actions on some events,
  247.          * we check to see that the affected window in question is really
  248.          * our window.
  249.          */
  250.         switch (myEvent.what) {
  251.             case mouseDown:
  252.                 switch (FindWindow(&myEvent.where, &whichWindow)) {
  253.                     case inSysWindow:
  254.                         SystemClick(&myEvent, whichWindow);
  255.                         break;
  256.                     case inMenuBar:
  257.                         doCommand(MenuSelect(&myEvent.where));
  258.                         break;
  259.                     case inDrag:
  260.                         DragWindow(whichWindow, &myEvent.where, &dragRect);
  261.                         break;
  262.                     case inGoAway:
  263.                         GlobalToLocal(&myEvent.where);
  264.                         if (TrackGoAway(whichWindow, &myEvent.where))
  265.                             DoneFlag = true;
  266.                         break;
  267.                     case inGrow:
  268.                         /* There is no grow box. (Fall through) */
  269.                     case inContent:
  270.                         if (whichWindow != theActiveWindow) {
  271.                             SelectWindow(whichWindow);
  272.                         }
  273.                         GlobalToLocal(&myEvent.where);
  274.                         if (whichWindow == myWindow) {
  275.                             ControlHandle tempc;
  276.                             FindControl(&myEvent.where,myWindow,&tempc);
  277.                             if (tempc)
  278.                                 if (TrackControl(tempc, &myEvent.where, NULL)) {
  279.                                 /* find which one */
  280.                                 for (i=0; i<NCS; i++)
  281.                                     if (tempc == mycontrol[i])
  282.                                         switch (i+129) {
  283.                                             case Cnewuser:
  284.                                                 donewuser();
  285.                                                 break;
  286.                                             case Cpasswd:
  287.                                                 donewpass();
  288.                                                 break;
  289.                                             case Cdelete:
  290.                                                 dodelete();
  291.                                                 break;
  292.                                             default:
  293.                                             break;
  294.                                         }
  295.                                         
  296.                                 }
  297.                             /*
  298.                             * check in list manager
  299.                             */
  300.                             if (PtInRect(&myEvent.where, &rframe)) {
  301.                                 LClick(&myEvent.where, myEvent.modifiers, mylist);
  302.                             }
  303.                 /* if something selected, highlight options, if not, dehighlight */
  304.                             csize.h = csize.v = 0;
  305.                             if (LGetSelect(true, &csize, mylist)) {
  306.                                 HiliteControl(mycontrol[Cdelete-129], 0);
  307.                                 HiliteControl(mycontrol[Cpasswd-129], 0);
  308.                             }
  309.                             else {
  310.                                 HiliteControl(mycontrol[Cdelete-129], 255);
  311.                                 HiliteControl(mycontrol[Cpasswd-129], 255);
  312.                             }
  313.                         }
  314.                         break;
  315.                     default:
  316.                         break;
  317.                 }/*endsw FindWindow*/
  318.                 break;
  319.  
  320.             case keyDown:
  321.             case autoKey:
  322.                 if (myWindow == theActiveWindow) {
  323.                     if (myEvent.modifiers & cmdKey) {
  324.                         doCommand(MenuKey(myEvent.message & charCodeMask));
  325.                     } else {
  326.                         if ('x' == (char) (myEvent.message & charCodeMask))
  327.                             DoneFlag = true;
  328.                     }
  329.                 }
  330.                 break;
  331.  
  332.             case activateEvt:
  333.                 if ((WindowPtr) myEvent.message == myWindow) {
  334.                     LActivate(myEvent.modifiers & activeFlag, mylist);
  335.                 }
  336.                 break;
  337.  
  338.             case updateEvt:
  339.                 if ((WindowPtr) myEvent.message == myWindow) {
  340.                     BeginUpdate(myWindow);
  341.                     DrawControls(myWindow);
  342.                     FrameRect(&rframe);
  343.                     LUpdate(myWindow->visRgn,mylist);
  344.                     EndUpdate(myWindow);
  345.                 }
  346.                 break;
  347.  
  348.             default:
  349.                 break;
  350.  
  351.         }/*endsw myEvent.what*/
  352.  
  353.     }/*endfor Main Event loop*/
  354.     /*
  355.      * No cleanup required, but if there was, it would happen here.
  356.      */
  357.     return(0);        /* Return from main() to allow C runtime cleanup */
  358. }
  359.  
  360. /*
  361.  * Set the segment to Initialize.  BEWARE: leading and trailing white space
  362.  * would be part of the segment name!
  363.  */
  364. # define    __SEG__ Initialize
  365.  
  366. /*
  367.  * Set up the Apple, File, and Edit menus.
  368.  * If the MENU resources are missing, we die.
  369.  */
  370. void
  371. setupMenus()
  372. {
  373.     extern MenuHandle    MyMenus[];
  374.     register MenuHandle *pMenu;
  375.     /*
  376.      * Set up the desk accessories menu.
  377.      * The "About Sample..." item, followed by a grey line,
  378.      * is presumed to be already in the resource.  We then
  379.      * append the desk accessory names from the 'DRVR' resources.
  380.      */
  381.     MyMenus[appleMenu] = GetMenu(appleID);
  382.     AddResMenu(MyMenus[appleMenu], (ResType) 'DRVR');
  383.     /*
  384.      * Now the File and Edit menus.
  385.      */
  386.     MyMenus[fileMenu] = GetMenu(fileID);
  387.     MyMenus[editMenu] = GetMenu(editID);
  388.     /*
  389.      * Now insert all of the application menus in the menu bar.
  390.      */
  391.     for (pMenu = &MyMenus[0]; pMenu < &MyMenus[menuCount]; ++pMenu) {
  392.         InsertMenu(*pMenu, 0);
  393.     }
  394.  
  395.     DrawMenuBar();
  396.  
  397.     return;
  398. }
  399.  
  400. /*
  401.  * Back to the Main segment.
  402.  */
  403. # define    __SEG__ Main
  404.  
  405. showAboutMeDialog()
  406. {
  407.     DialogPtr    theDialog;
  408.     short        itemType;
  409.     Handle        itemHdl;
  410.     Rect        itemRect;
  411.     short        itemHit;
  412.  
  413.     theDialog = GetNewDialog(aboutMeDLOG, nil, (WindowPtr) -1);
  414.     do {
  415.         ModalDialog(nil, &itemHit);
  416.     } while (itemHit != okButton);
  417.  
  418.     DisposDialog(theDialog);
  419.  
  420.     return;
  421. }
  422. /*****************************************************************/
  423. /* get a new user name and insert it into the list
  424. */
  425. donewuser()
  426.     {
  427.     DialogPtr    theDialog;
  428.     short        itemType;
  429.     Handle        itemHdl;
  430.     Rect        itemRect;
  431.     short        itemHit;
  432.  
  433.     theDialog = GetNewDialog(newuDLOG, nil, (WindowPtr) -1);
  434.     do {
  435.         ModalDialog(nil, &itemHit);
  436.         if (itemHit == 4 /* cancel */) {
  437.             DisposDialog(theDialog);
  438.             return(0);
  439.         }
  440.     } while (itemHit != okButton);
  441.  
  442.     GetDItem(theDialog, 3, &itemType, &itemHdl, &itemRect);
  443.     GetIText(itemHdl, s);
  444.     DisposDialog(theDialog);
  445.  
  446.     if (s[0])                /* if there was a user name typed */
  447.         adduser(s);
  448.  
  449. }
  450.  
  451. /*****************************************************************/
  452. /* get a new passwd and insert it into the list
  453. */
  454. int nchars;
  455. char lastpass[256];
  456.  
  457. pascal Boolean
  458. pfilt(td,tdevent,itemhit)
  459.     DialogPtr td;
  460.     EventRecord *tdevent;
  461.     short int *itemhit;
  462.     {
  463.     short        itemType;
  464.     Handle        itemHdl;
  465.     Rect        itemRect;
  466.     int c,i;
  467.     
  468.     switch(tdevent->what) {
  469.         case keyDown:
  470.         case autoKey:
  471.             if ((c = (tdevent->message & charCodeMask)) > 31) {
  472.                 if (nchars < 200)
  473.                     lastpass[nchars++] = c;
  474.                 lastpass[nchars] = 0;
  475.                 *itemhit = 2;
  476.             }
  477.             else if (c == 13) {
  478.                 *itemhit = 1;
  479.             }
  480.             else if (c == 8) {
  481.                 if (nchars > 0)
  482.                     nchars--;
  483.                 lastpass[nchars] = 0;
  484.                 *itemhit = 2;
  485.             }
  486.             GetDItem(td, 2, &itemType, &itemHdl, &itemRect);
  487.             for (i=0; i< nchars; i++)
  488.                 s[i] = '╞';
  489.             s[nchars] = 0;
  490.             SetIText(itemHdl, s);
  491.             return(true);
  492.             break;
  493.         default:
  494.             break;
  495.     }
  496.     
  497.     *itemhit=0;
  498.     return(false);                
  499.  
  500. }
  501.  
  502. donewpass()
  503.     {
  504.     DialogPtr    theDialog;
  505.     short        itemType;
  506.     Handle        itemHdl;
  507.     Rect        itemRect;
  508.     short        itemHit;
  509.     char *p,*strchr();
  510.  
  511.     csize.h = csize.v = 0;
  512.     if (!LGetSelect(true, &csize, mylist)) 
  513.         return(0);            /* no user selected to receive passwd */
  514.         
  515.     theDialog = GetNewDialog(newpDLOG, nil, (WindowPtr) -1);
  516.     nchars = 0;
  517. /*
  518. *  set username into dialog
  519. */
  520.     GetDItem(theDialog, 5, &itemType, &itemHdl, &itemRect);
  521.     strcpy(s, lines[csize.v]);
  522.     p = strchr(s,':');                /* find ':' and truncate */
  523.     *p = 0;
  524.     SetIText(itemHdl, s);
  525.     
  526.     do {
  527.         ModalDialog(pfilt, &itemHit);
  528.         if (itemHit == 3 /* cancel */) {
  529.             DisposDialog(theDialog);
  530.             return(0);
  531.         }
  532.     } while (itemHit != okButton);
  533.  
  534.     DisposDialog(theDialog);
  535. /*
  536. *  install the new password, it is now in lastpass
  537. *  Have to find which username it goes with first
  538. */
  539.     if (nchars < 1)
  540.         return(0);
  541.     
  542.     if (csize.v >= 0)
  543.         dochoice(csize.v,lastpass);    
  544.     
  545. }
  546.  
  547. /*
  548.  * Process mouse clicks in menu bar
  549.  */
  550. void
  551. doCommand(mResult)
  552. long mResult;
  553. {
  554.     extern MenuHandle    MyMenus[];
  555.     extern Boolean        DoneFlag;
  556.     extern TEHandle     TextH;
  557.     int                 theMenu, theItem,i;
  558.     char                daName[256];
  559.     GrafPtr             savePort;
  560.  
  561.     theItem = LOWORD(mResult);
  562.     theMenu = HIWORD(mResult);        /* This is the resource ID */
  563.  
  564.     switch (theMenu) {
  565.         case appleID:
  566.             if (theItem == aboutMeCommand) {
  567.                 showAboutMeDialog();
  568.             } else {
  569.                 GetItem(MyMenus[appleMenu], theItem, daName);
  570.                 GetPort(&savePort);
  571.                 (void) OpenDeskAcc(daName);
  572.                 SetPort(savePort);
  573.             }
  574.             break;
  575.  
  576.         case fileID:
  577.             switch (theItem) {
  578.                 case openCommand:
  579.                     if (strlen(currentfile) > 0)
  580.                         passwrite(currentfile);
  581.                     wh.h = wh.v = 50;
  582.                     tlst[0] = mytype;
  583.                     SFGetFile(&wh, "Select password file", nil, 1, tlst,
  584.                               nil, &reply);
  585.                     if (reply.good) {
  586.                         reply.fName.text[reply.fName.length] = 0;
  587.                         passlist(reply.fName.text);        /* load this file */
  588.                     }
  589.                     
  590.                     break;
  591.                 case saveCommand:
  592.                 case newCommand:
  593.                     if (strlen(currentfile) > 0)
  594.                         passwrite(currentfile);
  595.                     else
  596.                         saveit();
  597.                     if (theItem == newCommand) {
  598.                         clearit();
  599.                         currentfile[0] = 0;
  600.                         SetWTitle( myWindow, "Telpass: Untitled");
  601.                     }
  602.                     break;
  603.                 case saveasCommand:
  604.                     saveit();
  605.                     break;
  606.                 case quitCommand:
  607.                     DoneFlag = true;            /* Request exit */
  608.                     break;
  609.                 default:
  610.                     break;
  611.             }
  612.             if (strlen(currentfile) > 0) {
  613.                 strcpy(s,"Telpass: ");
  614.                 strcat(s,currentfile);
  615.                 SetWTitle( myWindow, s);
  616.             }
  617.             break;
  618.         case editID:
  619.             /*
  620.              * If this is for a 'standard' edit item,
  621.              * run it through SystemEdit first.
  622.              * SystemEdit will return FALSE if it's not a system window.
  623.              */
  624.             if ((theItem <= clearCommand) && SystemEdit(theItem-1)) {
  625.                 break;
  626.             }
  627.             /*
  628.              * Otherwise, it's my window.
  629.              */
  630.             switch (theItem) {
  631.                 case undoCommand:
  632.                     break;
  633.                 case cutCommand:
  634.                 case copyCommand:
  635.                     ZeroScrap();
  636.                     break;
  637.                 case pasteCommand:
  638.                     break;
  639.                 case clearCommand:
  640.                     break;
  641.                 default:
  642.                     break;
  643.             } /*endsw theItem*/
  644.             break;
  645.  
  646.         default:
  647.             break;
  648.  
  649.     }/*endsw theMenu*/
  650.  
  651.     HiliteMenu(0);
  652.  
  653.     return;
  654. }
  655.  
  656.  
  657. char space[256];
  658. char space2[256],*p;
  659.  
  660. FILE *fout,*fin;
  661.  
  662. int nnames;
  663.  
  664. /****************************************************************************/
  665. /* dodelete
  666. *  remove an entry from the list manager and from the storage list
  667. */
  668. dodelete()
  669.     {
  670.     int i;
  671.     
  672.     csize.v = csize.h = 0;
  673.     if (LGetSelect(true, &csize, mylist)) {
  674.         LDelRow( 1, csize.v, mylist);
  675.         if (csize.v >= nnames-1)
  676.             csize.v--;
  677.         LSetSelect(true, &csize, mylist);    /* reselect next one */
  678.         for (i=csize.v; i<nnames-1; i++)     /* maybe deallocate mem someday? */
  679.             lines[i] = lines[i+1];
  680.         nnames--;
  681.     }
  682.     
  683. }
  684.             
  685. /****************************************************************************/
  686. /* dochoice
  687. *  prompt for a certain password
  688. */
  689. dochoice(c,newpass)
  690.     int c;
  691.     char newpass[];
  692.     {
  693.     char *p,*strchr();
  694.     char space[256],space2[256];
  695.  
  696.     strcpy(space,lines[c]);
  697.  
  698.     do {
  699.         p = strchr(space,':');
  700.         if (!p)
  701.             strcat(space,":");
  702.     } while (!p);                        /* make sure we get a : */
  703.  
  704.     *p = '\0';
  705.     p++;
  706.     Sencompass(newpass,space2);                /* take password */
  707.     sprintf(s,"%s:%s",space,space2);
  708.     lines[c] = malloc(strlen(s)+1);
  709.     strcpy(lines[c],s);                    /* this string includes passwd */
  710.     
  711.     strcat(space,":╞");                    /* indicate passwd present */
  712.     LSetCell(space,strlen(space), &csize, mylist);
  713.     
  714. }
  715.  
  716. /****************************************************************************/
  717. /* passwrite
  718. *  write them out
  719. */
  720. passwrite(s)
  721.     char *s;
  722.     {
  723.     int i;
  724.     short int vref;
  725.     FInfo finf;
  726.     String(255) vname;
  727.     
  728.     if (strlen(s) == 0)
  729.         return(0);
  730.  
  731.     if (NULL == (fout = fopen(s,"w"))) {
  732.         return(0);
  733.     }
  734.  
  735.     for (i=0; i < nnames; i++) {
  736.         fputs(lines[i],fout);
  737.         fputs("\n",fout);
  738.     }
  739.  
  740.     fclose(fout);
  741.     
  742. /*
  743. *  set correct creator and type
  744. */
  745.     GetVol( &vname, &vref);
  746.     GetFInfo(s, vref, &finf);
  747.     finf.fdType = mytype;
  748.     finf.fdCreator = mycreator;
  749.     SetFInfo(s, vref, &finf);
  750. }
  751.  
  752. /****************************************************************************/
  753. /* clearit
  754. *  Clear the current list
  755. *  Write the current file out if we have a current file name
  756. */
  757. clearit()
  758.     {
  759.     ListPtr l;        /* temp use */
  760.  
  761.     passwrite(currentfile);
  762.     
  763.     LDispose(mylist);        /* loading new list, delete old one */
  764.     
  765.     csize.h = 200; csize.v = 15;
  766.     nnames = 0;
  767.     
  768. mylist = LNew( &rview,&dbounds, &csize, 0, myWindow, true,false,false,true);
  769.     l = *mylist;
  770.     l->selFlags |= lOnlyOne;        /* only one selection at a time */
  771.  
  772.     SetPort(myWindow);            /* make my window the current port */    
  773.     EraseRect(&rframe);
  774.     InvalRect(&rframe);
  775. }
  776.  
  777. /****************************************************************************/
  778. /* saveit
  779. *  Use the file picker to save out the current file
  780. */
  781. saveit()
  782.     {
  783.  
  784.     if (nnames <= 0)
  785.         return;
  786.         
  787.     wh.v = wh.h = 50;
  788.     SFPutFile(&wh, "Save password file as:", currentfile, nil, &reply);
  789.     if (reply.good) {
  790.         reply.fName.text[reply.fName.length] = 0;
  791.         passwrite(reply.fName.text);
  792.         strcpy(currentfile,reply.fName.text);
  793.     }
  794. }
  795.  
  796. /****************************************************************************/
  797. /*  passlist
  798. *   List the current file
  799. */
  800. passlist(s)
  801.     char *s;
  802.     {
  803.     char space[256];
  804.  
  805.     clearit();
  806.     strcpy(currentfile,s);
  807.     
  808.     if (NULL == (fin = fopen(s,"r"))) {
  809.         return(0);
  810.     }
  811.     nnames = 0;
  812.  
  813.     while (NULL != fgets(space,250,fin)) {
  814.         space[strlen(space)-1] = '\0';
  815.         adduser(space);
  816.     }
  817.     
  818.     InvalRect(&rframe);        /* make it draw right */
  819.  
  820.     fclose(fin);
  821.     
  822. }
  823.  
  824. /****************************************************************************/
  825. /* adduser
  826. *  add a new user to the list
  827. */
  828. adduser(p)
  829.     char *p;
  830.     {
  831.     char space[256];
  832.  
  833.     lines[nnames] = malloc(strlen(p)+1);    /* memory copy includes the password */
  834.     strcpy(lines[nnames],p);
  835.         
  836.     strcpy(space,p);
  837.  
  838.     do {
  839.         p = strchr(space,':');
  840.         if (!p)
  841.             strcat(space,":");
  842.     } while (!p);                        /* make sure we get a : */
  843.     p++;                                /* point past : */
  844.     if (*p)
  845.         *p = '╞';
  846.     else
  847.         *p = 0;
  848.     *(++p) = 0;                            /* end string */
  849. /*
  850. *  when adding to the list manager, replace ugly password with a symbol
  851. */
  852.         LAddRow(1,nnames, mylist);
  853.         csize.h = 0; csize.v = nnames;
  854.         LSetCell(space,strlen(space), &csize, mylist);
  855.         LDraw(&csize,mylist);
  856.         nnames++;
  857.     csize.h = 0; csize.v = nnames;
  858.  
  859. }
  860.  
  861. /****************************************************************************/
  862. /* Scompass
  863. *  compute and check the encrypted password
  864. */
  865. Sencompass(ps,en)
  866.     char *ps,*en;
  867.     {
  868.     int i,ck;
  869.     char *p,c;
  870.  
  871.     ck = 0;
  872.     p = ps;
  873.     while (*p)                /* checksum the string */
  874.         ck += *p++;
  875.  
  876.     c = ck;
  877.  
  878.     for (i=0; i<10; i++) {
  879.         *en =  (((*ps ^ c) | 32) & 127);     /* XOR with checksum */
  880.         if (*ps)
  881.             ps++;
  882.         else
  883.             c++;        /* to hide length */
  884.         en++;
  885.     }
  886.  
  887.     *en = 0;
  888.  
  889. }
  890.