;/* Execute me to compile gcc -g AmiSafe.c -o AmiSafe -lauto quit ;*/ /* * AmiSafe password enryption for safety * Written by Scott A. Cabit November 2011/2012 * */ //#define DEBUG #include <sys/types.h> #include <exec/exec.h> #include <intuition/intuition.h> #include <intuition/gui.h> #include <intuition/icclass.h> #include <dos/dos.h> #include <string.h> #include <images/label.h> #include <classes/window.h> #include <classes/requester.h> #include <stdio.h> #include <stdlib.h> #include <gadgets/fuelgauge.h> #include <gadgets/layout.h> #include <gadgets/texteditor.h> #include <gadgets/radiobutton.h> #include <gadgets/chooser.h> #include <gadgets/integer.h> #include <gadgets/clicktab.h> #include <gadgets/listbrowser.h> #include <libraries/keymap.h> /* * Autoinit takes care of these */ #include <proto/exec.h> #include <proto/dos.h> #include <proto/intuition.h> #include <proto/label.h> #include <proto/listbrowser.h> /* * Simply include the proto file for all ReAction classes you intent to use * to trigger their autoinitialization. */ #include <proto/fuelgauge.h> #include <proto/window.h> #include <proto/layout.h> #include <proto/texteditor.h> #include <proto/radiobutton.h> #include <proto/chooser.h> #include <proto/checkbox.h> #include <proto/integer.h> #include <proto/space.h> #include <proto/clicktab.h> #include <proto/requester.h> #include <proto/utility.h> #include <reaction/reaction_macros.h> #include <stdlib.h> #include <string.h> #include <stdarg.h> Object *win; Object *lb_gad = NULL; struct MsgPort *AppPort; struct List listbrowser_list1; struct ColumnInfo *columninfo1 = NULL; struct List listbrowser_list2; struct ColumnInfo *columninfo2 = NULL; struct List listbrowser_list3; struct ColumnInfo *columninfo3 = NULL; struct List listbrowser_list4; struct ColumnInfo *columninfo4 = NULL; STRPTR PageLabels[] = { "Credit or Bank Cards", " Internet Passwords ", " Other Passwords ", " Insurance Policies ", NULL }; #define STRSIZE 40 #define MAXENTRIES 100 #define COLSTAB1 5 #define COLSTAB2 3 #define COLSTAB3 2 #define COLSTAB4 3 /* STATIC BYTE Tab1Data[bufsize]; STATIC BYTE Tab2Data[bufsize]; STATIC BYTE Tab3Data[bufsize]; STATIC BYTE Tab4Data[bufsize]; */ // Arrays of text data for each tab STRPTR Tab1Strings[MAXENTRIES]; STRPTR Tab2Strings[MAXENTRIES]; STRPTR Tab3Strings[MAXENTRIES]; STRPTR Tab4Strings[MAXENTRIES]; /* * This enum generates the unique ID's we need both for * GadgetID's as well as for the index into our objects * array. You might want to use separate variables (we * did so for the window object) or use this method. * Note that not all objects need an id, and not all * objects need to be stored (Layout groups for example). * Essentially only store object pointers that you need * to manipulate from your program. */ enum { /* -- other controls -- */ OBJ_CLICKTAB, OBJ_LISTBROWSER1, OBJ_LISTBROWSER2, OBJ_LISTBROWSER3, OBJ_LISTBROWSER4, OBJ_ADD, OBJ_DELETE, OBJ_ABOUT, OBJ_NUM }; /* * This array will hold the objects we create. The two macros * below are for convenience. */ Object *Objects[OBJ_NUM]; #define OBJ(x) Objects[x] #define GAD(x) (struct Gadget *)Objects[x] BOOL make_browserlist(struct List *, char ** , int ); /* Quite handy */ #define SPACE LAYOUT_AddChild, SpaceObject, End Object * make_window(void) { columninfo1 = IListBrowser->AllocLBColumnInfo(COLSTAB1, LBCIA_Column, 0, LBCIA_Title, " Name", LBCIA_Width, 40, LBCIA_AutoSort, TRUE, LBCIA_SortArrow, TRUE, LBCIA_Column, 1, LBCIA_Title, " Number", LBCIA_Width, 20, LBCIA_AutoSort, TRUE, LBCIA_SortArrow, TRUE, LBCIA_Column, 2, LBCIA_Title, " Exp Date", LBCIA_Width, 8, LBCIA_AutoSort, TRUE, LBCIA_SortArrow, TRUE, LBCIA_Column, 3, LBCIA_Title, " PIN", LBCIA_Width, 8, LBCIA_AutoSort, TRUE, LBCIA_SortArrow, TRUE, LBCIA_Column, 4, LBCIA_Title, " Phone", LBCIA_Width, 14, LBCIA_AutoSort, TRUE, LBCIA_SortArrow, TRUE, TAG_DONE); columninfo2 = IListBrowser->AllocLBColumnInfo(3, LBCIA_Column, 0, LBCIA_Title, " Title", LBCIA_Width, 40, LBCIA_AutoSort, TRUE, LBCIA_SortArrow, TRUE, LBCIA_Column, 1, LBCIA_Title, " URL", LBCIA_Width, 80, LBCIA_AutoSort, TRUE, LBCIA_SortArrow, TRUE, LBCIA_Column, 2, LBCIA_Title, " Password", LBCIA_Width, 80, LBCIA_AutoSort, TRUE, LBCIA_SortArrow, TRUE, TAG_DONE); columninfo3 = IListBrowser->AllocLBColumnInfo(2, LBCIA_Column, 0, LBCIA_Title, " Item", LBCIA_Width, 80, LBCIA_AutoSort, TRUE, LBCIA_SortArrow, TRUE, LBCIA_Column, 1, LBCIA_Title, " Password", LBCIA_Width, 20, LBCIA_AutoSort, TRUE, LBCIA_SortArrow, TRUE, TAG_DONE); columninfo4 = IListBrowser->AllocLBColumnInfo(3, LBCIA_Column, 0, LBCIA_Title, " Company", LBCIA_Width, 40, LBCIA_AutoSort, TRUE, LBCIA_SortArrow, TRUE, LBCIA_Column, 1, LBCIA_Title, " Policy Number", LBCIA_Width, 30, LBCIA_AutoSort, TRUE, LBCIA_SortArrow, TRUE, LBCIA_Column, 2, LBCIA_Title, " Phone Number", LBCIA_Width, 24, LBCIA_AutoSort, TRUE, LBCIA_SortArrow, TRUE, TAG_DONE); /* * Page 1: Credit Cards * * Page 2: Internet * * Page 3: Others * * Page 4: Insurance Policies */ Object *page1 = NULL, *page2 = NULL, *page3 = NULL, *page4 = NULL; page1 = VLayoutObject, LAYOUT_AddChild, HLayoutObject, /* BevelStyle sets the style of the group border to BVS_GROUP, * which is the standard group frame. The Label tags gives a * text string to be displayed embedded into the frame. */ LAYOUT_BevelStyle, BVS_GROUP, LAYOUT_Label, "Credit or Bank Card Info", /* LAYOUT_AddChild adds a new child into the group. Depending * on the layout parameter (horizontal vs. vertical) the * objects are placed next to each other, or stacked one * above the other. */ LAYOUT_AddChild, OBJ(OBJ_LISTBROWSER1) = IIntuition->NewObject(NULL, "listbrowser.gadget", GA_ID, OBJ_LISTBROWSER1, GA_RelVerify, TRUE, GA_TabCycle, TRUE, LISTBROWSER_AutoFit, TRUE, LISTBROWSER_Labels, &listbrowser_list1, LISTBROWSER_ColumnInfo, columninfo1, LISTBROWSER_ColumnTitles, TRUE, LISTBROWSER_TitleClickable,TRUE, LISTBROWSER_ShowSelected, TRUE, LISTBROWSER_Editable, TRUE, LISTBROWSER_Striping, LBS_ROWS, TAG_DONE), End, /* HLayoutObject */ End; /* VLayoutObject */ page2 = VLayoutObject, LAYOUT_AddChild, HLayoutObject, LAYOUT_BevelStyle, BVS_GROUP, LAYOUT_Label, "Internet Passwords", LAYOUT_AddChild, OBJ(OBJ_LISTBROWSER2) = IIntuition->NewObject(NULL, "listbrowser.gadget", GA_ID, OBJ_LISTBROWSER2, GA_RelVerify, TRUE, GA_TabCycle, TRUE, LISTBROWSER_AutoFit, TRUE, LISTBROWSER_Labels, &listbrowser_list2, LISTBROWSER_ColumnInfo, columninfo2, LISTBROWSER_ColumnTitles, TRUE, LISTBROWSER_TitleClickable,TRUE, LISTBROWSER_ShowSelected, TRUE, LISTBROWSER_Editable, TRUE, LISTBROWSER_Striping, LBS_ROWS, TAG_DONE), End, /* HLayout */ End; /* VLayout */ page3 = VLayoutObject, LAYOUT_AddChild, HLayoutObject, LAYOUT_BevelStyle, BVS_GROUP, LAYOUT_Label, "Other Passwords", LAYOUT_AddChild, OBJ(OBJ_LISTBROWSER3) = IIntuition->NewObject(NULL, "listbrowser.gadget", GA_ID, OBJ_LISTBROWSER3, GA_RelVerify, TRUE, GA_TabCycle, TRUE, LISTBROWSER_AutoFit, TRUE, LISTBROWSER_Labels, &listbrowser_list3, LISTBROWSER_ColumnInfo, columninfo3, LISTBROWSER_ColumnTitles, TRUE, LISTBROWSER_TitleClickable,TRUE, LISTBROWSER_ShowSelected, TRUE, LISTBROWSER_Editable, TRUE, LISTBROWSER_Striping, LBS_ROWS, TAG_DONE), End, /* HLayout */ End; /* VLayout */ page4 = VLayoutObject, LAYOUT_AddChild, HLayoutObject, LAYOUT_BevelStyle, BVS_GROUP, LAYOUT_Label, "Insurance Policies", LAYOUT_AddChild, OBJ(OBJ_LISTBROWSER4) = IIntuition->NewObject(NULL, "listbrowser.gadget", GA_ID, OBJ_LISTBROWSER4, GA_RelVerify, TRUE, GA_TabCycle, TRUE, LISTBROWSER_AutoFit, TRUE, LISTBROWSER_Labels, &listbrowser_list4, LISTBROWSER_ColumnInfo, columninfo4, LISTBROWSER_ColumnTitles, TRUE, LISTBROWSER_TitleClickable,TRUE, LISTBROWSER_ShowSelected, TRUE, LISTBROWSER_Editable, TRUE, LISTBROWSER_Striping, LBS_ROWS, TAG_DONE), End, /* HLayout */ End; /* VLayout */ /* * A clicktab object is a controller for the page object. It's the * register card type gadget along the top of the resultiong dialog. * The GA_Text tag points to the STRPTR array with the labels to * display (plain ascii text in this case), and the pagegroup is * a special case of group that only displays one child at a time. * * This way we can select exactly one of the above pages as a time. */ OBJ(OBJ_CLICKTAB) = ClickTabObject, GA_Text, PageLabels, CLICKTAB_Current, 0, CLICKTAB_PageGroup, PageObject, PAGE_Add, page1, PAGE_Add, page2, PAGE_Add, page3, PAGE_Add, page4, End, /* PageObject */ End; /* ClickTab */ /* * This will generate our window object. The content of the window * is specified with the WINDOW_ParentGroup. We make this a VLayout * because we want to place our clicktabbed group above a row of * additional buttons (Print, Cancel and Help). */ return WindowObject, WA_Title, "AmiSafe Password Protection for Amiga OS4", WA_DragBar, TRUE, WA_SmartRefresh, TRUE, WA_CloseGadget, TRUE, WA_SizeGadget, TRUE, WA_DepthGadget, TRUE, WA_Activate, TRUE, WA_InnerWidth, 400, WA_InnerHeight, 400, WA_Opaqueness, 255, /* Initial opaqueness on opening (0..255) */ WA_OverrideOpaqueness, TRUE, /* Override global settings? (TRUE|FALSE) */ WA_FadeTime, 500000, /* Duration of transition in microseconds */ WINDOW_GadgetHelp, TRUE, WINDOW_IconifyGadget, TRUE, WINDOW_IconTitle, "AmiSafe", WINDOW_AppPort, AppPort, WINDOW_Position, WPOS_CENTERSCREEN, WINDOW_ParentGroup, VLayoutObject, LAYOUT_AddChild, OBJ(OBJ_CLICKTAB), /* * This will be special because we want the group to * stay the same size vertically regardless of window size * and rather let the content above (the clicktabbed groups) * expand and take up the space. */ /* For that we first generate a group with horizontal layout * and add our buttons to it. Specifying LAYOUT_EvenSize will * make all buttons the same size, which looks nicer. */ LAYOUT_AddChild, HLayoutObject, LAYOUT_BevelStyle, BVS_SBAR_HORIZ, LAYOUT_EvenSize, TRUE, LAYOUT_AddChild, ButtonObject, GA_HintInfo, "Select this button to add a new entry", GA_ID, OBJ_ADD, GA_Text, "_Add Entry", GA_RelVerify, TRUE, End, /* Button */ LAYOUT_AddChild, ButtonObject, GA_HintInfo, "Select this button to delete the selected entry", GA_ID, OBJ_DELETE, GA_Text, "_Delete Entry", GA_RelVerify, TRUE, End, /* Button */ LAYOUT_AddChild, ButtonObject, GA_HintInfo, "Select this button for program information", GA_ID, OBJ_ABOUT, GA_Text, "_Help", GA_RelVerify, TRUE, End, /* Button */ End, /* HLayout */ CHILD_WeightedHeight, 0, End, /* VLayout */ End; /* WindowObject */ } uint32 MessageBoxA(char *gadgets, char *format, APTR args ) { Object *requester; char buffer[512]; uint32 result = 0; memset(buffer, 0, 512); IExec->RawDoFmt(format, args, NULL, buffer); requester = IIntuition->NewObject(IRequester->REQUESTER_GetClass(), NULL, REQ_Type, REQTYPE_INFO, REQ_TitleText, "Auto Sample", REQ_BodyText, buffer, REQ_GadgetText, gadgets, TAG_DONE); if (requester) { result = IIntuition->IDoMethod( requester, RM_OPENREQ, NULL, NULL, NULL ); IIntuition->DisposeObject(requester); } return result; } uint32 VARARGS68K MessageBox(char *gadgets, char *format, ...) { va_list ap; LONG result; va_startlinear (ap, format); result = MessageBoxA(gadgets, format, va_getlinearva(ap,void*) ); va_end(ap); return result; } BOOL WriteBrowserList(struct List *browserlist, u_char columns, FILE *Outfile) { struct Node *currentNode; STRPTR Text1; STRPTR Text2; STRPTR Text3; STRPTR Text4; STRPTR Text5; char temp[500]; currentNode = IExec->GetHead(browserlist); while(currentNode != NULL) { switch(columns) { case 2: IListBrowser->GetListBrowserNodeAttrs(currentNode, LBNA_Column, 0, LBNCA_Text, &Text1, LBNA_Column, 1, LBNCA_Text, &Text2, TAG_DONE); sprintf(temp,"%s\n",Text1); fputs(temp,Outfile); sprintf(temp,"%s\n",Text2); fputs(temp,Outfile); break; case 3: IListBrowser->GetListBrowserNodeAttrs(currentNode, LBNA_Column, 0, LBNCA_Text, &Text1, LBNA_Column, 1, LBNCA_Text, &Text2, LBNA_Column, 2, LBNCA_Text, &Text3, TAG_DONE); sprintf(temp,"%s\n",Text1); fputs(temp,Outfile); sprintf(temp,"%s\n",Text2); fputs(temp,Outfile); sprintf(temp,"%s\n",Text3); fputs(temp,Outfile); break; case 4: IListBrowser->GetListBrowserNodeAttrs(currentNode, LBNA_Column, 0, LBNCA_Text, &Text1, LBNA_Column, 1, LBNCA_Text, &Text2, LBNA_Column, 2, LBNCA_Text, &Text3, LBNA_Column, 3, LBNCA_Text, &Text4, TAG_DONE); sprintf(temp,"%s\n",Text1); fputs(temp,Outfile); sprintf(temp,"%s\n",Text2); fputs(temp,Outfile); sprintf(temp,"%s\n",Text3); fputs(temp,Outfile); sprintf(temp,"%s\n",Text4); fputs(temp,Outfile); break; case 5: IListBrowser->GetListBrowserNodeAttrs(currentNode, LBNA_Column, 0, LBNCA_Text, &Text1, LBNA_Column, 1, LBNCA_Text, &Text2, LBNA_Column, 2, LBNCA_Text, &Text3, LBNA_Column, 3, LBNCA_Text, &Text4, LBNA_Column, 4, LBNCA_Text, &Text5, TAG_DONE); sprintf(temp,"%s\n",Text1); fputs(temp,Outfile); sprintf(temp,"%s\n",Text2); fputs(temp,Outfile); sprintf(temp,"%s\n",Text3); fputs(temp,Outfile); sprintf(temp,"%s\n",Text4); fputs(temp,Outfile); sprintf(temp,"%s\n",Text5); fputs(temp,Outfile); break; default: IDOS->Printf(" Invalid number of columns for write!\n"); return(FALSE); } // switch(columns) currentNode = IExec->GetSucc(currentNode); } // while currentNode != NULL return(TRUE); } /* Count the number of nodes (rows) in a browserlist and return it */ u_char CountNodes(struct List *browserlist) { struct Node *currentNode; u_char i=0; currentNode = IExec->GetHead(browserlist); while(currentNode != NULL) { currentNode = IExec->GetSucc(currentNode); i++; } return i; } /* Add a new empty node to a browser list */ BOOL AddNode(struct Window * window, uint32 tabnum) { struct Node *node; struct List *browserlist; int columns; // Detach the listbrowser list first switch (tabnum + 1) { case 1: IIntuition->SetAttrs(OBJ(OBJ_LISTBROWSER1), LISTBROWSER_Labels, NULL, TAG_DONE); columns = COLSTAB1; browserlist = (struct List *)&listbrowser_list1; break; case 2: IIntuition->SetAttrs(OBJ(OBJ_LISTBROWSER2), LISTBROWSER_Labels, NULL, TAG_DONE); columns = COLSTAB2; browserlist = (struct List *)&listbrowser_list2; break; case 3: IIntuition->SetAttrs(OBJ(OBJ_LISTBROWSER3), LISTBROWSER_Labels, NULL, TAG_DONE); columns = COLSTAB3; browserlist = (struct List *)&listbrowser_list3; break; case 4: IIntuition->SetAttrs(OBJ(OBJ_LISTBROWSER4), LISTBROWSER_Labels, NULL, TAG_DONE); columns = COLSTAB4; browserlist = (struct List *)&listbrowser_list4; break; default: IDOS->Printf(" Invalid tab number passed to AddNode()\n"); return(FALSE); break; } // end switch (tabnum) switch (columns) { case COLSTAB3: if (node = IListBrowser->AllocListBrowserNode(columns, LBNA_Column, 0, LBNCA_Text, "New data", LBNCA_Editable, TRUE, LBNCA_CopyText, TRUE, LBNCA_MaxChars, 30, LBNA_Column, 1, LBNCA_Text, "", LBNCA_Editable, TRUE, LBNCA_CopyText, TRUE, LBNCA_MaxChars, 30, (TAG_DONE))) { IExec->AddTail(browserlist, node); } else { IDOS->Printf(" AllocListBrowserNode() failed\n"); return(FALSE); } break; case COLSTAB2: if (node = IListBrowser->AllocListBrowserNode(columns, LBNA_Column, 0, LBNCA_Text, "New data", LBNCA_Editable, TRUE, LBNCA_CopyText, TRUE, LBNCA_MaxChars, 30, LBNA_Column, 1, LBNCA_Text, "", LBNCA_Editable, TRUE, LBNCA_CopyText, TRUE, LBNCA_MaxChars, 30, LBNA_Column, 2, LBNCA_Text, "", LBNCA_Editable, TRUE, LBNCA_CopyText, TRUE, LBNCA_MaxChars, 30, (TAG_DONE))) { IExec->AddTail(browserlist, node); } else { IDOS->Printf(" AllocListBrowserNode() failed\n"); return(FALSE); } break; case COLSTAB1: if (node = IListBrowser->AllocListBrowserNode(columns, LBNA_Column, 0, LBNCA_Text, "New data", LBNCA_Editable, TRUE, LBNCA_CopyText, TRUE, LBNCA_MaxChars, 30, LBNA_Column, 1, LBNCA_Text, "", LBNCA_Editable, TRUE, LBNCA_CopyText, TRUE, LBNCA_MaxChars, 30, LBNA_Column, 2, LBNCA_Text, "", LBNCA_Editable, TRUE, LBNCA_CopyText, TRUE, LBNCA_MaxChars, 30, LBNA_Column, 3, LBNCA_Text, "", LBNCA_Editable, TRUE, LBNCA_CopyText, TRUE, LBNCA_MaxChars, 30, LBNA_Column, 4, LBNCA_Text, "", LBNCA_Editable, TRUE, LBNCA_CopyText, TRUE, LBNCA_MaxChars, 30, (TAG_DONE))) { IExec->AddTail(browserlist, node); } else { IDOS->Printf(" AllocListBrowserNode() failed\n"); return(FALSE); } break; default: IDOS->Printf(" Invalid number of list fields\n"); return(FALSE); break; }; // switch(columns) /* Re-attach the listbrowser and force intuition * to refresh the gadget imagery. */ switch (tabnum + 1) { case 1: IIntuition->SetGadgetAttrs((struct Gadget *)OBJ(OBJ_LISTBROWSER1), window, NULL, LISTBROWSER_Labels, browserlist, TAG_END); break; case 2: IIntuition->SetGadgetAttrs((struct Gadget *)OBJ(OBJ_LISTBROWSER2), window, NULL, LISTBROWSER_Labels, browserlist, TAG_END); break; case 3: IIntuition->SetGadgetAttrs((struct Gadget *)OBJ(OBJ_LISTBROWSER3), window, NULL, LISTBROWSER_Labels, browserlist, TAG_END); break; case 4: IIntuition->SetGadgetAttrs((struct Gadget *)OBJ(OBJ_LISTBROWSER4), window, NULL, LISTBROWSER_Labels, browserlist, TAG_END); break; default: IDOS->Printf("Invalid tab number passed to AddNode()\n"); break; } return(TRUE); } void LoadFile() { FILE *Infile; u_char length1,length2,length3,length4; char mystring[100]; BOOL FILEOK = TRUE; int i,j; Infile = fopen("AmiSafe.dat", "r"); if(Infile == 0) { FILEOK = FALSE; } else // read in parameter data { // Read Tab #1 Info if(!feof(Infile)) { length1 = fgetc(Infile); #ifdef DEBUG IDOS->Printf("Tab 1 has %lu entries\n",length1); #endif IExec->NewList((struct List *)&listbrowser_list1); i = 0; while(length1 > 0) { j = COLSTAB1; while(j > 0) { fgets(mystring, 100, Infile); if(feof(Infile)) { FILEOK = FALSE; goto CloseFile; } mystring[strlen(mystring)-1] = 0; // convert \n to 0 strcpy(Tab1Strings[i++], mystring); j--; } length1--; } Tab1Strings[i] = 0; // add tail null #ifdef DEBUG IDOS->Printf("Created First tab data\n"); #endif if(!make_browserlist(&listbrowser_list1, (char **)Tab1Strings, COLSTAB1)) IDOS->Printf("Failed to create browserlist Tab1\n"); } else { IDOS->Printf("No Valid File Data for Tab1!\n"); FILEOK = FALSE; goto CloseFile; } // Read Tab #2 Info if(!feof(Infile)) { length2 = fgetc(Infile); #ifdef DEBUG IDOS->Printf("Tab 2 has %lu entries\n",length2); #endif IExec->NewList((struct List *)&listbrowser_list2); i = 0; while(length2 > 0) { j = COLSTAB2; while(j > 0) { fgets(mystring, 100, Infile); if(feof(Infile)) { FILEOK = FALSE; goto CloseFile; } mystring[strlen(mystring)-1] = 0; // convert \n to 0 strcpy(Tab2Strings[i++], mystring); j--; } length2--; } Tab2Strings[i] = 0; // add tail null #ifdef DEBUG IDOS->Printf("Created Second tab data\n"); #endif if(!make_browserlist(&listbrowser_list2, (char **)Tab2Strings, COLSTAB2)) IDOS->Printf("Failed to create browserlist Tab2\n"); } else { IDOS->Printf("No Valid File Data for Tab2!\n"); FILEOK = FALSE; goto CloseFile; } // Read Tab #3 Info if(!feof(Infile)) { length3 = fgetc(Infile); #ifdef DEBUG IDOS->Printf("Tab 3 has %lu entries\n",length3); #endif IExec->NewList((struct List *)&listbrowser_list3); i = 0; while(length3 > 0) { j = COLSTAB3; while(j > 0) { fgets(mystring, 100, Infile); if(feof(Infile)) { FILEOK = FALSE; goto CloseFile; } mystring[strlen(mystring)-1] = 0; // convert \n to 0 strcpy(Tab3Strings[i++], mystring); j--; } length3--; } Tab3Strings[i] = 0; // add tail null #ifdef DEBUG IDOS->Printf("Created Third tab data\n"); #endif if(!make_browserlist(&listbrowser_list3, (char **)Tab3Strings, COLSTAB3)) IDOS->Printf("Failed to create browserlist Tab3\n"); } else { IDOS->Printf("No Valid File Data for Tab3!\n"); FILEOK = FALSE; goto CloseFile; } // Read Tab #4 Info if(!feof(Infile)) { length4 = fgetc(Infile); #ifdef DEBUG IDOS->Printf("Tab 4 has %lu entries\n",length4); #endif IExec->NewList((struct List *)&listbrowser_list4); i = 0; while(length4 > 0) { j = COLSTAB4; while(j > 0) { fgets(mystring, 100, Infile); if(feof(Infile)) { FILEOK = FALSE; goto CloseFile; } mystring[strlen(mystring)-1] = 0; // convert \n to 0 strcpy(Tab4Strings[i++], mystring); j--; } length4--; } Tab4Strings[i] = 0; // add tail null #ifdef DEBUG IDOS->Printf("Created Fourth tab data\n"); #endif if(!make_browserlist(&listbrowser_list4, (char **)Tab4Strings, COLSTAB4)) IDOS->Printf("Failed to create browserlist Tab4\n"); } else { IDOS->Printf("No Valid File Data for Tab4!\n"); FILEOK = FALSE; goto CloseFile; } } CloseFile: fclose(Infile); if(FILEOK == FALSE) { MessageBox("Continue","Unable to find a valid AmiSafe.dat input file.\n"\ "Creating an empty file."); // create an empty group of tabs here IExec->NewList((struct List *)&listbrowser_list1); IExec->NewList((struct List *)&listbrowser_list2); IExec->NewList((struct List *)&listbrowser_list3); IExec->NewList((struct List *)&listbrowser_list4); Tab1Strings[0] = 0; // add tail null Tab2Strings[0] = 0; // add tail null Tab3Strings[0] = 0; // add tail null Tab4Strings[0] = 0; // add tail null if(!make_browserlist(&listbrowser_list1, (char **)Tab1Strings, COLSTAB1)) IDOS->Printf("Failed to create browserlist Tab1\n"); if(!make_browserlist(&listbrowser_list2, (char **)Tab2Strings, COLSTAB2)) IDOS->Printf("Failed to create browserlist Tab2\n"); if(!make_browserlist(&listbrowser_list3, (char **)Tab3Strings, COLSTAB3)) IDOS->Printf("Failed to create browserlist Tab3\n"); if(!make_browserlist(&listbrowser_list4, (char **)Tab4Strings, COLSTAB4)) IDOS->Printf("Failed to create browserlist Tab4\n"); } } void SaveFile(STRPTR sfile) { FILE *Outfile; u_char length1,length2,length3,length4; Outfile = fopen(sfile, "w"); if(Outfile == 0) { MessageBox("UhOh!","Unable to open AmiSafe output file!\n"\ "Check to see if the file is write protected please!"); } else // write out Amisafe data { // count number of rows in each Listbrowser and save it for later length1 = CountNodes(&listbrowser_list1); length2 = CountNodes(&listbrowser_list2); length3 = CountNodes(&listbrowser_list3); length4 = CountNodes(&listbrowser_list4); #ifdef DEBUG IDOS->Printf("Number of nodes in tabs = %lu %lu %lu %lu\n",length1,length2,length3,length4); #endif // Write row numbers then string data for each tab fputc(length1, Outfile); WriteBrowserList(&listbrowser_list1, COLSTAB1, Outfile); fputc(length2, Outfile); WriteBrowserList(&listbrowser_list2, COLSTAB2, Outfile); fputc(length3, Outfile); WriteBrowserList(&listbrowser_list3, COLSTAB3, Outfile); fputc(length4, Outfile); WriteBrowserList(&listbrowser_list4, COLSTAB4, Outfile); fclose(Outfile); } // unable to open output file! } int main() { // Object *winobj; struct Window *window = NULL; uint32 fade_time = 50000; uint32 current_tab; uint32 activenode = 0; int i; /* make sure our classes opened... */ if (!IntegerBase || !WindowBase || !LayoutBase || !IntuitionBase) return (30); if (( AppPort = IExec->CreateMsgPort() )) { // Allocate Space for Strings + 1 for nul for all tabs for(i = 0; i < MAXENTRIES; i++) { Tab1Strings[i] = malloc((STRSIZE + 1)*sizeof(char)); Tab2Strings[i] = malloc((STRSIZE + 1)*sizeof(char)); Tab3Strings[i] = malloc((STRSIZE + 1)*sizeof(char)); Tab4Strings[i] = malloc((STRSIZE + 1)*sizeof(char)); } LoadFile(); // create browser lists from file input { win = make_window(); window = RA_OpenWindow(win); if (window) { uint32 sigmask = 0, siggot = 0, result = 0, code = 0; BOOL done = FALSE; IIntuition->GetAttr(WINDOW_SigMask, win, &sigmask); while (!done) { siggot = IExec->Wait(sigmask | SIGBREAKF_CTRL_C); if (siggot & SIGBREAKF_CTRL_C) done = TRUE; while ((result = RA_HandleInput(win, &code))) { switch(result & WMHI_CLASSMASK) { case WMHI_CLOSEWINDOW: done = TRUE; break; case WMHI_ICONIFY: IIntuition->SetAttrs( win, WA_FadeTime, fade_time , TAG_END ); if (RA_Iconify(win)) window = NULL; break; case WMHI_UNICONIFY: window = RA_OpenWindow(win); IIntuition->SetAttrs( win, WA_FadeTime, fade_time , TAG_END ); break; case WMHI_GADGETUP: switch (result & WMHI_GADGETMASK) { case OBJ_ADD: // MessageBox("OK", // "Adding new Entry\n"); IIntuition->GetAttr(CLICKTAB_Current,OBJ(OBJ_CLICKTAB), ¤t_tab); if(AddNode(window, current_tab)) { } else { IDOS->Printf(" Unable to add listbrowser node!\n"); } break; case OBJ_DELETE: MessageBox("Delete", "Delete Selected Entry?\n"); // display tab and row here IIntuition->GetAttr(CLICKTAB_Current,OBJ(OBJ_CLICKTAB), ¤t_tab); IIntuition->GetAttrs( OBJ(current_tab + 1), LISTBROWSER_SelectedNode, (uint32 *)&activenode, TAG_DONE); #ifdef DEBUG if (activenode) { IDOS->Printf("Node = %ld\n",activenode); /* got selected node */ } else { IDOS->Printf("No node is selected!\n"); /* no node selected */ } IDOS->Printf(" Current Tab = %ld\n", current_tab); #endif // remove node, free it and update display IIntuition->DoGadgetMethod((struct Gadget *)OBJ(current_tab + 1), window, NULL, LBM_REMNODE, NULL, activenode); break; case OBJ_ABOUT: SaveFile("AmiSafe.dat"); MessageBox("OK", "AmiSafe stores all your passwords in an encrypted file.\n" \ "Only the proper password can unlock your encrypted data!\n" \ "If you are seeing garbage, you have not entered the correct password!"); break; } break; } // switch } // while result } // while !done } // if window IIntuition->DisposeObject(win); } // if make_broswerlist IListBrowser->FreeListBrowserList(&listbrowser_list1); IListBrowser->FreeLBColumnInfo(columninfo1); IListBrowser->FreeListBrowserList(&listbrowser_list2); IListBrowser->FreeLBColumnInfo(columninfo2); IListBrowser->FreeListBrowserList(&listbrowser_list3); IListBrowser->FreeLBColumnInfo(columninfo3); IListBrowser->FreeListBrowserList(&listbrowser_list4); IListBrowser->FreeLBColumnInfo(columninfo4); IExec->DeleteMsgPort(AppPort); // Free reserved space for strings for all tabs for(i = 0; i < MAXENTRIES; i++) { free(Tab1Strings[i]); free(Tab2Strings[i]); free(Tab3Strings[i]); free(Tab4Strings[i]); } } // if AppPort return 0; } BOOL make_browserlist(struct List *list, char **tagstring, int columns) { struct Node *node; IExec->NewList(list); switch (columns) { case 2: while (*tagstring) { if (node = IListBrowser->AllocListBrowserNode(columns, LBNA_Column, 0, LBNCA_Text, *tagstring++, LBNCA_Editable, TRUE, LBNCA_CopyText, TRUE, LBNCA_MaxChars, 30, LBNA_Column, 1, LBNCA_Text, *tagstring++, LBNCA_Editable, TRUE, LBNCA_CopyText, TRUE, LBNCA_MaxChars, 30, (TAG_DONE))) { IExec->AddTail(list, node); } else { IDOS->Printf(" AllocListBrowserNode() failed\n"); return(FALSE); } } case 3: while (*tagstring) { if (node = IListBrowser->AllocListBrowserNode(columns, LBNA_Column, 0, LBNCA_Text, *tagstring++, LBNCA_Editable, TRUE, LBNCA_CopyText, TRUE, LBNCA_MaxChars, 30, LBNA_Column, 1, LBNCA_Text, *tagstring++, LBNCA_Editable, TRUE, LBNCA_CopyText, TRUE, LBNCA_MaxChars, 30, LBNA_Column, 2, LBNCA_Text, *tagstring++, LBNCA_Editable, TRUE, LBNCA_CopyText, TRUE, LBNCA_MaxChars, 30, (TAG_DONE))) { IExec->AddTail(list, node); } else { IDOS->Printf(" AllocListBrowserNode() failed\n"); return(FALSE); } } case 5: while (*tagstring) { if (node = IListBrowser->AllocListBrowserNode(columns, LBNA_Column, 0, LBNCA_Text, *tagstring++, LBNCA_Editable, TRUE, LBNCA_CopyText, TRUE, LBNCA_MaxChars, 30, LBNA_Column, 1, LBNCA_Text, *tagstring++, LBNCA_Editable, TRUE, LBNCA_CopyText, TRUE, LBNCA_MaxChars, 30, LBNA_Column, 2, LBNCA_Text, *tagstring++, LBNCA_Editable, TRUE, LBNCA_CopyText, TRUE, LBNCA_MaxChars, 30, LBNA_Column, 3, LBNCA_Text, *tagstring++, LBNCA_Editable, TRUE, LBNCA_CopyText, TRUE, LBNCA_MaxChars, 30, LBNA_Column, 4, LBNCA_Text, *tagstring++, LBNCA_Editable, TRUE, LBNCA_CopyText, TRUE, LBNCA_MaxChars, 30, (TAG_DONE))) { IExec->AddTail(list, node); } else { IDOS->Printf(" AllocListBrowserNode() failed\n"); return(FALSE); } } break; default: IDOS->Printf(" Invalid number of list fields\n"); return(FALSE); }; // switch return(TRUE); }