ReactOS Package Manager
authorKlemens Friedl <frik85@gmail.com>
Sun, 3 Apr 2005 19:06:49 +0000 (19:06 +0000)
committerKlemens Friedl <frik85@gmail.com>
Sun, 3 Apr 2005 19:06:49 +0000 (19:06 +0000)
More information:
http://reactos.com/wiki/index.php/ReactOS_Package_Manager

* Maarten Bosma (Dr. Fred)
* Klemens Friedl (frik85)

svn path=/trunk/; revision=14481

46 files changed:
rosapps/packmgr/gui/en.rc [new file with mode: 0644]
rosapps/packmgr/gui/generic.rc [new file with mode: 0644]
rosapps/packmgr/gui/main.cpp [new file with mode: 0644]
rosapps/packmgr/gui/main.h [new file with mode: 0644]
rosapps/packmgr/gui/makefile [new file with mode: 0644]
rosapps/packmgr/gui/packmgr.rc [new file with mode: 0644]
rosapps/packmgr/gui/res/blank.ico [new file with mode: 0644]
rosapps/packmgr/gui/res/development.ico [new file with mode: 0644]
rosapps/packmgr/gui/res/games.ico [new file with mode: 0644]
rosapps/packmgr/gui/res/graphics.ico [new file with mode: 0644]
rosapps/packmgr/gui/res/inet.ico [new file with mode: 0644]
rosapps/packmgr/gui/res/install.ico [new file with mode: 0644]
rosapps/packmgr/gui/res/installed.ico [new file with mode: 0644]
rosapps/packmgr/gui/res/installsource.ico [new file with mode: 0644]
rosapps/packmgr/gui/res/multimedia.ico [new file with mode: 0644]
rosapps/packmgr/gui/res/office.ico [new file with mode: 0644]
rosapps/packmgr/gui/res/others.ico [new file with mode: 0644]
rosapps/packmgr/gui/res/packetmanager.ico [new file with mode: 0644]
rosapps/packmgr/gui/res/toolbar.bmp [new file with mode: 0644]
rosapps/packmgr/gui/res/tools.ico [new file with mode: 0644]
rosapps/packmgr/gui/res/uninstall.ico [new file with mode: 0644]
rosapps/packmgr/gui/res/update.ico [new file with mode: 0644]
rosapps/packmgr/gui/resource.h [new file with mode: 0644]
rosapps/packmgr/help.txt [new file with mode: 0644]
rosapps/packmgr/lib/download.cpp [new file with mode: 0644]
rosapps/packmgr/lib/en.rc [new file with mode: 0644]
rosapps/packmgr/lib/error.h [new file with mode: 0644]
rosapps/packmgr/lib/expat.h [new file with mode: 0644]
rosapps/packmgr/lib/functions.cpp [new file with mode: 0644]
rosapps/packmgr/lib/log.cpp [new file with mode: 0644]
rosapps/packmgr/lib/log.h [new file with mode: 0644]
rosapps/packmgr/lib/main.cpp [new file with mode: 0644]
rosapps/packmgr/lib/makefile [new file with mode: 0644]
rosapps/packmgr/lib/package.cpp [new file with mode: 0644]
rosapps/packmgr/lib/package.def [new file with mode: 0644]
rosapps/packmgr/lib/package.hpp [new file with mode: 0644]
rosapps/packmgr/lib/package.rc [new file with mode: 0644]
rosapps/packmgr/lib/script.cpp [new file with mode: 0644]
rosapps/packmgr/lib/script.h [new file with mode: 0644]
rosapps/packmgr/lib/tree.cpp [new file with mode: 0644]
rosapps/packmgr/makefile [new file with mode: 0644]
rosapps/packmgr/tree/abiword.inst.rps [new file with mode: 0644]
rosapps/packmgr/tree/abiword.xml [new file with mode: 0644]
rosapps/packmgr/tree/mozcontrol.xml [new file with mode: 0644]
rosapps/packmgr/tree/mozillacontrol.inst.rps [new file with mode: 0644]
rosapps/packmgr/tree/tree.xml [new file with mode: 0644]

diff --git a/rosapps/packmgr/gui/en.rc b/rosapps/packmgr/gui/en.rc
new file mode 100644 (file)
index 0000000..d82f2a9
--- /dev/null
@@ -0,0 +1,43 @@
+\r
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US\r
+\r
+/* Dialogs */\r
+IDD_OPTIONS DIALOG DISCARDABLE  0, 0, 180, 200\r
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU\r
+CAPTION "Options"\r
+FONT 8, "MS Sans Serif"\r
+BEGIN\r
+    LTEXT      "There are no options yet.", 0, 50, 95, 80, 8\r
+END\r
+\r
+IDD_DOIT DIALOG DISCARDABLE  0, 0, 180, 100\r
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU\r
+CAPTION "Performing Operations"\r
+FONT 8, "MS Sans Serif"\r
+BEGIN    \r
+\r
+    CTEXT          "{Status}", IDC_TSTATUS, 0, 10, 180, 8\r
+\r
+    CONTROL         "", IDC_STATUS1, "msctls_progress32", PBS_SMOOTH, 20, 25, 140, 15\r
+    \r
+    CONTROL         "", IDC_STATUS2, "msctls_progress32", PBS_SMOOTH, 20, 45, 140, 15\r
+\r
+    PUSHBUTTON      "Abort", IDC_CANCEL, 65, 70, 50, 14, WS_DISABLED\r
+END\r
+\r
+IDR_POPUP MENU DISCARDABLE \r
+BEGIN\r
+    POPUP "PopUp", MENUBARBREAK        \r
+    BEGIN\r
+        MENUITEM "No Action",                  1, GRAYED \r
+        MENUITEM "Install (recommended)",       2, GRAYED\r
+        MENUITEM "Install from Source",         3, GRAYED\r
+        MENUITEM "Update",                      4, GRAYED\r
+        MENUITEM "Unnstall",                    5, GRAYED\r
+        MENUITEM SEPARATOR\r
+        MENUITEM "Options",                     8\r
+        MENUITEM SEPARATOR\r
+        MENUITEM "DoIt",                        6\r
+    END\r
+END\r
+\r
diff --git a/rosapps/packmgr/gui/generic.rc b/rosapps/packmgr/gui/generic.rc
new file mode 100644 (file)
index 0000000..2548649
--- /dev/null
@@ -0,0 +1,24 @@
+\r
+LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL\r
+\r
+IDI_MAIN ICON DISCARDABLE "res/packetmanager.ico"\r
+IDB_TOOLBAR BITMAP DISCARDABLE "res/toolbar.bmp"\r
+\r
+/* TreeIcons - Categories */\r
+1 ICON DISCARDABLE "res/blank.ico"\r
+2 ICON DISCARDABLE "res/inet.ico"\r
+3 ICON DISCARDABLE "res/office.ico"\r
+4 ICON DISCARDABLE "res/graphics.ico"\r
+5 ICON DISCARDABLE "res/multimedia.ico"\r
+6 ICON DISCARDABLE "res/development.ico"\r
+7 ICON DISCARDABLE "res/games.ico"\r
+8 ICON DISCARDABLE "res/tools.ico"\r
+9 ICON DISCARDABLE "res/others.ico"\r
+10 ICON DISCARDABLE "res/installed.ico"\r
+\r
+/* TreeIcons - Actions */\r
+11 ICON DISCARDABLE "res/install.ico"\r
+12 ICON DISCARDABLE "res/installsource.ico"\r
+13 ICON DISCARDABLE "res/update.ico"\r
+14 ICON DISCARDABLE "res/uninstall.ico"\r
+\r
diff --git a/rosapps/packmgr/gui/main.cpp b/rosapps/packmgr/gui/main.cpp
new file mode 100644 (file)
index 0000000..893cb7a
--- /dev/null
@@ -0,0 +1,401 @@
+////////////////////////////////////////////////////////\r
+//\r
+// main.cpp\r
+// \r
+// Implementation of the Package Manager GUI\r
+//\r
+//\r
+// Maarten Bosma, 09.01.2004\r
+// maarten.paul@bosma.de\r
+//\r
+////////////////////////////////////////////////////////////////////\r
+\r
+#include "main.h"\r
+\r
+\r
+// Application's Entry Point\r
+int WINAPI WinMain (HINSTANCE hinst, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)\r
+{\r
+       HWND       hwnd;\r
+       MSG        msg;\r
+       WNDCLASSEX wc = {0};\r
+\r
+       // Window creation\r
+       wc.cbSize        = sizeof(WNDCLASSEX); \r
+       wc.lpszClassName = L"pgkmgr";\r
+       wc.style         = CS_HREDRAW | CS_VREDRAW;\r
+       wc.lpfnWndProc   = (WNDPROC)WndProc;\r
+       wc.hInstance     = hinst;\r
+       wc.hIcon                 = LoadIcon(hinst, MAKEINTRESOURCE(IDI_MAIN));\r
+       wc.hbrBackground = (HBRUSH)(COLOR_SCROLLBAR);\r
+\r
+       RegisterClassEx(&wc);\r
+\r
+       hwnd = CreateWindow(L"pgkmgr",\r
+                       L"ReactOS - Package Manager v0.3",\r
+                       WS_OVERLAPPEDWINDOW,\r
+                       CW_USEDEFAULT,  \r
+                       CW_USEDEFAULT,   \r
+                       500, 600, \r
+                       NULL, NULL,\r
+                       hinst, \r
+                                          NULL);\r
+\r
+\r
+       // Toolbar creation\r
+       InitCommonControls();\r
+\r
+       hTBar = CreateToolbarEx(hwnd, WS_CHILD|WS_VISIBLE|TBSTYLE_FLAT, 0, 8, hinst, IDB_TOOLBAR, \r
+                                                                               Buttons, sizeof(Buttons)/sizeof(TBBUTTON), TBSIZE, TBSIZE, TBSIZE, TBSIZE, sizeof(TBBUTTON));\r
+\r
+       // Show the windows\r
+       ShowWindow(hwnd, SW_SHOW);\r
+       UpdateWindow(hwnd);\r
+\r
+       // Load the tree\r
+       int error = PML_LoadTree(&tree, "tree.xml", AddItem);\r
+       \r
+       if(error)\r
+       {\r
+               MessageBox(0,PML_TransError(error),0,0);\r
+               return 0;\r
+       }\r
+       \r
+       // Read the help\r
+       Help();\r
+\r
+       // Start getting messages\r
+       while(GetMessage(&msg,NULL,0,0))\r
+       {\r
+         TranslateMessage(&msg);\r
+         DispatchMessage(&msg);\r
+       }\r
+       \r
+       // Close our handle\r
+       PML_CloseTree (tree);\r
+\r
+       return 0;\r
+}\r
+\r
+// Add a item to our tree\r
+int AddItem (int id, const char* name, int parent, int icon)\r
+{ \r
+       TV_INSERTSTRUCT tvins; \r
+\r
+       tvins.item.lParam = (UINT)id;\r
+       tvins.item.mask = TVIF_TEXT|TVIF_PARAM;\r
+       tvins.item.pszText = (WCHAR*)name; //that is ok\r
+       tvins.item.cchTextMax = strlen(name); \r
+       tvins.hInsertAfter = TVI_LAST;\r
+\r
+       if(icon)\r
+       {\r
+               tvins.item.iImage = icon;\r
+               tvins.item.iSelectedImage = icon;\r
+               tvins.item.mask |= TVIF_IMAGE | TVIF_SELECTEDIMAGE;\r
+       }\r
+\r
+       if (parent==0)\r
+               tvins.hParent = TVI_ROOT;\r
+       else\r
+               tvins.hParent = nodes[parent];\r
+\r
+       nodes[id] = (HTREEITEM)SendMessage(hTree, TVM_INSERTITEMA, 0, (LPARAM)&tvins);\r
+\r
+       return 0;\r
+} \r
+\r
+// Load the Help from file and display it\r
+void Help (void)\r
+{\r
+       string source;\r
+\r
+       ifstream file("help.txt", ios_base::in);\r
+       getline(file, source, '\0');\r
+\r
+       SetText(source.c_str());\r
+}\r
+\r
+// Create our Controls\r
+void InitControls (HWND hwnd)\r
+{\r
+\r
+       HINSTANCE hinst = GetModuleHandle(NULL);\r
+\r
+       // Create the controls\r
+       hTree = CreateWindowEx(0, WC_TREEVIEW, L"TreeView", WS_CHILD|WS_VISIBLE|WS_BORDER|TVS_HASLINES|TVS_LINESATROOT|TVS_HASBUTTONS, \r
+                                                       0, 0, 0, 0, hwnd, NULL, hinst, NULL);\r
+\r
+       hEdit = CreateWindowEx(WS_EX_CLIENTEDGE, L"edit", PML_TransError(IDS_LOAD), WS_CHILD|WS_VISIBLE|ES_MULTILINE, \r
+                                                       0, 0, 100, 100, hwnd, NULL, hinst, NULL);\r
+       \r
+       hPopup = LoadMenu(hinst, MAKEINTRESOURCE(IDR_POPUP));\r
+\r
+       // Create Tree Icons\r
+       HIMAGELIST hIcon = ImageList_Create(16,16,ILC_COLOR32,1,1); \r
+       SendMessage(hTree, TVM_SETIMAGELIST, TVSIL_NORMAL, (LPARAM)(HIMAGELIST)hIcon);\r
+               \r
+       ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(1))); \r
+       ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(11))); \r
+       ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(12))); \r
+       ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(13))); \r
+       ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(14))); \r
+\r
+       ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(2))); \r
+       ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(3))); \r
+       ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(4))); \r
+       ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(5))); \r
+       ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(6))); \r
+       ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(7))); \r
+       ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(8))); \r
+       ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(9))); \r
+       ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(10))); \r
+\r
+       // Setup Hotkeys\r
+       RegisterHotKey(hwnd, 1, MOD_CONTROL, VK_1);\r
+       RegisterHotKey(hwnd, 2, MOD_CONTROL, VK_2);\r
+       RegisterHotKey(hwnd, 3, MOD_CONTROL, VK_3);\r
+       RegisterHotKey(hwnd, 4, MOD_CONTROL, VK_4);\r
+       RegisterHotKey(hwnd, 0, MOD_CONTROL, VK_0);\r
+}\r
+\r
+// Set the Icons\r
+int SetIcon (int id, int icon) \r
+{\r
+    TVITEMEX item;\r
+       \r
+       item.hItem = nodes[id];\r
+       item.iImage = icon;\r
+       item.iSelectedImage = icon;\r
+       item.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE;\r
+\r
+       TreeView_SetItem(hTree, &item);\r
+\r
+    return 1;\r
+}\r
+\r
+// En- or Disable a Button inside of the toolbar and the Context Menu\r
+int SetButton (DWORD id, BOOL state) \r
+{\r
+       // Change the Toorbar Button\r
+    TBBUTTONINFO ti;\r
+\r
+    ti.cbSize = sizeof (ti);\r
+    ti.dwMask = TBIF_STATE;\r
+\r
+       if(state)\r
+               ti.fsState = TBSTATE_ENABLED;\r
+       else\r
+               ti.fsState = TBSTATE_INDETERMINATE;\r
+\r
+    SendMessage (hTBar, TB_SETBUTTONINFO, id, (LPARAM)&ti);\r
+\r
+       // Change the Context Menu item\r
+       MENUITEMINFO mi;\r
+\r
+    mi.cbSize = sizeof (mi);\r
+    mi.fMask = MIIM_STATE;\r
+\r
+       if(state)\r
+               mi.fState = MFS_ENABLED;\r
+\r
+       else\r
+               mi.fState = MFS_GRAYED;\r
+\r
+    SetMenuItemInfo(hPopup, id, FALSE, &mi);\r
+\r
+       return 1;\r
+}\r
+\r
+// Set the text of the text box\r
+int SetText (const char* text) \r
+{\r
+       int i = 0;\r
+       string source = text;\r
+\r
+       // the windows does not need "\n"\r
+       // for new lines but "\r\n"\r
+       for(i=0; source[i]; i++)\r
+               if(source[i]=='\n' && source[i]!='\r')\r
+                       source.insert (i++, "\r");\r
+\r
+       SetWindowTextA(hEdit, source.c_str());\r
+\r
+    return 0;\r
+}\r
+\r
+// Windows Message Callback (this is where most things happen)\r
+LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)\r
+{\r
+       switch (message)\r
+       {\r
+               // at the very beginning ...\r
+               case WM_CREATE:\r
+               {\r
+                       InitControls(hwnd);\r
+               } \r
+               break;\r
+\r
+               // calculate the size of the controls\r
+               case WM_SIZE:\r
+               {\r
+            RECT rcl;\r
+            SendMessage(hTBar, TB_AUTOSIZE, 0L, 0L);\r
+            GetWindowRect(hTBar, &rcl);\r
+\r
+                       int win_top = rcl.bottom - rcl.top;\r
+                       int win_hight = HIWORD(lParam) - win_top;\r
+\r
+            MoveWindow(hTree, 0, win_top, LOWORD(lParam), splitter_pos*win_hight/100, TRUE);\r
+            MoveWindow(hEdit, 0, (splitter_pos*win_hight/100)+win_top, LOWORD(lParam), win_hight, TRUE);\r
+               }\r
+           break;\r
+\r
+               // for the treeview\r
+               case WM_NOTIFY:\r
+               {\r
+                       if(((LPNMHDR)lParam)->code == TVN_SELCHANGED) \r
+                       {\r
+                               selected = ((LPNMTREEVIEW)lParam)->itemNew.lParam; \r
+                               PML_LoadPackage (tree, selected, SetButton, SetText);\r
+                       }\r
+\r
+                       else if ((int)(((LPNMHDR)lParam)->code) == NM_RCLICK) // <= ahhh LISP\r
+                       { \r
+                               // which item has been click on\r
+                               HTREEITEM item = TreeView_GetDropHilight(hTree);\r
+\r
+                               if(item != NULL)\r
+                               {\r
+                                       // mark the one as seleacted\r
+                                       SendMessage (hTree, TVM_SELECTITEM, TVGN_CARET, (LPARAM)item);\r
+                                       TreeView_EnsureVisible (hTree, item);\r
+                               }\r
+\r
+                               // create the context menu\r
+                               if(selected != 0)\r
+                               {\r
+                                       POINT pt;\r
+                                       GetCursorPos (&pt);\r
+                                       TrackPopupMenu (GetSubMenu(hPopup, 0), 0, (UINT)pt.x, (UINT)pt.y, 0, hwnd, NULL);\r
+                               }\r
+                       }\r
+               }\r
+               break;\r
+\r
+               // for the toolbar\r
+               case WM_COMMAND:\r
+               {\r
+                       // All Actions\r
+                       if(LOWORD(wParam) <= 5 && LOWORD(wParam) >= 1)\r
+                       {\r
+                               if(selected)\r
+                                       if(PML_SetAction(tree, selected, LOWORD(wParam)-1, SetIcon) == ERR_OK)\r
+                                               break;\r
+\r
+                               MessageBeep(MB_ICONHAND);\r
+                       }\r
+\r
+                       // DoIt\r
+                       else if(LOWORD(wParam)==6)\r
+                       {\r
+                               if(PML_DoIt(tree, SetStatus) == ERR_OK)\r
+                                       DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_DOIT), hwnd, StatusProc);\r
+                               else\r
+                                       MessageBeep(MB_ICONHAND);\r
+                       }\r
+\r
+                       // Help\r
+                       else if(LOWORD(wParam)==7)\r
+                               Help();\r
+\r
+                       // Options\r
+                       else if(LOWORD(wParam)==8)\r
+                               DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_OPTIONS), hwnd, OptionsProc);\r
+\r
+                       else\r
+                               MessageBox(0,0,0,0);\r
+               }\r
+               break;\r
+\r
+               // prozess hotkeys\r
+               case WM_HOTKEY:\r
+               {\r
+                       if(PML_SetAction(tree, selected, wParam, SetIcon) != ERR_OK)\r
+                               MessageBeep(MB_ICONHAND);\r
+               }\r
+               break;\r
+\r
+               // ... at the very end\r
+               case WM_DESTROY:\r
+               {\r
+                       PostQuitMessage(0);\r
+                       return 0;\r
+               }\r
+       }\r
+\r
+       return DefWindowProc (hwnd, message, wParam, lParam);\r
+}\r
+\r
+// Warning: This function is called from another thread\r
+int SetStatus (int status1, int status2, WCHAR* text)\r
+{\r
+       // Set the Rage to 1000\r
+       SendMessage(GetDlgItem(hStatus, IDC_STATUS1), PBM_SETRANGE32, 0, 1000);\r
+       SendMessage(GetDlgItem(hStatus, IDC_STATUS2), PBM_SETRANGE32, 0, 1000);\r
+\r
+       // The prozessbars and the text filds\r
+       if(text)\r
+               SetDlgItemText(hStatus, IDC_TSTATUS, text);\r
+\r
+       if(status1!=-1)\r
+               SendMessage(GetDlgItem(hStatus, IDC_STATUS1), PBM_SETPOS, status1, 0);\r
+\r
+       if(status2!=-1)\r
+               SendMessage(GetDlgItem(hStatus, IDC_STATUS2), PBM_SETPOS, status2, 0);\r
+\r
+       // If the Status is 1000 very thing is done\r
+       if(status1==1000)\r
+       {\r
+               EndDialog(hStatus, TRUE);\r
+               MessageBox(0,PML_TransError(status2),0,0);\r
+       }\r
+\r
+       return 0;\r
+}\r
+\r
+// Callback for the Status Dialog\r
+INT_PTR CALLBACK StatusProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)\r
+{\r
+    switch (msg)\r
+    {\r
+               case WM_INITDIALOG:\r
+               {\r
+                       hStatus = hwnd;\r
+                       \r
+               } break;\r
+\r
+               case WM_COMMAND: // can only be the about button\r
+               case WM_CLOSE: // the close-window-[x]\r
+               {\r
+                       PML_Abort();\r
+                       EndDialog(hwnd, TRUE);\r
+                       return 0;\r
+               }\r
+    }\r
+\r
+    return 0;\r
+}\r
+\r
+// Callback for the Options Dialog\r
+INT_PTR CALLBACK OptionsProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)\r
+{\r
+    switch (msg)\r
+    {\r
+               case WM_CLOSE:\r
+                       EndDialog(hwnd, TRUE);\r
+                       return 0;\r
+    }\r
+\r
+    return 0;\r
+}\r
diff --git a/rosapps/packmgr/gui/main.h b/rosapps/packmgr/gui/main.h
new file mode 100644 (file)
index 0000000..63cd4cc
--- /dev/null
@@ -0,0 +1,62 @@
+///////////////////////////////////////////////////\r
+//\r
+// main.h\r
+//                             main.cpp's lumber room :)\r
+///////////////////////////////////////////////////\r
+\r
+#include <windows.h>\r
+#include <ntos/keyboard.h>\r
+#include <commctrl.h>\r
+#include <iostream>\r
+#include <fstream>\r
+\r
+#include <package.hpp>\r
+#include "resource.h"\r
+\r
+/* Some Variables */ \r
+\r
+int selected, splitter_pos = 50;\r
+\r
+pTree tree;\r
+HMENU hPopup;\r
+HWND hTBar, hTree, hEdit, hStatus;\r
+HTREEITEM nodes [MAXNODES];\r
+\r
+/* Window Callbacks */\r
\r
+LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);\r
+INT_PTR CALLBACK StatusProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);\r
+INT_PTR CALLBACK OptionsProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);\r
+\r
+/* Prototypes */\r
+\r
+void Help (void);\r
+\r
+int AddItem (int id, const char* name, int parent, int icon);\r
+int SetText (const char* text);\r
+int SetStatus (int status1, int status2, WCHAR* text);\r
+\r
+/* Toolbar Releated */\r
+\r
+#define TBSTYLE_FLAT 2048\r
+\r
+// This is the struct where the toolbar is defined\r
+TBBUTTON Buttons [] = \r
+{\r
+       {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, 0},\r
+       \r
+       {0, 1, TBSTATE_INDETERMINATE, TBSTYLE_BUTTON, 0L, 0}, // No Action\r
+       {1, 2, TBSTATE_INDETERMINATE, TBSTYLE_BUTTON, 0L, 0}, // Install\r
+       {2, 3, TBSTATE_INDETERMINATE, TBSTYLE_BUTTON, 0L, 0}, // Install from source\r
+       {3, 4, TBSTATE_INDETERMINATE, TBSTYLE_BUTTON, 0L, 0}, // Update\r
+       {4, 5, TBSTATE_INDETERMINATE, TBSTYLE_BUTTON, 0L, 0}, // Unistall\r
+\r
+       {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, 0},\r
+       {5, 6, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0}, // DoIt (tm)\r
+       {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, 0},\r
+\r
+       {6, 7, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0}, // Help\r
+       {7, 8, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0}, // Options\r
+\r
+       {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, 0},\r
+}; \r
diff --git a/rosapps/packmgr/gui/makefile b/rosapps/packmgr/gui/makefile
new file mode 100644 (file)
index 0000000..8bd3eb1
--- /dev/null
@@ -0,0 +1,24 @@
+\r
+TARGET_NAME = packmgr\r
+TARGET_TYPE = program\r
+TARGET_APPTYPE = windows\r
+PATH_TO_TOP = ../../../reactos\r
+\r
+TARGET_SDKLIBS = kernel32.a user32.a package.a gdi32.a comctl32.a shell32.a\r
+\r
+TARGET_GCCLIBS = stdc++ uuid\r
+\r
+TARGET_OBJECTS = main.o\r
+\r
+\r
+TARGET_CFLAGS = \\r
+       -D__USE_W32API -DWIN32 -D_ROS_ \\r
+       -D_WIN32_IE=0x0501 -D_WIN32_WINNT=0x0501 \\r
+       -DUNICODE -Wall -I../lib\r
+\r
+TARGET_CPPFLAGS = $(TARGET_CFLAGS)\r
+TARGET_RCFLAGS =  -D__USE_W32API -DNDEBUG -DWIN32 -D_ROS_ -D__WINDRES__ -DUNICODE\r
+\r
+include $(PATH_TO_TOP)/rules.mak\r
+include $(TOOLS_PATH)/helper.mk\r
+include $(TOOLS_PATH)/depend.mk\r
diff --git a/rosapps/packmgr/gui/packmgr.rc b/rosapps/packmgr/gui/packmgr.rc
new file mode 100644 (file)
index 0000000..9b38cf6
--- /dev/null
@@ -0,0 +1,18 @@
+\r
+#include <windows.h>\r
+#include "resource.h"\r
+\r
+#define REACTOS_STR_FILE_DESCRIPTION   "ReactOS Package Manager\0"\r
+#define REACTOS_STR_INTERNAL_NAME      "packmgr\0"\r
+#define REACTOS_STR_ORIGINAL_FILENAME  "packmgr.exe\0"\r
+\r
+#include <reactos/version.rc>\r
+\r
+/* For all langs */\r
+#include "generic.rc"\r
+\r
+/* Language specific */\r
+\r
+#include "en.rc"\r
+\r
+/* EOF */\r
diff --git a/rosapps/packmgr/gui/res/blank.ico b/rosapps/packmgr/gui/res/blank.ico
new file mode 100644 (file)
index 0000000..96c1bdd
Binary files /dev/null and b/rosapps/packmgr/gui/res/blank.ico differ
diff --git a/rosapps/packmgr/gui/res/development.ico b/rosapps/packmgr/gui/res/development.ico
new file mode 100644 (file)
index 0000000..442132d
Binary files /dev/null and b/rosapps/packmgr/gui/res/development.ico differ
diff --git a/rosapps/packmgr/gui/res/games.ico b/rosapps/packmgr/gui/res/games.ico
new file mode 100644 (file)
index 0000000..92469e7
Binary files /dev/null and b/rosapps/packmgr/gui/res/games.ico differ
diff --git a/rosapps/packmgr/gui/res/graphics.ico b/rosapps/packmgr/gui/res/graphics.ico
new file mode 100644 (file)
index 0000000..0232780
Binary files /dev/null and b/rosapps/packmgr/gui/res/graphics.ico differ
diff --git a/rosapps/packmgr/gui/res/inet.ico b/rosapps/packmgr/gui/res/inet.ico
new file mode 100644 (file)
index 0000000..e048867
Binary files /dev/null and b/rosapps/packmgr/gui/res/inet.ico differ
diff --git a/rosapps/packmgr/gui/res/install.ico b/rosapps/packmgr/gui/res/install.ico
new file mode 100644 (file)
index 0000000..3a44f71
Binary files /dev/null and b/rosapps/packmgr/gui/res/install.ico differ
diff --git a/rosapps/packmgr/gui/res/installed.ico b/rosapps/packmgr/gui/res/installed.ico
new file mode 100644 (file)
index 0000000..a50f549
Binary files /dev/null and b/rosapps/packmgr/gui/res/installed.ico differ
diff --git a/rosapps/packmgr/gui/res/installsource.ico b/rosapps/packmgr/gui/res/installsource.ico
new file mode 100644 (file)
index 0000000..7296f0a
Binary files /dev/null and b/rosapps/packmgr/gui/res/installsource.ico differ
diff --git a/rosapps/packmgr/gui/res/multimedia.ico b/rosapps/packmgr/gui/res/multimedia.ico
new file mode 100644 (file)
index 0000000..7af917a
Binary files /dev/null and b/rosapps/packmgr/gui/res/multimedia.ico differ
diff --git a/rosapps/packmgr/gui/res/office.ico b/rosapps/packmgr/gui/res/office.ico
new file mode 100644 (file)
index 0000000..b696ae6
Binary files /dev/null and b/rosapps/packmgr/gui/res/office.ico differ
diff --git a/rosapps/packmgr/gui/res/others.ico b/rosapps/packmgr/gui/res/others.ico
new file mode 100644 (file)
index 0000000..82eba8b
Binary files /dev/null and b/rosapps/packmgr/gui/res/others.ico differ
diff --git a/rosapps/packmgr/gui/res/packetmanager.ico b/rosapps/packmgr/gui/res/packetmanager.ico
new file mode 100644 (file)
index 0000000..d50b13b
Binary files /dev/null and b/rosapps/packmgr/gui/res/packetmanager.ico differ
diff --git a/rosapps/packmgr/gui/res/toolbar.bmp b/rosapps/packmgr/gui/res/toolbar.bmp
new file mode 100644 (file)
index 0000000..665df99
Binary files /dev/null and b/rosapps/packmgr/gui/res/toolbar.bmp differ
diff --git a/rosapps/packmgr/gui/res/tools.ico b/rosapps/packmgr/gui/res/tools.ico
new file mode 100644 (file)
index 0000000..bc5d250
Binary files /dev/null and b/rosapps/packmgr/gui/res/tools.ico differ
diff --git a/rosapps/packmgr/gui/res/uninstall.ico b/rosapps/packmgr/gui/res/uninstall.ico
new file mode 100644 (file)
index 0000000..962bc6d
Binary files /dev/null and b/rosapps/packmgr/gui/res/uninstall.ico differ
diff --git a/rosapps/packmgr/gui/res/update.ico b/rosapps/packmgr/gui/res/update.ico
new file mode 100644 (file)
index 0000000..010d1bb
Binary files /dev/null and b/rosapps/packmgr/gui/res/update.ico differ
diff --git a/rosapps/packmgr/gui/resource.h b/rosapps/packmgr/gui/resource.h
new file mode 100644 (file)
index 0000000..90aa5f7
--- /dev/null
@@ -0,0 +1,14 @@
+#include "../lib/error.h"\r
+\r
+#define IDI_MAIN               0\r
+\r
+#define TBSIZE                 32\r
+#define IDB_TOOLBAR            0x102\r
+#define IDD_OPTIONS     0x103\r
+#define IDD_DOIT               0x104 \r
+#define IDR_POPUP              0x105 \r
+\r
+#define IDC_STATUS1            0x110 \r
+#define IDC_STATUS2            0x111 \r
+#define IDC_CANCEL             0x112 \r
+#define IDC_TSTATUS            0x113 \r
diff --git a/rosapps/packmgr/help.txt b/rosapps/packmgr/help.txt
new file mode 100644 (file)
index 0000000..c6de41b
--- /dev/null
@@ -0,0 +1,9 @@
+Welcome to ReactOS's Package Manager !\r
+\r
+WARNING: This is still pre-alfa software you can't do much with it yet.\r
+\r
+This is the online help. You can show it at any time by clicking on the the Questionmark Icon above.\r
+\r
+You can use this package manager like this: click on the \r
+You can also use the Buttons [ctrl] + [0] to [4] to set the action.\r
+\r
diff --git a/rosapps/packmgr/lib/download.cpp b/rosapps/packmgr/lib/download.cpp
new file mode 100644 (file)
index 0000000..6528ae5
--- /dev/null
@@ -0,0 +1,117 @@
+////////////////////////////////////////////////////////\r
+//\r
+// download.cpp\r
+// \r
+// Stuff related to downloading\r
+//\r
+//\r
+// Maarten Bosma, 09.01.2004\r
+// maarten.paul@bosma.de\r
+//\r
+////////////////////////////////////////////////////////\r
+\r
+#include "package.hpp"\r
+#include "expat.h"\r
+#include "log.h"\r
+#include <wine/urlmon.h>\r
+\r
+// Server there all the files lie\r
+const char* tree_server = "http://svn.reactos.com/viewcvs/*checkout*/trunk/rosapps/packmgr/tree/"; \r
+\r
+HRESULT WINAPI URLDownloadToFileA(      \r
+    LPUNKNOWN pCaller,\r
+    LPCSTR szURL,\r
+    LPCSTR szFileName,\r
+    DWORD dwReserved,\r
+    LPBINDSTATUSCALLBACK lpfnCB\r
+);\r
+\r
+\r
+// Download a file\r
+char* PML_Download (const char* name, const char* local_name = "packmgr.txt", const char* server = tree_server, BOOL totemp = TRUE) \r
+{\r
+       char url [MAX_PATH];\r
+       static char path [MAX_PATH]; \r
+\r
+       // get temp dir\r
+       if(totemp)\r
+               GetTempPathA (200, path);\r
+       \r
+       // create the local file name\r
+       if(local_name)\r
+               strcat(path, local_name);\r
+       else\r
+               strcat(path, "tmp.tmp"); \r
+\r
+       // get the url\r
+       if(server) strcpy(url, server);\r
+       strcat(url, name);\r
+       \r
+       // make sure there is no old file\r
+       DeleteFileA (path);     \r
+\r
+       // download the file\r
+       if(URLDownloadToFileA (NULL, url, path, 0, NULL) != S_OK)\r
+       {\r
+               Log("!  ERROR: Unable to download ");\r
+               LogAdd(url);\r
+\r
+               return NULL;\r
+       }\r
+\r
+       return path;\r
+}\r
+\r
+// Download and prozess a xml file\r
+int PML_XmlDownload (const char* url, void* usrdata, XML_StartElementHandler start, \r
+                                                XML_EndElementHandler end, XML_CharacterDataHandler text) \r
+{\r
+       char buffer[255];\r
+       int done = 0;\r
+\r
+       // logging\r
+       Log("*  prozess the xml file: ");\r
+       LogAdd(url);\r
+\r
+       // download the file\r
+       char* filename = PML_Download(url);\r
+\r
+       if(!filename) \r
+       {\r
+               Log("!  ERROR: Could not download the xml file");\r
+               return ERR_DOWNL;\r
+       }\r
+\r
+       // open the file\r
+       FILE* file = fopen(filename, "r");\r
+       if(!file) \r
+       {\r
+               Log("!  ERROR: Could not open the xml file");\r
+               return ERR_GENERIC;\r
+       }\r
+\r
+       // parse the xml file\r
+       XML_Parser parser = XML_ParserCreate(NULL);\r
+       XML_SetUserData (parser, usrdata);\r
+       XML_SetElementHandler(parser, start, end);\r
+       XML_SetCharacterDataHandler(parser, text);\r
+\r
+       while (!done)\r
+       {\r
+               size_t len = fread (buffer, 1, sizeof(buffer), file);\r
+               done = len < sizeof(buffer);\r
+\r
+               buffer[len] = 0;\r
+               if(!XML_Parse(parser, buffer, len, done)) \r
+               {\r
+                       Log("!  ERROR: Could not parse the xml file");\r
+                       return ERR_GENERIC;\r
+               }\r
+       }\r
+\r
+       XML_ParserFree(parser);\r
+       fclose(file);\r
+\r
+       return ERR_OK;\r
+}\r
+\r
diff --git a/rosapps/packmgr/lib/en.rc b/rosapps/packmgr/lib/en.rc
new file mode 100644 (file)
index 0000000..386b5bb
--- /dev/null
@@ -0,0 +1,19 @@
+\r
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US\r
+\r
+/* String Tables */\r
+STRINGTABLE DISCARDABLE \r
+BEGIN\r
+  IDS_LOAD        "Loading ..."\r
+  ERR_OK          "Operation done."\r
+  ERR_PACK        "Not all packages could be installed\n\nPlease have a look at the log file for details."\r
+  ERR_GENERIC      "An error occured. \nFor more information please have a look at the log file."\r
+  ERR_DOWNL       "A needed file could not be downloaded!\nFor more information please have a look at the log file."\r
+  ERR_FILE        "Error while Script Execution.\nFile could not be opened."\r
\r
+  ERR_SYNATX       "Error while Script Execution.\nWrong Synatx."\r
+  ERR_CALL         "Error while Script Execution.\nCould not find function."\r
+  ERR_PARAMETER    "Error while Script Execution.\nWrong Parameter(s)."\r
+END\r
+\r
+/* EOF */\r
diff --git a/rosapps/packmgr/lib/error.h b/rosapps/packmgr/lib/error.h
new file mode 100644 (file)
index 0000000..847c699
--- /dev/null
@@ -0,0 +1,16 @@
+// error.h\r
+\r
+#define ERR_OK         0x000\r
+#define ERR_GENERIC    0x001\r
+#define ERR_DOWNL         0x002\r
+#define ERR_NOTODO        0x003 // without text yet\r
+#define ERR_PACK          0x004\r
+\r
+// Script\r
+#define ERR_SYNATX     0x011\r
+#define ERR_CALL       0x012\r
+#define ERR_PARAMETER  0x013\r
+#define ERR_FILE          0x014\r
+\r
+#define IDS_LOAD          0x254\r
+#define NOTFOUND          -1\r
diff --git a/rosapps/packmgr/lib/expat.h b/rosapps/packmgr/lib/expat.h
new file mode 100644 (file)
index 0000000..c6d86a2
--- /dev/null
@@ -0,0 +1,1081 @@
+/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd\r
+   See the file COPYING for copying permission.\r
+*/\r
+\r
+#ifndef XmlParse_INCLUDED\r
+#define XmlParse_INCLUDED 1\r
+\r
+#ifdef __VMS\r
+/*      0        1         2         3      0        1         2         3\r
+        1234567890123456789012345678901     1234567890123456789012345678901 */\r
+#define XML_SetProcessingInstructionHandler XML_SetProcessingInstrHandler\r
+#define XML_SetUnparsedEntityDeclHandler    XML_SetUnparsedEntDeclHandler\r
+#define XML_SetStartNamespaceDeclHandler    XML_SetStartNamespcDeclHandler\r
+#define XML_SetExternalEntityRefHandlerArg  XML_SetExternalEntRefHandlerArg\r
+#endif\r
+\r
+#include <stdlib.h>\r
+\r
+#if defined(_MSC_EXTENSIONS) && !defined(__BEOS__) && !defined(__CYGWIN__)\r
+#define XML_USE_MSC_EXTENSIONS 1\r
+#endif\r
+\r
+/* Expat tries very hard to make the API boundary very specifically\r
+   defined.  There are two macros defined to control this boundary;\r
+   each of these can be defined before including this header to\r
+   achieve some different behavior, but doing so it not recommended or\r
+   tested frequently.\r
+\r
+   XMLCALL    - The calling convention to use for all calls across the\r
+                "library boundary."  This will default to cdecl, and\r
+                try really hard to tell the compiler that's what we\r
+                want.\r
+\r
+   XMLIMPORT  - Whatever magic is needed to note that a function is\r
+                to be imported from a dynamically loaded library\r
+                (.dll, .so, or .sl, depending on your platform).\r
+\r
+   The XMLCALL macro was added in Expat 1.95.7.  The only one which is\r
+   expected to be directly useful in client code is XMLCALL.\r
+\r
+   Note that on at least some Unix versions, the Expat library must be\r
+   compiled with the cdecl calling convention as the default since\r
+   system headers may assume the cdecl convention.\r
+*/\r
+#ifndef XMLCALL\r
+#if defined(XML_USE_MSC_EXTENSIONS)\r
+#define XMLCALL __cdecl\r
+#elif defined(__GNUC__) && defined(__i386)\r
+//MF#define XMLCALL __attribute__((cdecl))\r
+#define XMLCALL//MF\r
+#else\r
+/* For any platform which uses this definition and supports more than\r
+   one calling convention, we need to extend this definition to\r
+   declare the convention used on that platform, if it's possible to\r
+   do so.\r
+\r
+   If this is the case for your platform, please file a bug report\r
+   with information on how to identify your platform via the C\r
+   pre-processor and how to specify the same calling convention as the\r
+   platform's malloc() implementation.\r
+*/\r
+#define XMLCALL\r
+#endif\r
+#endif  /* not defined XMLCALL */\r
+\r
+\r
+#if !defined(XML_STATIC) && !defined(XMLIMPORT)\r
+#ifndef XML_BUILDING_EXPAT\r
+/* using Expat from an application */\r
+\r
+#ifdef XML_USE_MSC_EXTENSIONS\r
+#define XMLIMPORT __declspec(dllimport)\r
+#endif\r
+\r
+#endif\r
+#endif  /* not defined XML_STATIC */\r
+\r
+/* If we didn't define it above, define it away: */\r
+#ifndef XMLIMPORT\r
+#define XMLIMPORT\r
+#endif\r
+\r
+\r
+#define XMLPARSEAPI(type) XMLIMPORT type XMLCALL\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+#ifdef XML_UNICODE_WCHAR_T\r
+#define XML_UNICODE\r
+#endif\r
+\r
+struct XML_ParserStruct;\r
+typedef struct XML_ParserStruct *XML_Parser;\r
+\r
+#ifdef XML_UNICODE     /* Information is UTF-16 encoded. */\r
+#ifdef XML_UNICODE_WCHAR_T\r
+typedef wchar_t XML_Char;\r
+typedef wchar_t XML_LChar;\r
+#else\r
+typedef unsigned short XML_Char;\r
+typedef char XML_LChar;\r
+#endif /* XML_UNICODE_WCHAR_T */\r
+#else                  /* Information is UTF-8 encoded. */\r
+typedef char XML_Char;\r
+typedef char XML_LChar;\r
+#endif /* XML_UNICODE */\r
+\r
+/* Should this be defined using stdbool.h when C99 is available? */\r
+typedef unsigned char XML_Bool;\r
+#define XML_TRUE   ((XML_Bool) 1)\r
+#define XML_FALSE  ((XML_Bool) 0)\r
+\r
+/* The XML_Status enum gives the possible return values for several\r
+   API functions.  The preprocessor #defines are included so this\r
+   stanza can be added to code that still needs to support older\r
+   versions of Expat 1.95.x:\r
+\r
+   #ifndef XML_STATUS_OK\r
+   #define XML_STATUS_OK    1\r
+   #define XML_STATUS_ERROR 0\r
+   #endif\r
+\r
+   Otherwise, the #define hackery is quite ugly and would have been\r
+   dropped.\r
+*/\r
+enum XML_Status {\r
+  XML_STATUS_ERROR = 0,\r
+#define XML_STATUS_ERROR XML_STATUS_ERROR\r
+  XML_STATUS_OK = 1,\r
+#define XML_STATUS_OK XML_STATUS_OK\r
+  XML_STATUS_SUSPENDED = 2,\r
+#define XML_STATUS_SUSPENDED XML_STATUS_SUSPENDED\r
+};\r
+\r
+enum XML_Error {\r
+  XML_ERROR_NONE,\r
+  XML_ERROR_NO_MEMORY,\r
+  XML_ERROR_SYNTAX,\r
+  XML_ERROR_NO_ELEMENTS,\r
+  XML_ERROR_INVALID_TOKEN,\r
+  XML_ERROR_UNCLOSED_TOKEN,\r
+  XML_ERROR_PARTIAL_CHAR,\r
+  XML_ERROR_TAG_MISMATCH,\r
+  XML_ERROR_DUPLICATE_ATTRIBUTE,\r
+  XML_ERROR_JUNK_AFTER_DOC_ELEMENT,\r
+  XML_ERROR_PARAM_ENTITY_REF,\r
+  XML_ERROR_UNDEFINED_ENTITY,\r
+  XML_ERROR_RECURSIVE_ENTITY_REF,\r
+  XML_ERROR_ASYNC_ENTITY,\r
+  XML_ERROR_BAD_CHAR_REF,\r
+  XML_ERROR_BINARY_ENTITY_REF,\r
+  XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF,\r
+  XML_ERROR_MISPLACED_XML_PI,\r
+  XML_ERROR_UNKNOWN_ENCODING,\r
+  XML_ERROR_INCORRECT_ENCODING,\r
+  XML_ERROR_UNCLOSED_CDATA_SECTION,\r
+  XML_ERROR_EXTERNAL_ENTITY_HANDLING,\r
+  XML_ERROR_NOT_STANDALONE,\r
+  XML_ERROR_UNEXPECTED_STATE,\r
+  XML_ERROR_ENTITY_DECLARED_IN_PE,\r
+  XML_ERROR_FEATURE_REQUIRES_XML_DTD,\r
+  XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING,\r
+  XML_ERROR_UNBOUND_PREFIX,\r
+  XML_ERROR_SUSPENDED,\r
+  XML_ERROR_NOT_SUSPENDED,\r
+  XML_ERROR_ABORTED,\r
+  XML_ERROR_FINISHED,\r
+  XML_ERROR_SUSPEND_PE\r
+};\r
+\r
+enum XML_Content_Type {\r
+  XML_CTYPE_EMPTY = 1,\r
+  XML_CTYPE_ANY,\r
+  XML_CTYPE_MIXED,\r
+  XML_CTYPE_NAME,\r
+  XML_CTYPE_CHOICE,\r
+  XML_CTYPE_SEQ\r
+};\r
+\r
+enum XML_Content_Quant {\r
+  XML_CQUANT_NONE,\r
+  XML_CQUANT_OPT,\r
+  XML_CQUANT_REP,\r
+  XML_CQUANT_PLUS\r
+};\r
+\r
+/* If type == XML_CTYPE_EMPTY or XML_CTYPE_ANY, then quant will be\r
+   XML_CQUANT_NONE, and the other fields will be zero or NULL.\r
+   If type == XML_CTYPE_MIXED, then quant will be NONE or REP and\r
+   numchildren will contain number of elements that may be mixed in\r
+   and children point to an array of XML_Content cells that will be\r
+   all of XML_CTYPE_NAME type with no quantification.\r
+\r
+   If type == XML_CTYPE_NAME, then the name points to the name, and\r
+   the numchildren field will be zero and children will be NULL. The\r
+   quant fields indicates any quantifiers placed on the name.\r
+\r
+   CHOICE and SEQ will have name NULL, the number of children in\r
+   numchildren and children will point, recursively, to an array\r
+   of XML_Content cells.\r
+\r
+   The EMPTY, ANY, and MIXED types will only occur at top level.\r
+*/\r
+\r
+typedef struct XML_cp XML_Content;\r
+\r
+struct XML_cp {\r
+  enum XML_Content_Type         type;\r
+  enum XML_Content_Quant        quant;\r
+  XML_Char *                    name;\r
+  unsigned int                  numchildren;\r
+  XML_Content *                 children;\r
+};\r
+\r
+\r
+/* This is called for an element declaration. See above for\r
+   description of the model argument. It's the caller's responsibility\r
+   to free model when finished with it.\r
+*/\r
+typedef void (XMLCALL *XML_ElementDeclHandler) (void *userData,\r
+                                                const XML_Char *name,\r
+                                                XML_Content *model);\r
+\r
+XMLPARSEAPI(void)\r
+XML_SetElementDeclHandler(XML_Parser parser,\r
+                          XML_ElementDeclHandler eldecl);\r
+\r
+/* The Attlist declaration handler is called for *each* attribute. So\r
+   a single Attlist declaration with multiple attributes declared will\r
+   generate multiple calls to this handler. The "default" parameter\r
+   may be NULL in the case of the "#IMPLIED" or "#REQUIRED"\r
+   keyword. The "isrequired" parameter will be true and the default\r
+   value will be NULL in the case of "#REQUIRED". If "isrequired" is\r
+   true and default is non-NULL, then this is a "#FIXED" default.\r
+*/\r
+typedef void (XMLCALL *XML_AttlistDeclHandler) (\r
+                                    void            *userData,\r
+                                    const XML_Char  *elname,\r
+                                    const XML_Char  *attname,\r
+                                    const XML_Char  *att_type,\r
+                                    const XML_Char  *dflt,\r
+                                    int              isrequired);\r
+\r
+XMLPARSEAPI(void)\r
+XML_SetAttlistDeclHandler(XML_Parser parser,\r
+                          XML_AttlistDeclHandler attdecl);\r
+\r
+/* The XML declaration handler is called for *both* XML declarations\r
+   and text declarations. The way to distinguish is that the version\r
+   parameter will be NULL for text declarations. The encoding\r
+   parameter may be NULL for XML declarations. The standalone\r
+   parameter will be -1, 0, or 1 indicating respectively that there\r
+   was no standalone parameter in the declaration, that it was given\r
+   as no, or that it was given as yes.\r
+*/\r
+typedef void (XMLCALL *XML_XmlDeclHandler) (void           *userData,\r
+                                            const XML_Char *version,\r
+                                            const XML_Char *encoding,\r
+                                            int             standalone);\r
+\r
+XMLPARSEAPI(void)\r
+XML_SetXmlDeclHandler(XML_Parser parser,\r
+                      XML_XmlDeclHandler xmldecl);\r
+\r
+\r
+typedef struct {\r
+  void *(XMLCALL *malloc_fcn)(size_t size);\r
+  void *(XMLCALL *realloc_fcn)(void *ptr, size_t size);\r
+  void (XMLCALL *free_fcn)(void *ptr);\r
+} XML_Memory_Handling_Suite;\r
+\r
+/* Constructs a new parser; encoding is the encoding specified by the\r
+   external protocol or NULL if there is none specified.\r
+*/\r
+XMLPARSEAPI(XML_Parser)\r
+XML_ParserCreate(const XML_Char *encoding);\r
+\r
+/* Constructs a new parser and namespace processor.  Element type\r
+   names and attribute names that belong to a namespace will be\r
+   expanded; unprefixed attribute names are never expanded; unprefixed\r
+   element type names are expanded only if there is a default\r
+   namespace. The expanded name is the concatenation of the namespace\r
+   URI, the namespace separator character, and the local part of the\r
+   name.  If the namespace separator is '\0' then the namespace URI\r
+   and the local part will be concatenated without any separator.\r
+   When a namespace is not declared, the name and prefix will be\r
+   passed through without expansion.\r
+*/\r
+XMLPARSEAPI(XML_Parser)\r
+XML_ParserCreateNS(const XML_Char *encoding, XML_Char namespaceSeparator);\r
+\r
+\r
+/* Constructs a new parser using the memory management suite referred to\r
+   by memsuite. If memsuite is NULL, then use the standard library memory\r
+   suite. If namespaceSeparator is non-NULL it creates a parser with\r
+   namespace processing as described above. The character pointed at\r
+   will serve as the namespace separator.\r
+\r
+   All further memory operations used for the created parser will come from\r
+   the given suite.\r
+*/\r
+XMLPARSEAPI(XML_Parser)\r
+XML_ParserCreate_MM(const XML_Char *encoding,\r
+                    const XML_Memory_Handling_Suite *memsuite,\r
+                    const XML_Char *namespaceSeparator);\r
+\r
+/* Prepare a parser object to be re-used.  This is particularly\r
+   valuable when memory allocation overhead is disproportionatly high,\r
+   such as when a large number of small documnents need to be parsed.\r
+   All handlers are cleared from the parser, except for the\r
+   unknownEncodingHandler. The parser's external state is re-initialized\r
+   except for the values of ns and ns_triplets.\r
+\r
+   Added in Expat 1.95.3.\r
+*/\r
+XMLPARSEAPI(XML_Bool)\r
+XML_ParserReset(XML_Parser parser, const XML_Char *encoding);\r
+\r
+/* atts is array of name/value pairs, terminated by 0;\r
+   names and values are 0 terminated.\r
+*/\r
+typedef void (XMLCALL *XML_StartElementHandler) (void *userData,\r
+                                                 const XML_Char *name,\r
+                                                 const XML_Char **atts);\r
+\r
+typedef void (XMLCALL *XML_EndElementHandler) (void *userData,\r
+                                               const XML_Char *name);\r
+\r
+\r
+/* s is not 0 terminated. */\r
+typedef void (XMLCALL *XML_CharacterDataHandler) (void *userData,\r
+                                                  const XML_Char *s,\r
+                                                  int len);\r
+\r
+/* target and data are 0 terminated */\r
+typedef void (XMLCALL *XML_ProcessingInstructionHandler) (\r
+                                                void *userData,\r
+                                                const XML_Char *target,\r
+                                                const XML_Char *data);\r
+\r
+/* data is 0 terminated */\r
+typedef void (XMLCALL *XML_CommentHandler) (void *userData,\r
+                                            const XML_Char *data);\r
+\r
+typedef void (XMLCALL *XML_StartCdataSectionHandler) (void *userData);\r
+typedef void (XMLCALL *XML_EndCdataSectionHandler) (void *userData);\r
+\r
+/* This is called for any characters in the XML document for which\r
+   there is no applicable handler.  This includes both characters that\r
+   are part of markup which is of a kind that is not reported\r
+   (comments, markup declarations), or characters that are part of a\r
+   construct which could be reported but for which no handler has been\r
+   supplied. The characters are passed exactly as they were in the XML\r
+   document except that they will be encoded in UTF-8 or UTF-16.\r
+   Line boundaries are not normalized. Note that a byte order mark\r
+   character is not passed to the default handler. There are no\r
+   guarantees about how characters are divided between calls to the\r
+   default handler: for example, a comment might be split between\r
+   multiple calls.\r
+*/\r
+typedef void (XMLCALL *XML_DefaultHandler) (void *userData,\r
+                                            const XML_Char *s,\r
+                                            int len);\r
+\r
+/* This is called for the start of the DOCTYPE declaration, before\r
+   any DTD or internal subset is parsed.\r
+*/\r
+typedef void (XMLCALL *XML_StartDoctypeDeclHandler) (\r
+                                            void *userData,\r
+                                            const XML_Char *doctypeName,\r
+                                            const XML_Char *sysid,\r
+                                            const XML_Char *pubid,\r
+                                            int has_internal_subset);\r
+\r
+/* This is called for the start of the DOCTYPE declaration when the\r
+   closing > is encountered, but after processing any external\r
+   subset.\r
+*/\r
+typedef void (XMLCALL *XML_EndDoctypeDeclHandler)(void *userData);\r
+\r
+/* This is called for entity declarations. The is_parameter_entity\r
+   argument will be non-zero if the entity is a parameter entity, zero\r
+   otherwise.\r
+\r
+   For internal entities (<!ENTITY foo "bar">), value will\r
+   be non-NULL and systemId, publicID, and notationName will be NULL.\r
+   The value string is NOT nul-terminated; the length is provided in\r
+   the value_length argument. Since it is legal to have zero-length\r
+   values, do not use this argument to test for internal entities.\r
+\r
+   For external entities, value will be NULL and systemId will be\r
+   non-NULL. The publicId argument will be NULL unless a public\r
+   identifier was provided. The notationName argument will have a\r
+   non-NULL value only for unparsed entity declarations.\r
+\r
+   Note that is_parameter_entity can't be changed to XML_Bool, since\r
+   that would break binary compatibility.\r
+*/\r
+typedef void (XMLCALL *XML_EntityDeclHandler) (\r
+                              void *userData,\r
+                              const XML_Char *entityName,\r
+                              int is_parameter_entity,\r
+                              const XML_Char *value,\r
+                              int value_length,\r
+                              const XML_Char *base,\r
+                              const XML_Char *systemId,\r
+                              const XML_Char *publicId,\r
+                              const XML_Char *notationName);\r
+\r
+XMLPARSEAPI(void)\r
+XML_SetEntityDeclHandler(XML_Parser parser,\r
+                         XML_EntityDeclHandler handler);\r
+\r
+/* OBSOLETE -- OBSOLETE -- OBSOLETE\r
+   This handler has been superceded by the EntityDeclHandler above.\r
+   It is provided here for backward compatibility.\r
+\r
+   This is called for a declaration of an unparsed (NDATA) entity.\r
+   The base argument is whatever was set by XML_SetBase. The\r
+   entityName, systemId and notationName arguments will never be\r
+   NULL. The other arguments may be.\r
+*/\r
+typedef void (XMLCALL *XML_UnparsedEntityDeclHandler) (\r
+                                    void *userData,\r
+                                    const XML_Char *entityName,\r
+                                    const XML_Char *base,\r
+                                    const XML_Char *systemId,\r
+                                    const XML_Char *publicId,\r
+                                    const XML_Char *notationName);\r
+\r
+/* This is called for a declaration of notation.  The base argument is\r
+   whatever was set by XML_SetBase. The notationName will never be\r
+   NULL.  The other arguments can be.\r
+*/\r
+typedef void (XMLCALL *XML_NotationDeclHandler) (\r
+                                    void *userData,\r
+                                    const XML_Char *notationName,\r
+                                    const XML_Char *base,\r
+                                    const XML_Char *systemId,\r
+                                    const XML_Char *publicId);\r
+\r
+/* When namespace processing is enabled, these are called once for\r
+   each namespace declaration. The call to the start and end element\r
+   handlers occur between the calls to the start and end namespace\r
+   declaration handlers. For an xmlns attribute, prefix will be\r
+   NULL.  For an xmlns="" attribute, uri will be NULL.\r
+*/\r
+typedef void (XMLCALL *XML_StartNamespaceDeclHandler) (\r
+                                    void *userData,\r
+                                    const XML_Char *prefix,\r
+                                    const XML_Char *uri);\r
+\r
+typedef void (XMLCALL *XML_EndNamespaceDeclHandler) (\r
+                                    void *userData,\r
+                                    const XML_Char *prefix);\r
+\r
+/* This is called if the document is not standalone, that is, it has an\r
+   external subset or a reference to a parameter entity, but does not\r
+   have standalone="yes". If this handler returns XML_STATUS_ERROR,\r
+   then processing will not continue, and the parser will return a\r
+   XML_ERROR_NOT_STANDALONE error.\r
+   If parameter entity parsing is enabled, then in addition to the\r
+   conditions above this handler will only be called if the referenced\r
+   entity was actually read.\r
+*/\r
+typedef int (XMLCALL *XML_NotStandaloneHandler) (void *userData);\r
+\r
+/* This is called for a reference to an external parsed general\r
+   entity.  The referenced entity is not automatically parsed.  The\r
+   application can parse it immediately or later using\r
+   XML_ExternalEntityParserCreate.\r
+\r
+   The parser argument is the parser parsing the entity containing the\r
+   reference; it can be passed as the parser argument to\r
+   XML_ExternalEntityParserCreate.  The systemId argument is the\r
+   system identifier as specified in the entity declaration; it will\r
+   not be NULL.\r
+\r
+   The base argument is the system identifier that should be used as\r
+   the base for resolving systemId if systemId was relative; this is\r
+   set by XML_SetBase; it may be NULL.\r
+\r
+   The publicId argument is the public identifier as specified in the\r
+   entity declaration, or NULL if none was specified; the whitespace\r
+   in the public identifier will have been normalized as required by\r
+   the XML spec.\r
+\r
+   The context argument specifies the parsing context in the format\r
+   expected by the context argument to XML_ExternalEntityParserCreate;\r
+   context is valid only until the handler returns, so if the\r
+   referenced entity is to be parsed later, it must be copied.\r
+   context is NULL only when the entity is a parameter entity.\r
+\r
+   The handler should return XML_STATUS_ERROR if processing should not\r
+   continue because of a fatal error in the handling of the external\r
+   entity.  In this case the calling parser will return an\r
+   XML_ERROR_EXTERNAL_ENTITY_HANDLING error.\r
+\r
+   Note that unlike other handlers the first argument is the parser,\r
+   not userData.\r
+*/\r
+typedef int (XMLCALL *XML_ExternalEntityRefHandler) (\r
+                                    XML_Parser parser,\r
+                                    const XML_Char *context,\r
+                                    const XML_Char *base,\r
+                                    const XML_Char *systemId,\r
+                                    const XML_Char *publicId);\r
+\r
+/* This is called in two situations:\r
+   1) An entity reference is encountered for which no declaration\r
+      has been read *and* this is not an error.\r
+   2) An internal entity reference is read, but not expanded, because\r
+      XML_SetDefaultHandler has been called.\r
+   Note: skipped parameter entities in declarations and skipped general\r
+         entities in attribute values cannot be reported, because\r
+         the event would be out of sync with the reporting of the\r
+         declarations or attribute values\r
+*/\r
+typedef void (XMLCALL *XML_SkippedEntityHandler) (\r
+                                    void *userData,\r
+                                    const XML_Char *entityName,\r
+                                    int is_parameter_entity);\r
+\r
+/* This structure is filled in by the XML_UnknownEncodingHandler to\r
+   provide information to the parser about encodings that are unknown\r
+   to the parser.\r
+\r
+   The map[b] member gives information about byte sequences whose\r
+   first byte is b.\r
+\r
+   If map[b] is c where c is >= 0, then b by itself encodes the\r
+   Unicode scalar value c.\r
+\r
+   If map[b] is -1, then the byte sequence is malformed.\r
+\r
+   If map[b] is -n, where n >= 2, then b is the first byte of an\r
+   n-byte sequence that encodes a single Unicode scalar value.\r
+\r
+   The data member will be passed as the first argument to the convert\r
+   function.\r
+\r
+   The convert function is used to convert multibyte sequences; s will\r
+   point to a n-byte sequence where map[(unsigned char)*s] == -n.  The\r
+   convert function must return the Unicode scalar value represented\r
+   by this byte sequence or -1 if the byte sequence is malformed.\r
+\r
+   The convert function may be NULL if the encoding is a single-byte\r
+   encoding, that is if map[b] >= -1 for all bytes b.\r
+\r
+   When the parser is finished with the encoding, then if release is\r
+   not NULL, it will call release passing it the data member; once\r
+   release has been called, the convert function will not be called\r
+   again.\r
+\r
+   Expat places certain restrictions on the encodings that are supported\r
+   using this mechanism.\r
+\r
+   1. Every ASCII character that can appear in a well-formed XML document,\r
+      other than the characters\r
+\r
+      $@\^`{}~\r
+\r
+      must be represented by a single byte, and that byte must be the\r
+      same byte that represents that character in ASCII.\r
+\r
+   2. No character may require more than 4 bytes to encode.\r
+\r
+   3. All characters encoded must have Unicode scalar values <=\r
+      0xFFFF, (i.e., characters that would be encoded by surrogates in\r
+      UTF-16 are  not allowed).  Note that this restriction doesn't\r
+      apply to the built-in support for UTF-8 and UTF-16.\r
+\r
+   4. No Unicode character may be encoded by more than one distinct\r
+      sequence of bytes.\r
+*/\r
+typedef struct {\r
+  int map[256];\r
+  void *data;\r
+  int (XMLCALL *convert)(void *data, const char *s);\r
+  void (XMLCALL *release)(void *data);\r
+} XML_Encoding;\r
+\r
+/* This is called for an encoding that is unknown to the parser.\r
+\r
+   The encodingHandlerData argument is that which was passed as the\r
+   second argument to XML_SetUnknownEncodingHandler.\r
+\r
+   The name argument gives the name of the encoding as specified in\r
+   the encoding declaration.\r
+\r
+   If the callback can provide information about the encoding, it must\r
+   fill in the XML_Encoding structure, and return XML_STATUS_OK.\r
+   Otherwise it must return XML_STATUS_ERROR.\r
+\r
+   If info does not describe a suitable encoding, then the parser will\r
+   return an XML_UNKNOWN_ENCODING error.\r
+*/\r
+typedef int (XMLCALL *XML_UnknownEncodingHandler) (\r
+                                    void *encodingHandlerData,\r
+                                    const XML_Char *name,\r
+                                    XML_Encoding *info);\r
+\r
+XMLPARSEAPI(void)\r
+XML_SetElementHandler(XML_Parser parser,\r
+                      XML_StartElementHandler start,\r
+                      XML_EndElementHandler end);\r
+\r
+XMLPARSEAPI(void)\r
+XML_SetStartElementHandler(XML_Parser parser,\r
+                           XML_StartElementHandler handler);\r
+\r
+XMLPARSEAPI(void)\r
+XML_SetEndElementHandler(XML_Parser parser,\r
+                         XML_EndElementHandler handler);\r
+\r
+XMLPARSEAPI(void)\r
+XML_SetCharacterDataHandler(XML_Parser parser,\r
+                            XML_CharacterDataHandler handler);\r
+\r
+XMLPARSEAPI(void)\r
+XML_SetProcessingInstructionHandler(XML_Parser parser,\r
+                                    XML_ProcessingInstructionHandler handler);\r
+XMLPARSEAPI(void)\r
+XML_SetCommentHandler(XML_Parser parser,\r
+                      XML_CommentHandler handler);\r
+\r
+XMLPARSEAPI(void)\r
+XML_SetCdataSectionHandler(XML_Parser parser,\r
+                           XML_StartCdataSectionHandler start,\r
+                           XML_EndCdataSectionHandler end);\r
+\r
+XMLPARSEAPI(void)\r
+XML_SetStartCdataSectionHandler(XML_Parser parser,\r
+                                XML_StartCdataSectionHandler start);\r
+\r
+XMLPARSEAPI(void)\r
+XML_SetEndCdataSectionHandler(XML_Parser parser,\r
+                              XML_EndCdataSectionHandler end);\r
+\r
+/* This sets the default handler and also inhibits expansion of\r
+   internal entities. These entity references will be passed to the\r
+   default handler, or to the skipped entity handler, if one is set.\r
+*/\r
+XMLPARSEAPI(void)\r
+XML_SetDefaultHandler(XML_Parser parser,\r
+                      XML_DefaultHandler handler);\r
+\r
+/* This sets the default handler but does not inhibit expansion of\r
+   internal entities.  The entity reference will not be passed to the\r
+   default handler.\r
+*/\r
+XMLPARSEAPI(void)\r
+XML_SetDefaultHandlerExpand(XML_Parser parser,\r
+                            XML_DefaultHandler handler);\r
+\r
+XMLPARSEAPI(void)\r
+XML_SetDoctypeDeclHandler(XML_Parser parser,\r
+                          XML_StartDoctypeDeclHandler start,\r
+                          XML_EndDoctypeDeclHandler end);\r
+\r
+XMLPARSEAPI(void)\r
+XML_SetStartDoctypeDeclHandler(XML_Parser parser,\r
+                               XML_StartDoctypeDeclHandler start);\r
+\r
+XMLPARSEAPI(void)\r
+XML_SetEndDoctypeDeclHandler(XML_Parser parser,\r
+                             XML_EndDoctypeDeclHandler end);\r
+\r
+XMLPARSEAPI(void)\r
+XML_SetUnparsedEntityDeclHandler(XML_Parser parser,\r
+                                 XML_UnparsedEntityDeclHandler handler);\r
+\r
+XMLPARSEAPI(void)\r
+XML_SetNotationDeclHandler(XML_Parser parser,\r
+                           XML_NotationDeclHandler handler);\r
+\r
+XMLPARSEAPI(void)\r
+XML_SetNamespaceDeclHandler(XML_Parser parser,\r
+                            XML_StartNamespaceDeclHandler start,\r
+                            XML_EndNamespaceDeclHandler end);\r
+\r
+XMLPARSEAPI(void)\r
+XML_SetStartNamespaceDeclHandler(XML_Parser parser,\r
+                                 XML_StartNamespaceDeclHandler start);\r
+\r
+XMLPARSEAPI(void)\r
+XML_SetEndNamespaceDeclHandler(XML_Parser parser,\r
+                               XML_EndNamespaceDeclHandler end);\r
+\r
+XMLPARSEAPI(void)\r
+XML_SetNotStandaloneHandler(XML_Parser parser,\r
+                            XML_NotStandaloneHandler handler);\r
+\r
+XMLPARSEAPI(void)\r
+XML_SetExternalEntityRefHandler(XML_Parser parser,\r
+                                XML_ExternalEntityRefHandler handler);\r
+\r
+/* If a non-NULL value for arg is specified here, then it will be\r
+   passed as the first argument to the external entity ref handler\r
+   instead of the parser object.\r
+*/\r
+XMLPARSEAPI(void)\r
+XML_SetExternalEntityRefHandlerArg(XML_Parser parser,\r
+                                   void *arg);\r
+\r
+XMLPARSEAPI(void)\r
+XML_SetSkippedEntityHandler(XML_Parser parser,\r
+                            XML_SkippedEntityHandler handler);\r
+\r
+XMLPARSEAPI(void)\r
+XML_SetUnknownEncodingHandler(XML_Parser parser,\r
+                              XML_UnknownEncodingHandler handler,\r
+                              void *encodingHandlerData);\r
+\r
+/* This can be called within a handler for a start element, end\r
+   element, processing instruction or character data.  It causes the\r
+   corresponding markup to be passed to the default handler.\r
+*/\r
+XMLPARSEAPI(void)\r
+XML_DefaultCurrent(XML_Parser parser);\r
+\r
+/* If do_nst is non-zero, and namespace processing is in effect, and\r
+   a name has a prefix (i.e. an explicit namespace qualifier) then\r
+   that name is returned as a triplet in a single string separated by\r
+   the separator character specified when the parser was created: URI\r
+   + sep + local_name + sep + prefix.\r
+\r
+   If do_nst is zero, then namespace information is returned in the\r
+   default manner (URI + sep + local_name) whether or not the name\r
+   has a prefix.\r
+\r
+   Note: Calling XML_SetReturnNSTriplet after XML_Parse or\r
+     XML_ParseBuffer has no effect.\r
+*/\r
+\r
+XMLPARSEAPI(void)\r
+XML_SetReturnNSTriplet(XML_Parser parser, int do_nst);\r
+\r
+/* This value is passed as the userData argument to callbacks. */\r
+XMLPARSEAPI(void)\r
+XML_SetUserData(XML_Parser parser, void *userData);\r
+\r
+/* Returns the last value set by XML_SetUserData or NULL. */\r
+#define XML_GetUserData(parser) (*(void **)(parser))\r
+\r
+/* This is equivalent to supplying an encoding argument to\r
+   XML_ParserCreate. On success XML_SetEncoding returns non-zero,\r
+   zero otherwise.\r
+   Note: Calling XML_SetEncoding after XML_Parse or XML_ParseBuffer\r
+     has no effect and returns XML_STATUS_ERROR.\r
+*/\r
+XMLPARSEAPI(enum XML_Status)\r
+XML_SetEncoding(XML_Parser parser, const XML_Char *encoding);\r
+\r
+/* If this function is called, then the parser will be passed as the\r
+   first argument to callbacks instead of userData.  The userData will\r
+   still be accessible using XML_GetUserData.\r
+*/\r
+XMLPARSEAPI(void)\r
+XML_UseParserAsHandlerArg(XML_Parser parser);\r
+\r
+/* If useDTD == XML_TRUE is passed to this function, then the parser\r
+   will assume that there is an external subset, even if none is\r
+   specified in the document. In such a case the parser will call the\r
+   externalEntityRefHandler with a value of NULL for the systemId\r
+   argument (the publicId and context arguments will be NULL as well).\r
+   Note: If this function is called, then this must be done before\r
+     the first call to XML_Parse or XML_ParseBuffer, since it will\r
+     have no effect after that.  Returns\r
+     XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING.\r
+   Note: If the document does not have a DOCTYPE declaration at all,\r
+     then startDoctypeDeclHandler and endDoctypeDeclHandler will not\r
+     be called, despite an external subset being parsed.\r
+   Note: If XML_DTD is not defined when Expat is compiled, returns\r
+     XML_ERROR_FEATURE_REQUIRES_XML_DTD.\r
+*/\r
+XMLPARSEAPI(enum XML_Error)\r
+XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD);\r
+\r
+\r
+/* Sets the base to be used for resolving relative URIs in system\r
+   identifiers in declarations.  Resolving relative identifiers is\r
+   left to the application: this value will be passed through as the\r
+   base argument to the XML_ExternalEntityRefHandler,\r
+   XML_NotationDeclHandler and XML_UnparsedEntityDeclHandler. The base\r
+   argument will be copied.  Returns XML_STATUS_ERROR if out of memory,\r
+   XML_STATUS_OK otherwise.\r
+*/\r
+XMLPARSEAPI(enum XML_Status)\r
+XML_SetBase(XML_Parser parser, const XML_Char *base);\r
+\r
+XMLPARSEAPI(const XML_Char *)\r
+XML_GetBase(XML_Parser parser);\r
+\r
+/* Returns the number of the attribute/value pairs passed in last call\r
+   to the XML_StartElementHandler that were specified in the start-tag\r
+   rather than defaulted. Each attribute/value pair counts as 2; thus\r
+   this correspondds to an index into the atts array passed to the\r
+   XML_StartElementHandler.\r
+*/\r
+XMLPARSEAPI(int)\r
+XML_GetSpecifiedAttributeCount(XML_Parser parser);\r
+\r
+/* Returns the index of the ID attribute passed in the last call to\r
+   XML_StartElementHandler, or -1 if there is no ID attribute.  Each\r
+   attribute/value pair counts as 2; thus this correspondds to an\r
+   index into the atts array passed to the XML_StartElementHandler.\r
+*/\r
+XMLPARSEAPI(int)\r
+XML_GetIdAttributeIndex(XML_Parser parser);\r
+\r
+/* Parses some input. Returns XML_STATUS_ERROR if a fatal error is\r
+   detected.  The last call to XML_Parse must have isFinal true; len\r
+   may be zero for this call (or any other).\r
+\r
+   Though the return values for these functions has always been\r
+   described as a Boolean value, the implementation, at least for the\r
+   1.95.x series, has always returned exactly one of the XML_Status\r
+   values.\r
+*/\r
+XMLPARSEAPI(enum XML_Status)\r
+XML_Parse(XML_Parser parser, const char *s, int len, int isFinal);\r
+\r
+XMLPARSEAPI(void *)\r
+XML_GetBuffer(XML_Parser parser, int len);\r
+\r
+XMLPARSEAPI(enum XML_Status)\r
+XML_ParseBuffer(XML_Parser parser, int len, int isFinal);\r
+\r
+/* Stops parsing, causing XML_Parse() or XML_ParseBuffer() to return.\r
+   Must be called from within a call-back handler, except when aborting\r
+   (resumable = 0) an already suspended parser. Some call-backs may\r
+   still follow because they would otherwise get lost. Examples:\r
+   - endElementHandler() for empty elements when stopped in\r
+     startElementHandler(), \r
+   - endNameSpaceDeclHandler() when stopped in endElementHandler(), \r
+   and possibly others.\r
+\r
+   Can be called from most handlers, including DTD related call-backs,\r
+   except when parsing an external parameter entity and resumable != 0.\r
+   Returns XML_STATUS_OK when successful, XML_STATUS_ERROR otherwise.\r
+   Possible error codes: \r
+   - XML_ERROR_SUSPENDED: when suspending an already suspended parser.\r
+   - XML_ERROR_FINISHED: when the parser has already finished.\r
+   - XML_ERROR_SUSPEND_PE: when suspending while parsing an external PE.\r
+\r
+   When resumable != 0 (true) then parsing is suspended, that is, \r
+   XML_Parse() and XML_ParseBuffer() return XML_STATUS_SUSPENDED. \r
+   Otherwise, parsing is aborted, that is, XML_Parse() and XML_ParseBuffer()\r
+   return XML_STATUS_ERROR with error code XML_ERROR_ABORTED.\r
+\r
+   *Note*:\r
+   This will be applied to the current parser instance only, that is, if\r
+   there is a parent parser then it will continue parsing when the\r
+   externalEntityRefHandler() returns. It is up to the implementation of\r
+   the externalEntityRefHandler() to call XML_StopParser() on the parent\r
+   parser (recursively), if one wants to stop parsing altogether.\r
+\r
+   When suspended, parsing can be resumed by calling XML_ResumeParser(). \r
+*/\r
+XMLPARSEAPI(enum XML_Status)\r
+XML_StopParser(XML_Parser parser, XML_Bool resumable);\r
+\r
+/* Resumes parsing after it has been suspended with XML_StopParser().\r
+   Must not be called from within a handler call-back. Returns same\r
+   status codes as XML_Parse() or XML_ParseBuffer().\r
+   Additional error code XML_ERROR_NOT_SUSPENDED possible.   \r
+\r
+   *Note*:\r
+   This must be called on the most deeply nested child parser instance\r
+   first, and on its parent parser only after the child parser has finished,\r
+   to be applied recursively until the document entity's parser is restarted.\r
+   That is, the parent parser will not resume by itself and it is up to the\r
+   application to call XML_ResumeParser() on it at the appropriate moment.\r
+*/\r
+XMLPARSEAPI(enum XML_Status)\r
+XML_ResumeParser(XML_Parser parser);\r
+\r
+enum XML_Parsing {\r
+  XML_INITIALIZED,\r
+  XML_PARSING,\r
+  XML_FINISHED,\r
+  XML_SUSPENDED\r
+};\r
+\r
+typedef struct {\r
+  enum XML_Parsing parsing;\r
+  XML_Bool finalBuffer;\r
+} XML_ParsingStatus;\r
+\r
+/* Returns status of parser with respect to being initialized, parsing,\r
+   finished, or suspended and processing the final buffer.\r
+   XXX XML_Parse() and XML_ParseBuffer() should return XML_ParsingStatus,\r
+   XXX with XML_FINISHED_OK or XML_FINISHED_ERROR replacing XML_FINISHED\r
+*/\r
+XMLPARSEAPI(void)\r
+XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status);\r
+\r
+/* Creates an XML_Parser object that can parse an external general\r
+   entity; context is a '\0'-terminated string specifying the parse\r
+   context; encoding is a '\0'-terminated string giving the name of\r
+   the externally specified encoding, or NULL if there is no\r
+   externally specified encoding.  The context string consists of a\r
+   sequence of tokens separated by formfeeds (\f); a token consisting\r
+   of a name specifies that the general entity of the name is open; a\r
+   token of the form prefix=uri specifies the namespace for a\r
+   particular prefix; a token of the form =uri specifies the default\r
+   namespace.  This can be called at any point after the first call to\r
+   an ExternalEntityRefHandler so longer as the parser has not yet\r
+   been freed.  The new parser is completely independent and may\r
+   safely be used in a separate thread.  The handlers and userData are\r
+   initialized from the parser argument.  Returns NULL if out of memory.\r
+   Otherwise returns a new XML_Parser object.\r
+*/\r
+XMLPARSEAPI(XML_Parser)\r
+XML_ExternalEntityParserCreate(XML_Parser parser,\r
+                               const XML_Char *context,\r
+                               const XML_Char *encoding);\r
+\r
+enum XML_ParamEntityParsing {\r
+  XML_PARAM_ENTITY_PARSING_NEVER,\r
+  XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE,\r
+  XML_PARAM_ENTITY_PARSING_ALWAYS\r
+};\r
+\r
+/* Controls parsing of parameter entities (including the external DTD\r
+   subset). If parsing of parameter entities is enabled, then\r
+   references to external parameter entities (including the external\r
+   DTD subset) will be passed to the handler set with\r
+   XML_SetExternalEntityRefHandler.  The context passed will be 0.\r
+\r
+   Unlike external general entities, external parameter entities can\r
+   only be parsed synchronously.  If the external parameter entity is\r
+   to be parsed, it must be parsed during the call to the external\r
+   entity ref handler: the complete sequence of\r
+   XML_ExternalEntityParserCreate, XML_Parse/XML_ParseBuffer and\r
+   XML_ParserFree calls must be made during this call.  After\r
+   XML_ExternalEntityParserCreate has been called to create the parser\r
+   for the external parameter entity (context must be 0 for this\r
+   call), it is illegal to make any calls on the old parser until\r
+   XML_ParserFree has been called on the newly created parser.\r
+   If the library has been compiled without support for parameter\r
+   entity parsing (ie without XML_DTD being defined), then\r
+   XML_SetParamEntityParsing will return 0 if parsing of parameter\r
+   entities is requested; otherwise it will return non-zero.\r
+   Note: If XML_SetParamEntityParsing is called after XML_Parse or\r
+      XML_ParseBuffer, then it has no effect and will always return 0.\r
+*/\r
+XMLPARSEAPI(int)\r
+XML_SetParamEntityParsing(XML_Parser parser,\r
+                          enum XML_ParamEntityParsing parsing);\r
+\r
+/* If XML_Parse or XML_ParseBuffer have returned XML_STATUS_ERROR, then\r
+   XML_GetErrorCode returns information about the error.\r
+*/\r
+XMLPARSEAPI(enum XML_Error)\r
+XML_GetErrorCode(XML_Parser parser);\r
+\r
+/* These functions return information about the current parse\r
+   location.  They may be called from any callback called to report\r
+   some parse event; in this case the location is the location of the\r
+   first of the sequence of characters that generated the event.  When\r
+   called from callbacks generated by declarations in the document\r
+   prologue, the location identified isn't as neatly defined, but will\r
+   be within the relevant markup.  When called outside of the callback\r
+   functions, the position indicated will be just past the last parse\r
+   event (regardless of whether there was an associated callback).\r
+   \r
+   They may also be called after returning from a call to XML_Parse\r
+   or XML_ParseBuffer.  If the return value is XML_STATUS_ERROR then\r
+   the location is the location of the character at which the error\r
+   was detected; otherwise the location is the location of the last\r
+   parse event, as described above.\r
+*/\r
+XMLPARSEAPI(int) XML_GetCurrentLineNumber(XML_Parser parser);\r
+XMLPARSEAPI(int) XML_GetCurrentColumnNumber(XML_Parser parser);\r
+XMLPARSEAPI(long) XML_GetCurrentByteIndex(XML_Parser parser);\r
+\r
+/* Return the number of bytes in the current event.\r
+   Returns 0 if the event is in an internal entity.\r
+*/\r
+XMLPARSEAPI(int)\r
+XML_GetCurrentByteCount(XML_Parser parser);\r
+\r
+/* If XML_CONTEXT_BYTES is defined, returns the input buffer, sets\r
+   the integer pointed to by offset to the offset within this buffer\r
+   of the current parse position, and sets the integer pointed to by size\r
+   to the size of this buffer (the number of input bytes). Otherwise\r
+   returns a NULL pointer. Also returns a NULL pointer if a parse isn't\r
+   active.\r
+\r
+   NOTE: The character pointer returned should not be used outside\r
+   the handler that makes the call.\r
+*/\r
+XMLPARSEAPI(const char *)\r
+XML_GetInputContext(XML_Parser parser,\r
+                    int *offset,\r
+                    int *size);\r
+\r
+/* For backwards compatibility with previous versions. */\r
+#define XML_GetErrorLineNumber   XML_GetCurrentLineNumber\r
+#define XML_GetErrorColumnNumber XML_GetCurrentColumnNumber\r
+#define XML_GetErrorByteIndex    XML_GetCurrentByteIndex\r
+\r
+/* Frees the content model passed to the element declaration handler */\r
+XMLPARSEAPI(void)\r
+XML_FreeContentModel(XML_Parser parser, XML_Content *model);\r
+\r
+/* Exposing the memory handling functions used in Expat */\r
+XMLPARSEAPI(void *)\r
+XML_MemMalloc(XML_Parser parser, size_t size);\r
+\r
+XMLPARSEAPI(void *)\r
+XML_MemRealloc(XML_Parser parser, void *ptr, size_t size);\r
+\r
+XMLPARSEAPI(void)\r
+XML_MemFree(XML_Parser parser, void *ptr);\r
+\r
+/* Frees memory used by the parser. */\r
+XMLPARSEAPI(void)\r
+XML_ParserFree(XML_Parser parser);\r
+\r
+/* Returns a string describing the error. */\r
+XMLPARSEAPI(const XML_LChar *)\r
+XML_ErrorString(enum XML_Error code);\r
+\r
+/* Return a string containing the version number of this expat */\r
+XMLPARSEAPI(const XML_LChar *)\r
+XML_ExpatVersion(void);\r
+\r
+typedef struct {\r
+  int major;\r
+  int minor;\r
+  int micro;\r
+} XML_Expat_Version;\r
+\r
+/* Return an XML_Expat_Version structure containing numeric version\r
+   number information for this version of expat.\r
+*/\r
+XMLPARSEAPI(XML_Expat_Version)\r
+XML_ExpatVersionInfo(void);\r
+\r
+/* Added in Expat 1.95.5. */\r
+enum XML_FeatureEnum {\r
+  XML_FEATURE_END = 0,\r
+  XML_FEATURE_UNICODE,\r
+  XML_FEATURE_UNICODE_WCHAR_T,\r
+  XML_FEATURE_DTD,\r
+  XML_FEATURE_CONTEXT_BYTES,\r
+  XML_FEATURE_MIN_SIZE,\r
+  XML_FEATURE_SIZEOF_XML_CHAR,\r
+  XML_FEATURE_SIZEOF_XML_LCHAR\r
+  /* Additional features must be added to the end of this enum. */\r
+};\r
+\r
+typedef struct {\r
+  enum XML_FeatureEnum  feature;\r
+  const XML_LChar       *name;\r
+  long int              value;\r
+} XML_Feature;\r
+\r
+XMLPARSEAPI(const XML_Feature *)\r
+XML_GetFeatureList(void);\r
+\r
+\r
+/* Expat follows the GNU/Linux convention of odd number minor version for\r
+   beta/development releases and even number minor version for stable\r
+   releases. Micro is bumped with each release, and set to 0 with each\r
+   change to major or minor version.\r
+*/\r
+#define XML_MAJOR_VERSION 1\r
+#define XML_MINOR_VERSION 95\r
+#define XML_MICRO_VERSION 8\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* not XmlParse_INCLUDED */\r
diff --git a/rosapps/packmgr/lib/functions.cpp b/rosapps/packmgr/lib/functions.cpp
new file mode 100644 (file)
index 0000000..d7524d6
--- /dev/null
@@ -0,0 +1,101 @@
+////////////////////////////////////////////////////////\r
+//\r
+// script.cpp\r
+// \r
+// Script Functions\r
+//\r
+//\r
+// Klemens Friedl, 19.03.2005\r
+// frik85@hotmail.com\r
+//\r
+////////////////////////////////////////////////////////////////////\r
+\r
+#include "package.hpp"\r
+#include "script.h"\r
+#include "log.h"\r
+\r
+extern const char* tree_server;\r
+char* PML_Download (const char* name, const char* local_name, const char* server, BOOL totemp = TRUE);\r
+\r
+\r
+int debuglog (int argc, char* argv[])\r
+{\r
+       Log("!  SCRIPT DEBUG: ");\r
+       LogAdd(argv[1]);\r
+\r
+       return ERR_OK;\r
+}\r
+\r
+int download (int argc, char* argv[])\r
+{\r
+       char* result;\r
+\r
+       if (argc==3)\r
+               result = PML_Download(argv[1], argv[2], argv[3]);\r
+\r
+       else if (argc==2)\r
+               result = PML_Download(argv[1], argv[2], NULL);\r
+\r
+       else \r
+               return ERR_GENERIC;\r
+\r
+       if(!result)\r
+               return ERR_GENERIC;\r
+\r
+       return ERR_OK;\r
+\r
+}\r
+\r
+int extract (int argc, char* argv[])\r
+{\r
+       return ERR_OK;\r
+}\r
+\r
+int msgbox (int argc, char* argv[])\r
+{\r
+       if (argc==1)\r
+               MessageBoxA(0,argv[1],0,0);\r
+\r
+       else if (argc==2)\r
+               MessageBoxA(0,argv[1],argv[2],0);\r
+\r
+       else \r
+               return ERR_GENERIC;\r
+\r
+       return ERR_OK;\r
+}\r
+\r
+int shell (int argc, char* argv[])\r
+{\r
+       // Get the temp dir\r
+       char tmp [MAX_PATH];\r
+       GetTempPathA (MAX_PATH, tmp);\r
+\r
+       SHELLEXECUTEINFOA info = {0};\r
+       info.cbSize = sizeof(SHELLEXECUTEINFO);\r
+       info.fMask = SEE_MASK_NOCLOSEPROCESS;\r
+       info.lpVerb = "open";\r
+       info.lpFile = argv[1];          \r
+       info.lpDirectory = tmp;\r
+       info.nShow = SW_SHOW;\r
+\r
+       if(argc >= 2)\r
+               info.lpParameters = "";\r
+\r
+       if(!ShellExecuteExA (&info))\r
+               return ERR_GENERIC;\r
+\r
+       WaitForSingleObject (info.hProcess, INFINITE);\r
+\r
+       return ERR_OK;\r
+}\r
+\r
+const FUNC_TABLE FuncTable[] =\r
+{\r
+   /* Name */   /* Function */ \r
+  {"download", download},\r
+  {"extract",  extract},\r
+  {"shell",            shell},\r
+  {"msgbox",   msgbox},\r
+  {"debug",            debuglog}\r
+};\r
diff --git a/rosapps/packmgr/lib/log.cpp b/rosapps/packmgr/lib/log.cpp
new file mode 100644 (file)
index 0000000..94b583f
--- /dev/null
@@ -0,0 +1,98 @@
+////////////////////////////////////////////////////////\r
+//\r
+// log.cpp\r
+// \r
+// Script Functions\r
+//\r
+//\r
+// Klemens Friedl, 19.03.2005\r
+// frik85@hotmail.com\r
+//\r
+////////////////////////////////////////////////////////////////////\r
+\r
+#include <stdlib.h>\r
+#include <stdio.h>\r
+#include <time.h>\r
+#include <windows.h>\r
+\r
+#include "log.h"\r
+#include "package.hpp"   // for Package Manager version\r
+#include <reactos/version.h>   // ReactOS version: \reactos\include\reactos\version.h\r
+\r
+bool LogCreated = false;\r
+\r
+void Log (const char *message)\r
+{\r
+       FILE *file;\r
+       char GTime[80];\r
+       char version[50];\r
+       char versionos[50];\r
+\r
+       if (!LogCreated) {              \r
+               file = fopen(LOGFILE, "w");\r
+               LogCreated = true;\r
+\r
+               // date and time\r
+               time_t now;\r
+               now = time(NULL);\r
+               strftime(GTime,sizeof GTime,"%Y-%m-%d",localtime(&now));\r
+\r
+               // package manager version information\r
+               wsprintfA(version, " Package Manager %d.%d.%d",\r
+                       PACKMGR_VERSION_MAJOR,\r
+                       PACKMGR_VERSION_MINOR,\r
+                       PACKMGR_VERSION_PATCH_LEVEL);\r
+\r
+               // operating system version information\r
+               wsprintfA(versionos, " ReactOS %d.%d.%d",\r
+                       KERNEL_VERSION_MAJOR,\r
+                       KERNEL_VERSION_MINOR,\r
+                       KERNEL_VERSION_PATCH_LEVEL);\r
+\r
+               fputs("# ReactOS Package Manager - Log File\n#\n# WARNING: This is still pre-alpha software.\n# Date: ", file);\r
+               fputs(GTime, file);\r
+               fputs("\n#\n#", file);\r
+               fputs(version, file);\r
+               fputs("\n#", file);\r
+               fputs(versionos, file);\r
+               fputs("\n#\n", file);\r
+       }\r
+       else            \r
+               file = fopen(LOGFILE, "a");\r
+               \r
+       if (file == NULL) {\r
+\r
+               if (LogCreated)\r
+                       LogCreated = false;\r
+\r
+               return;\r
+       }\r
+       else\r
+       {\r
+               // Save log entry (+ add time)\r
+               fputs("\n", file);\r
+               time_t now;\r
+               now = time(NULL);\r
+               strftime(GTime,sizeof GTime,"%I:%M:%S %p  ",localtime(&now));\r
+               fputs(GTime, file);\r
+               fputs(message, file);\r
+               fclose(file);\r
+       }\r
+\r
+       if (file)\r
+               fclose(file);\r
+}\r
+\r
+void LogAdd (const char *message)\r
+{\r
+       FILE *file;\r
+\r
+       file = fopen(LOGFILE, "a");\r
+               \r
+       // Save log entry\r
+       fputs(message, file);\r
+       fclose(file);\r
+\r
+       if (file)\r
+               fclose(file);\r
+}\r
diff --git a/rosapps/packmgr/lib/log.h b/rosapps/packmgr/lib/log.h
new file mode 100644 (file)
index 0000000..d04e29e
--- /dev/null
@@ -0,0 +1,21 @@
+////////////////////////////////////////////////////////\r
+//\r
+// log.h\r
+// \r
+// Script Functions\r
+//\r
+//\r
+// Klemens Friedl, 19.03.2005\r
+// frik85@hotmail.com\r
+//\r
+////////////////////////////////////////////////////////////////////\r
+\r
+#include <stdio.h>\r
+#include <string.h>\r
+\r
+#define LOGFILE        "packmgr.log"\r
+\r
+extern bool LogCreated;\r
+\r
+void Log (const char *message);\r
+void LogAdd (const char *message);\r
diff --git a/rosapps/packmgr/lib/main.cpp b/rosapps/packmgr/lib/main.cpp
new file mode 100644 (file)
index 0000000..f5812fe
--- /dev/null
@@ -0,0 +1,185 @@
+////////////////////////////////////////////////////////\r
+//\r
+// main.cpp\r
+// \r
+// Doit stuff and\r
+// everything that fits nowhere else.\r
+//\r
+//\r
+// Maarten Bosma, 09.01.2004\r
+// maarten.paul@bosma.de\r
+//\r
+////////////////////////////////////////////////////////////////////\r
+\r
+#include <windows.h>\r
+#include "package.hpp"\r
+#include "log.h"\r
+#include "script.h"\r
+\r
+HANDLE hThread = NULL;\r
+BOOL thread_abort = FALSE;\r
+\r
+extern const char* tree_server;\r
+char* PML_Download (const char* name, const char* local_name = "packmgr.txt", const char* server = tree_server, BOOL totemp = TRUE);\r
+\r
+\r
+// Abort other thread\r
+extern "C" void PML_Abort (void)\r
+{\r
+       thread_abort = TRUE;\r
+\r
+       if(hThread)\r
+               WaitForSingleObject(hThread, INFINITE);\r
+}\r
+\r
+// Callback function of the "doit"-thread\r
+DWORD WINAPI DoitThread (void* lpParam) \r
+{ \r
+       UINT i;\r
+       int ret = ERR_OK;\r
+       TREE* tree = (TREE*)lpParam;\r
+       vector<SCRIPT*> scripts;\r
+                       \r
+       /* Load the scripts */\r
+\r
+       tree->setStatus(0, 0, L"Downloading Install instructions ...");\r
+       \r
+       for(i=0; i<tree->todo.size(); i++)\r
+       {\r
+               SCRIPT* script;\r
+\r
+               char* path = PML_Download(tree->todo[i]);\r
+\r
+               if(RPS_Load(&script, path) == ERR_OK)\r
+                       scripts.push_back(script);\r
+               else\r
+                       ret = ERR_PACK;\r
+       }\r
+\r
+       /* Preinstall */\r
+\r
+       Log("*  enter preinstall");\r
+\r
+       tree->setStatus(250, 0, L"Preinstall");\r
+       \r
+       for(i=0; i<scripts.size(); i++)\r
+       {\r
+               if(RPS_Execute(scripts[i], "preinstall") != ERR_OK)\r
+                       ret = ERR_PACK;\r
+       }\r
+\r
+       /* Install */\r
+\r
+       Log("*  enter install");\r
+\r
+       tree->setStatus(500, 0, L"Install");\r
+\r
+       for(i=0; i<scripts.size(); i++)\r
+       {\r
+               if(RPS_Execute(scripts[i], "main") != ERR_OK)\r
+                       ret = ERR_PACK;\r
+       }\r
+\r
+       /* Postinstall */\r
+\r
+       Log("*  enter postinstall");\r
+\r
+       tree->setStatus(750, 0, L"Postinstall");\r
+\r
+       for(i=0; i<scripts.size(); i++)\r
+       {\r
+               if(RPS_Execute(scripts[i], "after") != ERR_OK)\r
+                       ret = ERR_PACK;\r
+       }\r
+\r
+       /* Finish */\r
+\r
+       for(i=0; i<tree->todo.size(); i++)\r
+               RPS_Clear(scripts[i]);\r
+\r
+       // clear the todo list\r
+       tree->todo.clear();\r
+\r
+       // set all actions to none\r
+       for(i=0; i<tree->packages.size(); i++)\r
+               PML_SetAction (tree, i, 0, tree->setIcon);\r
+\r
+       tree->setStatus(1000, ret, NULL);\r
+\r
+    return 1; \r
+} \r
+\r
+// Do the actions the user wants us to do\r
+extern "C" int PML_DoIt (TREE* tree, PML_SetStatus SetStatus)\r
+{ \r
+    DWORD dummy; \r
+       tree->setStatus = SetStatus;\r
+\r
+       if(!tree->todo.size())\r
+               return ERR_NOTODO;\r
+\r
+       hThread = CreateThread(NULL, 0, DoitThread, tree, 0, &dummy);\r
+\r
+       if(!hThread)\r
+               return ERR_GENERIC;\r
+       \r
+       LogAdd("\n");\r
+       \r
+       return ERR_OK;\r
+}\r
+\r
+// Translates Errorcode into human language\r
+extern "C" WCHAR* PML_TransError (int code)\r
+{\r
+       // I know we, got a memory leak here\r
+       static WCHAR string [256];\r
+\r
+    if(!LoadString(GetModuleHandle(L"package"), code, string, 256))\r
+               return PML_TransError(ERR_GENERIC);\r
+\r
+       return string;\r
+}\r
+\r
+// Free alloced memory\r
+extern "C" void PML_CloseTree (TREE* tree)\r
+{\r
+       UINT i;\r
+\r
+       LogAdd ("\n");\r
+       Log("*  free alloced memory");\r
+       Log("*  package manager will exit now. Bye!");\r
+\r
+       for(i=0; i<tree->packages.size(); i++)\r
+       {\r
+               if(tree->packages[i].path)\r
+                       delete tree->packages[i].path;\r
+\r
+               if(tree->packages[i].name)\r
+                       delete tree->packages[i].name;\r
+\r
+               if(tree->packages[i].description)\r
+                       delete tree->packages[i].description;\r
+\r
+               tree->packages.clear();\r
+\r
+               if(tree->packages[i].files[0])\r
+                       delete tree->packages[i].files[0];\r
+\r
+               if(tree->packages[i].files[1])\r
+                       delete tree->packages[i].files[1];\r
+\r
+               if(tree->packages[i].files[2])\r
+                       delete tree->packages[i].files[2];\r
+\r
+               if(tree->packages[i].files[3])\r
+                       delete tree->packages[i].files[3];\r
+       }\r
+\r
+       tree->descriptionPath.clear();\r
+       tree->todo.clear();\r
+       tree->packages.clear();\r
+\r
+       if(tree)\r
+               delete tree;\r
+}\r
+\r
diff --git a/rosapps/packmgr/lib/makefile b/rosapps/packmgr/lib/makefile
new file mode 100644 (file)
index 0000000..943b78f
--- /dev/null
@@ -0,0 +1,27 @@
+\r
+TARGET_TYPE = dynlink\r
+TARGET_NAME = package\r
+PATH_TO_TOP = ../../../reactos\r
+\r
+TARGET_SDKLIBS = kernel32.a shell32.a user32.a package.a expat.a urlmon.a\r
+\r
+TARGET_OBJECTS = main.o tree.o package.o download.o script.o functions.o log.o\r
+\r
+TARGET_GCCLIBS = stdc++ uuid\r
+\r
+\r
+TARGET_CFLAGS = \\r
+ -DUNICODE \\r
+ -Wall \\r
+ -Wno-error \\r
+ -D__USE_W32API \\r
+ -DWINVER=0x0600 \\r
+ -D_WIN32_WINNT=0x0501\r
+\r
+TARGET_CPPFLAGS = $(TARGET_CFLAGS)\r
+\r
+include $(PATH_TO_TOP)/rules.mak\r
+include $(TOOLS_PATH)/helper.mk\r
+include $(TOOLS_PATH)/depend.mk\r
+\r
+# EOF\r
diff --git a/rosapps/packmgr/lib/package.cpp b/rosapps/packmgr/lib/package.cpp
new file mode 100644 (file)
index 0000000..469cb4d
--- /dev/null
@@ -0,0 +1,191 @@
+////////////////////////////////////////////////////////\r
+//\r
+// package.cpp\r
+// \r
+// package related functions\r
+//\r
+//\r
+// Maarten Bosma, 09.01.2004\r
+// maarten.paul@bosma.de\r
+//\r
+////////////////////////////////////////////////////////////////////\r
+\r
+#include "package.hpp"\r
+#include "expat.h"\r
+#include "log.h"\r
+\r
+int PML_XmlDownload (const char* url, void* usrdata, XML_StartElementHandler start, \r
+                                        XML_EndElementHandler end, XML_CharacterDataHandler text=0);\r
+\r
+\r
+// expat callback for start of a package tag\r
+void pack_start (void* usrdata, const char* tag, const char** arg)\r
+{\r
+       int i, id;\r
+       PACKAGE* pack = (PACKAGE*)usrdata;\r
+\r
+       // if the tag is a script tag ...\r
+       if(!strcmp(tag, "scripts"))\r
+       {\r
+               // ... read the arguments\r
+               for (i=0; arg[i]; i+=2) \r
+               {\r
+                       if(!strcmp(arg[i], "inst"))\r
+                               id = 0;\r
+\r
+                       else if(!strcmp(arg[i], "update"))\r
+                               id = 1;\r
+\r
+                       else if(!strcmp(arg[i], "uinst"))\r
+                               id = 2;\r
+\r
+                       else if(!strcmp(arg[i], "srcinst"))\r
+                               id = 3;\r
+\r
+                       else\r
+                               continue;\r
+\r
+                       pack->files[id] = new char [strlen(arg[i+1])+1];\r
+                       strcpy(pack->files[id], arg[i+1]);\r
+               }\r
+       }\r
+\r
+       // ... save the field\r
+       else\r
+       {\r
+               if(!strcmp(tag, "name"))\r
+                       pack->field = &pack->name;\r
+\r
+               else if(!strcmp(tag, "description"))\r
+                       pack->field = &pack->description;\r
+       }\r
+}\r
+\r
+// expat callback for end of a package tag\r
+void pack_end (void* usrdata, const char* tag)\r
+{\r
+       PACKAGE* pack = (PACKAGE*)usrdata;\r
+\r
+       pack->field = NULL;\r
+}\r
+\r
+// expat callback for text\r
+void pack_text (void* usrdata, const char* data, int len)\r
+{\r
+       PACKAGE* pack = (PACKAGE*)usrdata;\r
+\r
+       if(!pack->field)\r
+               return;\r
+\r
+       *pack->field = new char[len+1];\r
+       strncpy(*pack->field, data, len);\r
+       (*pack->field)[len] = '\0';\r
+}\r
+\r
+\r
+// The user clicks on a package\r
+extern "C" int PML_LoadPackage (TREE* tree, int id, PML_SetButton SetButton, PML_SetText SetText)\r
+{\r
+       PACKAGE* pack = &tree->packages[id];\r
+       tree->setButton = SetButton;\r
+\r
+       SetButton(1, pack->action);\r
+       SetButton(2, pack->inst); // && pack->action != 0\r
+       SetButton(3, pack->src_inst); \r
+       SetButton(4, pack->update);\r
+       SetButton(5, pack->uninstall); \r
+\r
+       // root notes (like network) return here\r
+       if(!pack->path)\r
+               return 1;\r
+\r
+       if(!pack->loaded)\r
+       {\r
+               PML_XmlDownload (pack->path, (void*)pack, pack_start, pack_end, pack_text);\r
+               pack->loaded = TRUE;\r
+       }\r
+\r
+       if(pack->description)\r
+               SetText(pack->description);\r
+\r
+       return ERR_OK;\r
+}\r
+\r
+// The user chooses a actions like Install\r
+extern "C" int PML_SetAction (TREE* tree, int id, int action, PML_SetIcon SetIcon)\r
+{\r
+       UINT i;\r
+       int ret = ERR_OK;\r
+\r
+       tree->setIcon = SetIcon;\r
+       PACKAGE* pack = &tree->packages[id];\r
+\r
+       // if we have children, same action for them\r
+       for (i=0; i<pack->children.size(); i++)\r
+               ret = ret || PML_SetAction(tree, pack->children[i], action, SetIcon);\r
+\r
+       // is the action possible ? \r
+       if(!pack->actions[action])\r
+               return ERR_GENERIC;\r
+\r
+       // is it already set \r
+       if(pack->action == action)\r
+               return ERR_OK;\r
+\r
+       // set the icon\r
+       if(!pack->icon)\r
+               SetIcon(id, action);\r
+\r
+       // can't do src install yet\r
+       if(action == 2)\r
+       {\r
+               MessageBox(0, L"Sorry, but source install is not implemented yet.", 0,0);\r
+               return ERR_OK;\r
+       }\r
+\r
+       // everything but undoing is done here\r
+       else if (action != 0)\r
+       {\r
+               // since we are setting a action we undo it again\r
+               tree->setButton(1, 1);\r
+               //tree->setButton(action+1, 0);\r
+               pack->action = action;\r
+\r
+               // root notes (like network) return here\r
+               if(!pack->path)\r
+                       return ret; \r
+\r
+               // load it if it's not loaded yet\r
+               if(!pack->loaded)\r
+               {\r
+                       PML_XmlDownload (pack->path, (void*)pack, pack_start, pack_end, pack_text);\r
+                       pack->loaded = TRUE;\r
+               }\r
+\r
+               // save the name of the corresponding script in a vector\r
+               tree->todo.push_back(pack->files[action-1]);\r
+       }\r
+\r
+       // undoing\r
+       else \r
+       {+\r
+               // set other things back\r
+               tree->setButton(1, 0);\r
+               //tree->setButton(pack->action+1, 1);\r
+               pack->action = 0;\r
+\r
+               // root notes (like network) return here\r
+               if(!pack->path || pack->action==0)\r
+                       return ret; \r
+       \r
+               // erase from todo list\r
+               for(i=0; i<tree->todo.size(); i++)\r
+                       if(!strcmp(tree->todo[i], pack->files[pack->action-1])) // look for right entry\r
+                               tree->todo.erase(tree->todo.begin()+i); // delete it\r
+\r
+               return ERR_OK;\r
+       }\r
+\r
+       return ret;\r
+}\r
+\r
diff --git a/rosapps/packmgr/lib/package.def b/rosapps/packmgr/lib/package.def
new file mode 100644 (file)
index 0000000..9154be9
--- /dev/null
@@ -0,0 +1,13 @@
+LIBRARY package.dll\r
+\r
+EXPORTS\r
+\r
+  PML_Abort\r
+  PML_TransError\r
+  PML_LoadTree\r
+  PML_LoadPackage\r
+  PML_SetAction\r
+  PML_DoIt\r
+  PML_CloseTree\r
+\r
+; EOF\r
diff --git a/rosapps/packmgr/lib/package.hpp b/rosapps/packmgr/lib/package.hpp
new file mode 100644 (file)
index 0000000..ce6ee46
--- /dev/null
@@ -0,0 +1,86 @@
+////////////////////////////////////////////////\r
+//\r
+// package.hpp\r
+//                                     Package C++ Header\r
+////////////////////////////////////////////////\r
+\r
+#include <windows.h>\r
+#include <vector>\r
+#include "error.h"\r
+\r
+using namespace std;\r
+\r
+\r
+/* Callbacks */\r
+\r
+typedef int (*PML_AddItem)             (int id, const char* name, int parent, int icon);\r
+typedef int (*PML_SetStatus)   (int status1, int status2, WCHAR* text);\r
+typedef int (*PML_SetButton)   (DWORD dwID, BOOL state);\r
+typedef int (*PML_SetIcon)             (int id, int icon);\r
+typedef int (*PML_SetText)             (const char* text);\r
+\r
+\r
+/* Structs */\r
+\r
+typedef struct\r
+{\r
+  char*                        path;\r
+  BOOL                 icon;\r
+  BOOL                 loaded;\r
+  vector<int>  children;\r
+\r
+  char**               field;\r
+  char*                        name;\r
+  char*                        description;\r
+  \r
+  int                  action;\r
+  char*                        files [4];\r
+\r
+  union //which actions are possible\r
+  {\r
+    struct { BOOL none, inst, src_inst, update, uninstall; };\r
+    BOOL actions [4];\r
+  };\r
+\r
+} PACKAGE;\r
+\r
+typedef struct\r
+{\r
+  char*                                xmltree;\r
+\r
+  vector<char*>                descriptionPath;\r
+  vector<char*>                todo;\r
+  vector<PACKAGE>      packages;\r
+\r
+  PML_AddItem          addItem;\r
+  PML_SetButton                setButton;\r
+  PML_SetStatus                setStatus;\r
+  PML_SetIcon          setIcon;\r
+  PML_SetText          setText;\r
+\r
+} TREE, *pTree;\r
+\r
+#define MAXNODES 10000\r
+\r
+\r
+/* Prototypes */\r
+\r
+extern "C" \r
+{\r
+  void PML_Abort (void);\r
+  WCHAR* PML_TransError (int code);\r
+\r
+  int PML_LoadTree (pTree*, char* url, PML_AddItem);\r
+  int PML_LoadPackage (pTree, int id, PML_SetButton, PML_SetText);\r
+  int PML_SetAction (pTree, int package, int action, PML_SetIcon);\r
+  int PML_DoIt (pTree, PML_SetStatus);\r
+\r
+  void PML_CloseTree (pTree);\r
+}\r
+\r
+\r
+/* Version */ \r
+\r
+#define PACKMGR_VERSION_MAJOR          0\r
+#define PACKMGR_VERSION_MINOR          3\r
+#define PACKMGR_VERSION_PATCH_LEVEL    1\r
diff --git a/rosapps/packmgr/lib/package.rc b/rosapps/packmgr/lib/package.rc
new file mode 100644 (file)
index 0000000..c5bc60f
--- /dev/null
@@ -0,0 +1,15 @@
+\r
+#include <windows.h>\r
+#include "error.h"\r
+\r
+#define REACTOS_STR_FILE_DESCRIPTION   "ReactOS Package Manager\0"\r
+#define REACTOS_STR_INTERNAL_NAME      "package\0"\r
+#define REACTOS_STR_ORIGINAL_FILENAME  "package.dll\0"\r
+\r
+#include <reactos/version.rc>\r
+\r
+/* Language specific */\r
+\r
+#include "en.rc"\r
+\r
+/* EOF */\r
diff --git a/rosapps/packmgr/lib/script.cpp b/rosapps/packmgr/lib/script.cpp
new file mode 100644 (file)
index 0000000..6c52ef8
--- /dev/null
@@ -0,0 +1,278 @@
+////////////////////////////////////////////////////////\r
+//\r
+// script.cpp\r
+// \r
+// Implementaion of a basic basic :) interpreter\r
+//\r
+//\r
+// Maarten Bosma, 09.01.2004\r
+// maarten.paul@bosma.de\r
+//\r
+////////////////////////////////////////////////////////////////////\r
+\r
+#include "package.hpp"\r
+#include "script.h"\r
+#include "log.h"\r
+#include <fstream>\r
+\r
+using namespace std;\r
+\r
+// just a few Helpers\r
+void Replace (string* Where, string Old, string New, int start = 0, int end = -1, int instring = 1);\r
+int FindCount (string What, string Where, int start = 0, int end = -1);\r
+int Find (string Where, string What, int start = 0, int end = -1, int instring = 1);\r
+\r
+\r
+// Loads script from file, checks if it's synaxially correct\r
+// and converts it into a easy to interprete one.\r
+int RPS_Load (SCRIPT** script, const char* path)\r
+{\r
+       string source;\r
+\r
+       /* We have to do it that way (doublepointer) because MinGw \r
+          calls "delete" at the end of function otherwise. */\r
+       (*script) = new SCRIPT; \r
+\r
+       // Load file to string\r
+       ifstream file(path, ios_base::in);\r
+       if (!file.is_open())\r
+               return ERR_FILE;\r
+\r
+       getline(file, source, '\0');\r
+\r
+       // make sure last char is a new line\r
+       source += "\n"; \r
+       \r
+       // Are all subs and strings closed ?\r
+       // FIXME: Just a quick hack sould be both checked line by line\r
+       if(FindCount(source, "\"")%2) // if count is uneven not all strings are closed \r
+               return ERR_SYNATX;\r
+\r
+       if(FindCount(source, "Sub ") != FindCount(source, "End Sub\n"))\r
+               return ERR_SYNATX;\r
+\r
+       // Delete comments\r
+       while (true)\r
+       {\r
+               int start = Find(source, "'");\r
+               if(start == NOTFOUND)\r
+                       break;\r
+               int end = Find(source, "\n", start);\r
+               source.erase(start, end-start); // needs size not line\r
+       }\r
+\r
+       // Converte the file into some thing easier to interprete\r
+       Replace(&source, "(", " ");\r
+       Replace(&source, ")", " ");\r
+       Replace(&source, ";", " ");\r
+       Replace(&source, ",", " ");\r
+       Replace(&source, "\"", " \" ");\r
+       Replace(&source, "\t", " ");\r
+\r
+       Replace(&source, "  ", " ");\r
+       Replace(&source, "\n ", "\n");\r
+       Replace(&source, " \n", "\n");\r
+       Replace(&source, "\n\n", "\n");\r
+\r
+       if(source[0]=='\n')\r
+               source.erase(0,1);\r
+\r
+       // copy string into struct (line by line)\r
+       UINT i, line=0;\r
+       for (i=0; i < source.size(); i++)\r
+       {\r
+               // Make everything non capital letters\r
+               if (source[i] >= 65 && source[i] <= 90) // ASCII-Code (A-Z 65-90)\r
+               {\r
+                       source[i] += 32; // ASCII-Code (a-z 97-122)\r
+               }\r
+\r
+               else if (source[i] == '\"')\r
+               {\r
+                       while(source[++i]!='\"');\r
+               }\r
+\r
+               else if (source[i] == '\n')\r
+               {\r
+                       (*script)->code.push_back(source.substr(line, i-line));\r
+                       line = i+1;\r
+               }\r
+       }\r
+\r
+       // create a sub table (with name, beginnig and end of function)\r
+       for (i=0; i < (*script)->code.size(); i++) // code.size() is the cout of lines\r
+       {\r
+               SUB sub;\r
+               \r
+               if((*script)->code[i].substr(0,4) != "sub ")\r
+                       return ERR_SYNATX; // script has to start with sub\r
+\r
+               sub.name = (*script)->code[i].substr(4,((*script)->code[i].size()-4));\r
+               sub.start = i+1;\r
+\r
+               while ((*script)->code[i] != "end sub")\r
+               {\r
+                       i++;\r
+                       //if script does not end with "end sub" we got a problem\r
+                       if (i>(*script)->code.size())\r
+                               return ERR_SYNATX; \r
+               }\r
+\r
+               sub.end = i;\r
+               (*script)->subs.push_back(sub);\r
+       }\r
+\r
+       return ERR_OK;\r
+}\r
+\r
+\r
+// Executes a subroutine of the script\r
+int RPS_Execute (SCRIPT* script, const char* function)\r
+{\r
+       char *argv[100];\r
+       char *buffer;\r
+       int a, b, c, nr = NOTFOUND, argc = 0;\r
+\r
+       // find the right fuction\r
+       for(a=0; (UINT)a<script->subs.size(); a++)\r
+               if(script->subs[a].name == function)\r
+                       nr = a;\r
+\r
+       // if there isn't a fuction with this name we can't do anything\r
+       if(nr == NOTFOUND)\r
+               return ERR_OK;\r
+\r
+       // call the function\r
+       for (a=script->subs[nr].start; a<script->subs[nr].end; a++)\r
+       {\r
+               // create a temporarry buffer \r
+               buffer = new char[script->code[a].size()];\r
+               strcpy(buffer, script->code[a].c_str());\r
+\r
+               // make the fist argument the function's name\r
+               argv[0] = &buffer[0];\r
+       \r
+               int buffer_size = (int)strlen(buffer);\r
+               for (b=0; b<buffer_size+1; b++)\r
+               {\r
+                       // ignore chars in strings\r
+                       if(buffer[b]=='\"')\r
+                       {\r
+                               argv[argc] = &buffer[b+1];\r
+\r
+                               while(buffer[++b]!='\"');\r
+\r
+                               buffer[b] = '\0';\r
+                       }\r
+\r
+                       // create a new argument\r
+                       else if(buffer[b]==' ')\r
+                       {\r
+                               argc++;\r
+                               argv[argc] = &buffer[b+1];\r
+                               buffer[b] = '\0';\r
+\r
+                               // we don't want buffer overflows\r
+                               if(argc == 99) \r
+                                       return ERR_GENERIC;\r
+\r
+                       }\r
+\r
+                       // call the function\r
+                       else if(buffer[b]=='\0')\r
+                       {\r
+                               int error = 0;\r
+\r
+                               // log the name\r
+                               Log("*   excute command: ");\r
+                               for(c=0; c<argc+1; c++)\r
+                               {\r
+                                       LogAdd(argv[c]); \r
+                                       LogAdd(" ");\r
+                               }\r
+\r
+                               for(c=0; c<FUNC_COUNT; c++)\r
+                                       if(!strcmp(argv[0], FuncTable[c].name))\r
+                                               error = FuncTable[c].function(argc, &argv[0]);\r
+\r
+                               if(error)\r
+                                       return error;\r
+                       }\r
+\r
+               }\r
+\r
+               // start again with next line\r
+               delete[] buffer;\r
+               argc = 0;\r
+       }\r
+\r
+       return ERR_OK;\r
+}\r
+\r
+// get a Constant or a variavle\r
+int RPS_getVar (const char* name)\r
+{\r
+       return ERR_OK;\r
+}\r
+\r
+// Clears up Memory\r
+void RPS_Clear (SCRIPT* script)\r
+{\r
+       if(script)\r
+               delete script;\r
+}\r
+\r
+/* Helper Functions */\r
+\r
+// How often do we find a string inside another one\r
+int FindCount (string where, string what, int start, int end)\r
+{\r
+       int counter = 0, pos;\r
+       \r
+       while(true)\r
+       {\r
+               pos = (int)where.find (what, start);\r
+               //could could not be found or is outside of search area \r
+               if (pos == (int)string::npos || (end!=-1 && pos>end)) \r
+                       break;\r
+               start = pos+1;\r
+               counter++;\r
+       }\r
+\r
+       return counter;\r
+}\r
+\r
+// Find (with only or not in Strings option)\r
+int Find (string where, string what, int start, int end, int instring)\r
+{\r
+       int pos = (int)where.find (what, start);\r
+\r
+       //could could not be found or is outside of search area \r
+       if (pos == (int)string::npos || (end!=-1 && pos>end)) \r
+               return -1;\r
+\r
+       // if the count of this quotes is eaven we are in string \r
+       int isInString = FindCount(where, "\"", start, pos)%2;\r
+\r
+       // if so we go on searching \r
+    if(isInString == instring)\r
+               return Find (where, what, pos+1, end, instring);\r
+\r
+       return pos;\r
+\r
+}\r
+\r
+// Replace (using Find)\r
+void Replace (string* String, string Old, string New, int start, int end, int instring)\r
+{\r
+       int pos = start;\r
+\r
+       while(true)\r
+       {\r
+               pos = Find(String->c_str(), Old, pos, end, instring);\r
+               if (pos == -1)\r
+                       break;\r
+\r
+               String->replace (pos, Old.length(), New);\r
+       }\r
+}\r
diff --git a/rosapps/packmgr/lib/script.h b/rosapps/packmgr/lib/script.h
new file mode 100644 (file)
index 0000000..7677874
--- /dev/null
@@ -0,0 +1,65 @@
+////////////////////////////////////////////////\r
+//\r
+// package.hpp\r
+//                                Header for the script stuff\r
+////////////////////////////////////////////////\r
+\r
+#include <vector>\r
+#include <string>\r
+\r
+using namespace std;\r
+\r
+\r
+/* Structs */\r
+\r
+typedef struct\r
+{\r
+  string name;\r
+  int start, end;\r
+\r
+} SUB;\r
+\r
+typedef struct\r
+{\r
+  vector<string> code;\r
+  vector<SUB> subs;\r
+\r
+} SCRIPT;\r
+\r
+\r
+/* Prototypes */\r
+\r
+int RPS_Load (SCRIPT** script, const char* path);\r
+int RPS_Execute (SCRIPT* script, const char* function);\r
+int RPS_getVar (const char* name);\r
+void RPS_Clear (SCRIPT* script);\r
+\r
+\r
+/* Callbacks */\r
+\r
+typedef int (*FUNC_PROC)(int, char**); // function callback\r
+\r
+\r
+/* Function table */\r
+\r
+typedef struct\r
+{\r
+  char* name;\r
+  FUNC_PROC function;\r
+} FUNC_TABLE;\r
+\r
+// very function is listed in there \r
+extern const FUNC_TABLE FuncTable[];\r
+\r
+// count of functions\r
+#define FUNC_COUNT 3\r
+\r
+\r
+/* For the helper-funtions */\r
+\r
+#define STR_NO    0x1;\r
+#define STR_ONLY  0x0;\r
+#define STR_YES   0x2;\r
+\r
+// ^^ I would write down here that they \r
+// mean but I don't know anymore myself :O\r
diff --git a/rosapps/packmgr/lib/tree.cpp b/rosapps/packmgr/lib/tree.cpp
new file mode 100644 (file)
index 0000000..030e633
--- /dev/null
@@ -0,0 +1,112 @@
+////////////////////////////////////////////////////////\r
+//\r
+// tree.cpp\r
+// \r
+// Loading of the package tree\r
+//\r
+//\r
+// Maarten Bosma, 09.01.2004\r
+// maarten.paul@bosma.de\r
+//\r
+////////////////////////////////////////////////////////////////////\r
+\r
+#include "package.hpp"\r
+#include "expat.h"\r
+\r
+vector <int> parents;\r
+\r
+void tree_end (void* tree, const char* tag);\r
+void tree_start (void* usrdata, const char* tag, const char** arg);\r
+\r
+int PML_XmlDownload (const char* file, void* usrdata, XML_StartElementHandler start, \r
+                                        XML_EndElementHandler end, XML_CharacterDataHandler text=0);\r
+\r
+\r
+// Load the tree\r
+extern "C" int PML_LoadTree (TREE** tree, char* url, PML_AddItem AddItem)\r
+{\r
+       // get the memory\r
+       (*tree) = new TREE;\r
+\r
+       // set every to zero\r
+       memset((*tree), 0, sizeof((*tree)));\r
+       \r
+       // set addItem callback\r
+       (*tree)->addItem = AddItem;\r
+\r
+       return PML_XmlDownload (url, (void*)(*tree), tree_start, tree_end);\r
+}\r
+\r
+// expat callback for start of a "node" tag\r
+void tree_start (void* usrdata, const char* tag, const char** arg)\r
+{\r
+       int i, icon;\r
+       static int id = 1;\r
+       const char* name = "\0";\r
+\r
+       TREE* tree = (TREE*)usrdata;\r
+\r
+       // ignore if tag is the root tag ("tree")\r
+       if(!strcmp(tag, "tree"))\r
+               return;\r
+\r
+       // set the package memory\r
+       tree->packages.resize(id+1);\r
+       memset(&tree->packages[id], 0, sizeof(tree->packages[id]));\r
+\r
+       tree->packages[id].loaded = FALSE;\r
+       tree->packages[id].icon = FALSE;\r
+       tree->packages[id].none = TRUE;\r
+       tree->packages[id].path = NULL;\r
+\r
+       // read the arguments\r
+       for (i=0; arg[i]; i+=2) \r
+       {\r
+               if(!strcmp(arg[i], "name"))\r
+                       name = arg[i+1];\r
+\r
+               if(!strcmp(arg[i], "icon"))\r
+               {\r
+                       icon = atoi(arg[i+1]);\r
+                       tree->packages[id].icon = TRUE;\r
+               }\r
+\r
+               if(!strcmp(arg[i], "file"))\r
+               {\r
+                       tree->packages[id].path = new char [strlen(arg[i+1])];\r
+                       strcpy(tree->packages[id].path, arg[i+1]);\r
+\r
+                       if(strcmp(tag, "bin"))\r
+                               tree->packages[id].inst = TRUE;\r
+\r
+                       if(strcmp(tag, "src"))\r
+                               tree->packages[id].src_inst = TRUE;\r
+               }\r
+       }\r
+\r
+       if(name[0]=='\0') return;\r
+\r
+       // add it\r
+       if(!parents.size())\r
+          tree->addItem(id, name, 0, icon);\r
+       else\r
+       {\r
+          tree->addItem(id, name, parents.back(), icon);\r
+\r
+          // list as child in the parent node\r
+          tree->packages[parents.back()].children.push_back(id);\r
+\r
+          // this is for the buttons\r
+          tree->packages[parents.back()].inst = tree->packages[parents.back()].inst || tree->packages[id].inst;\r
+          tree->packages[parents.back()].src_inst = tree->packages[parents.back()].src_inst || tree->packages[id].src_inst;\r
+       }\r
+\r
+       parents.push_back(id++);\r
+}\r
+\r
+// expat callback for end of a "node" tag\r
+void tree_end (void* tree, const char* tag)\r
+{\r
+       // delete last item\r
+       parents.pop_back();\r
+}\r
diff --git a/rosapps/packmgr/makefile b/rosapps/packmgr/makefile
new file mode 100644 (file)
index 0000000..439f9f1
--- /dev/null
@@ -0,0 +1,14 @@
+\r
+all: lib gui\r
+\r
+lib: dummy\r
+       $(MAKE) -C lib\r
+       \r
+gui: dummy\r
+       $(MAKE) -C gui\r
+\r
+dummy:\r
+\r
+clean:\r
+       $(MAKE) -C gui clean\r
+       $(MAKE) -C lib clean\r
diff --git a/rosapps/packmgr/tree/abiword.inst.rps b/rosapps/packmgr/tree/abiword.inst.rps
new file mode 100644 (file)
index 0000000..40cd3b9
--- /dev/null
@@ -0,0 +1,9 @@
+'Install rutine for abiword\r
+\r
+Sub Main     \r
+  download ("http://www.abisource.com/downloads/abiword/2.2.5/Windows/abiword-setup-2.2.5.exe", "abisetup.exe")\r
+End Sub\r
+\r
+Sub After\r
+  shell abisetup.exe\r
+End Sub
\ No newline at end of file
diff --git a/rosapps/packmgr/tree/abiword.xml b/rosapps/packmgr/tree/abiword.xml
new file mode 100644 (file)
index 0000000..07f07ee
--- /dev/null
@@ -0,0 +1,7 @@
+<package>\r
+<name>AbiWord</name>\r
+<description>Currently it's definitely the best word processor running under ReactOS.</description>\r
+<scripts inst="abiword.inst.rps" srcinst="abiword.inst.rps"/>\r
\r
+</package>\r
+\r
diff --git a/rosapps/packmgr/tree/mozcontrol.xml b/rosapps/packmgr/tree/mozcontrol.xml
new file mode 100644 (file)
index 0000000..01e9536
--- /dev/null
@@ -0,0 +1,7 @@
+<package>\r
+<name>MozillaControl</name>\r
+<description>Provide the Gekko Engine for ReactOS.</description>\r
+<scripts inst="mozillacontrol.inst.rps" srcinst="mozillacontrol.inst.rps"/>\r
\r
+</package>\r
+\r
diff --git a/rosapps/packmgr/tree/mozillacontrol.inst.rps b/rosapps/packmgr/tree/mozillacontrol.inst.rps
new file mode 100644 (file)
index 0000000..096e2a4
--- /dev/null
@@ -0,0 +1,9 @@
+'Install rutine for Mozilla Control 1.6\r
+\r
+Sub Main\r
+  download ("http://www.iol.ie/~locka/mozilla/MozillaControl16.exe", "mozillacontrol16.exe")\r
+End Sub\r
+\r
+Sub After\r
+  shell mozillacontrol16.exe\r
+End Sub
\ No newline at end of file
diff --git a/rosapps/packmgr/tree/tree.xml b/rosapps/packmgr/tree/tree.xml
new file mode 100644 (file)
index 0000000..0ebd185
--- /dev/null
@@ -0,0 +1,69 @@
+<tree>\r
+  <node name="Internet and Network" icon="5">\r
+    <node name="Browser" icon="5">\r
+      <node name="MozillaControl" file="mozcontrol.xml"/>\r
+    </node>\r
+    <node name="Email" icon="5"/>\r
+    <node name="Instant Messaging and IRC" icon="5">\r
+      <node name="VoIP" icon="5"/>\r
+    </node>\r
+    <node name="Filesharing" icon="5"/>\r
+    <node name="Remotecontrol" icon="5"/>\r
+    <node name="Server" icon="5">\r
+      <node name="File-Server" icon="5"/>\r
+      <node name="HTTP" icon="5"/>\r
+      <node name="IRC" icon="5"/>\r
+      <node name="FTP" icon="5"/>\r
+    </node>\r
+    <node name="Network monitoring" icon="5"/>\r
+    <node name="Security" icon="5"/>\r
+    <node name="Streaming" icon="5"/>\r
+    <node name="Other" icon="5"/>\r
+  </node>\r
+  <node name="Office" icon="6">\r
+    <node name="Writing" icon="6">\r
+      <node name="PDF" icon="6"/>\r
+      <node name="AbiWord" file="abiword.xml"/>\r
+    </node>\r
+    <node name="Dictionaries" icon="6"/>\r
+  </node>\r
+  <node name="Graphics" icon="7">\r
+    <node name="Vector" icon="7"/>\r
+    <node name="Pixel" icon="7"/>\r
+    <node name="3D" icon="7"/>\r
+  </node>\r
+  <node name="Multimedia" icon="8">\r
+    <node name="Codecs" icon="8"/>\r
+    <node name="Editors" icon="8"/>\r
+    <node name="Players" icon="8"/>\r
+  </node>\r
+  <node name="Development" icon="9">\r
+    <node name="IDE" icon="9"/>\r
+    <node name="Compiler" icon="9"/>\r
+    <node name="Version Control" icon="9"/>\r
+    <node name="Web" icon="9"/>\r
+    <node name="Other" icon="9"/>\r
+  </node>\r
+  <node name="Games and Fun" icon="10"/>\r
+  <node name="Tools" icon="11">\r
+    <node name="Compression" icon="11"/>\r
+    <node name="Backup" icon="11"/>\r
+    <node name="Burning" icon="11">\r
+      <node name="CD" icon="11"/>\r
+      <node name="DVD" icon="11"/>\r
+    </node>\r
+  </node>\r
+  <node name="Others" icon="12">\r
+    <node name="Desktop Environments and Shellreplacements" icon="12"/>\r
+    <node name="Desktop" icon="12"/>\r
+    <node name="Antivirus" icon="12"/>\r
+    <node name="Emulators" icon="12">\r
+      <node name="Computers" icon="12"/>\r
+      <node name="Systems" icon="12"/>\r
+      <node name="Games" icon="12"/>\r
+    </node>\r
+    <node name="Drivers" icon="12"/>\r
+  </node>\r
+  <node name="Installed Programms" icon="13"/> \r
+</tree>\r
+\r