fix issues with string truncation and undersized buffers. (NicJA)
[AROS.git] / workbench / network / stacks / AROSTCP / bsdsocket / kern / amiga_gui.c
blob69ef5bf2d45a9f4ba1acd9a37bfb2f206f921ef3
1 #include "conf.h"
3 #include <proto/intuition.h>
5 #include <devices/timer.h>
6 #include <dos/dos.h>
7 #include <dos/dosextens.h>
8 #include <dos/dostags.h>
9 #if !defined(__AROS__)
10 #include <emul/emulinterface.h>
11 #endif
12 #include <exec/libraries.h>
13 #include <intuition/intuition.h>
14 #include <libraries/miamipanel.h>
15 #include <proto/dos.h>
16 #include <proto/exec.h>
17 #include <proto/miamipanel.h>
18 #include <kern/amiga_dhcp.h>
19 #include <kern/amiga_gui.h>
20 #include <kern/amiga_log.h>
21 #include <sys/synch.h>
22 #include <stdio.h>
23 #include <syslog.h>
25 /* Panel preferences */
26 struct gui_cnf gui_cnf = {NULL};
27 LONG gui_show[6] = {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE};
28 ULONG gui_refresh = 1;
29 long panelx = 50;
30 long panely = 50;
32 UBYTE GUI_Running = 0;
33 ULONG guimask = 0;
34 struct Library *MiamiPanelBase = NULL;
35 struct MsgPort *gui_msgport = NULL;
36 struct timerequest *gui_timerio = NULL;
37 ULONG InternalProc = 0;
39 extern struct ifnet *ifnet;
40 extern struct Task *AmiTCP_Task;
41 extern TEXT panels_path[];
43 STRPTR strings[] =
45 ">On",
46 ">Of",
47 ">Su",
48 "Onl",
49 "Off",
50 "Sus",
51 "Show",
52 "Hide",
53 "Quit",
54 "Onl",
55 "Off"
58 void SAVEDS gui_async_op(ULONG code, ULONG unit)
60 struct ifnet *ifp;
62 DGUI(log(LOG_DEBUG,"gui_async_op(%lu, %lu) called", code, unit);)
63 for (ifp = ifnet; ifp; ifp = ifp->if_next) {
64 if (ifp->if_index == unit) {
65 DGUI(log(LOG_DEBUG,"Found ifp = 0x%08lx", ifp);)
66 ifupdown(ifp, (code == MIAMIPANELV_CallBack_Code_UnitOffline));
69 Forbid();
70 InternalProc--;
73 #ifdef __MORPHOS__
74 #define getarg(x, y) (y)*x++
75 long callback_function(void)
77 long *m68k_stack = (ULONG *)REG_A7;
78 long code = m68k_stack[1];
79 long count = m68k_stack[2];
80 ULONG *args = (ULONG *)m68k_stack[3];
81 #else
82 #define getarg va_arg
83 long callback(long code, long count, va_list args)
85 #endif
86 ULONG nstr;
87 struct SysLogPacket *msg;
89 switch (code) {
90 case MIAMIPANELV_CallBack_Code_Localize:
91 nstr = getarg(args, ULONG) - 5000;
92 DGUI(KPrintF("Callback: localize(%lu), result: %s", nstr, strings[nstr]);)
93 /* TODO: full localization */
94 return (long)strings[nstr];
95 case MIAMIPANELV_CallBack_Code_UnitOnline:
96 case MIAMIPANELV_CallBack_Code_UnitOffline:
97 nstr = getarg(args, ULONG);
98 InternalProc++;
99 if (!(CreateNewProcTags(NP_Entry, (IPTR)&gui_async_op,
100 NP_Name, (IPTR)"AROSTCP interface control",
101 #ifdef __MORPHOS__
102 NP_CodeType, CODETYPE_PPC,
103 NP_PPC_Arg1, code,
104 NP_PPC_Arg2, nstr,
105 #else
106 /* TODO: Implement passing arguments to gui_async_op() */
107 #endif
108 TAG_DONE)))
109 InternalProc--;
110 break;
111 case MIAMIPANELV_CallBack_Code_ShowMainGUI:
112 /* TODO: Run configuration editor */
113 break;
114 case MIAMIPANELV_CallBack_Code_HideMainGUI:
115 /* In fact we don't have main GUI so we have nothing to hide here.
116 However many panels (MUI.MiamiPanel for example) have "Hide"
117 button and in order to make it usable we simply make it doing
118 the same as "Close panel" */
119 case MIAMIPANELV_CallBack_Code_ClosePanel:
120 if (msg = (struct SysLogPacket *)GetLogMsg(&logReplyPort)) {
121 msg->Level = LOG_GUIMSG | GUICMD_CLOSE;
122 PutMsg(logPort, (struct Message *)msg);
124 break;
125 case MIAMIPANELV_CallBack_Code_QuitMiami:
126 Signal(AmiTCP_Task, SIGBREAKF_CTRL_C);
127 break;
128 default:
129 DGUI(KPrintF("Bad callback code %ld from panel\n", code));
131 return 0;
134 #ifdef __MORPHOS__
135 struct EmulLibEntry callback =
137 TRAP_LIB, 0, (void (*)(void)) callback_function
139 #endif
141 TEXT panel_path[FILENAME_MAX];
143 static void getbaud(char *buf, unsigned long baud)
145 if (baud > 1000000000)
146 sprintf(buf,"%luG", baud / 1000000000);
147 else if (baud > 1000000)
148 sprintf(buf,"%luM", baud / 1000000);
149 else if (baud > 1000)
150 sprintf(buf,"%luK", baud / 1000);
151 else
152 sprintf(buf,"%lu", baud);
155 void gui_open()
157 struct ifnet *ifp;
158 DGUI(long PanelVersion;)
159 long showflags = 0;
160 char ifname[IFNAMSIZ+2];
161 long ifstate;
162 char ifspeed[16];
163 int i;
165 #if defined(__AROS__)
166 D(bug("[AROSTCP](amiga_gui.c) %s()\n", __func__));
167 #endif
169 if (GUI_Running) {
170 DGUI(KPrintF("GUI is already opened\n");)
171 return;
173 if (!gui_cnf.PanelName) {
174 DGUI(KPrintF("GUI is disabled\n");)
175 return;
177 gui_timerio = CreateIORequest(logPort, sizeof(struct timerequest));
178 if (gui_timerio) {
179 if (!OpenDevice("timer.device", UNIT_VBLANK, (struct IORequest *)gui_timerio, 0)) {
180 // NameFromLock(GetProgramDir(), panel_path, FILENAME_MAX);
181 AddPart(panel_path,"LIBS:", FILENAME_MAX);
182 AddPart(panel_path,gui_cnf.PanelName, FILENAME_MAX);
183 strcat(panel_path, ".MiamiPanel");
184 DGUI(KPrintF("Opening GUI: %s...\n", panel_path);)
185 #if defined(__AROS__)
186 D(bug("[AROSTCP](amiga_gui.c) %s: Attempting to use '%s'\n", __func__, panel_path));
187 #endif
188 MiamiPanelBase = OpenLibrary(panel_path, 0);
189 DGUI(KPrintF("Panel library opened, base = 0x%08lx\n", MiamiPanelBase);)
190 if (MiamiPanelBase) {
191 DGUI(PanelVersion = MiamiPanelGetVersion();)
192 DGUI(KPrintF("Panel API version: %lu\n", PanelVersion);)
193 MiamiPanelInhibitRefresh(TRUE);
194 DGUI(KPrintF("Panel inhibited\n");)
195 for (i=0; i<6; i++)
196 if (gui_show[i])
197 showflags |= 1<<i;
198 /* Screen is always default */
199 if (MiamiPanelInit((IPTR)&callback, (IPTR)&callback, showflags, gui_cnf.PanelFont, NULL, panelx, panely, (IPTR)&guimask)) {
200 DGUI(KPrintF("Panel initialized, signals = 0x%08lx\n", guimask);)
201 GUI_Running = 1;
202 for (ifp = ifnet; ifp; ifp = ifp->if_next) {
203 if (!(ifp->if_flags & IFF_LOOPBACK)) {
204 sprintf(ifname, "%s%d", ifp->if_name, ifp->if_unit);
205 DGUI(KPrintF("Adding interface %s, index %lu, baud rate %lu\n", ifname, ifp->if_index, ifp->if_baudrate);)
206 if (ifp->if_flags & IFF_UP) {
207 ifstate = MIAMIPANELV_AddInterface_State_Online;
208 getbaud(ifspeed, ifp->if_baudrate);
209 } else {
210 ifstate = MIAMIPANELV_AddInterface_State_Offline;
211 ifspeed[0] = 0;
213 MiamiPanelAddInterface(ifp->if_index, ifname, ifstate, ifp->if_data.ifi_aros_ontime.tv_secs, ifspeed);
216 DGUI(KPrintF("Opening the panel...\n");)
217 MiamiPanelInhibitRefresh(FALSE);
218 DGUI(KPrintF("Panel opened\n");)
219 gui_timerio->tr_node.io_Command = TR_ADDREQUEST;
220 gui_timerio->tr_time.tv_secs = gui_refresh;
221 gui_timerio->tr_time.tv_micro = 0;
222 SendIO ((struct IORequest *)gui_timerio);
223 return;
225 CloseLibrary(MiamiPanelBase);
226 MiamiPanelBase = NULL;
228 CloseDevice((struct IORequest *)gui_timerio);
230 DeleteIORequest((struct IORequest *)gui_timerio);
231 gui_timerio = NULL;
235 void gui_close()
237 #if defined(__AROS__)
238 D(bug("[AROSTCP](amiga_gui.c) %s()\n", __func__));
239 #endif
240 DGUI(KPrintF("Closing GUI...\n");)
241 if (gui_timerio) {
242 if (MiamiPanelBase) {
243 if (GUI_Running) {
244 DGUI(KPrintF("Cleaning up the panel\n");)
245 AbortIO((struct IORequest *)gui_timerio);
246 WaitIO((struct IORequest *)gui_timerio);
247 GUI_Running = 0;
248 guimask = 0;
249 MiamiPanelCleanup();
251 CloseLibrary(MiamiPanelBase);
252 MiamiPanelBase = NULL;
253 DGUI(KPrintF("Panel library closed\n");)
255 CloseDevice((struct IORequest *)gui_timerio);
256 DeleteIORequest((struct IORequest *)gui_timerio);
257 gui_timerio = NULL;
261 void gui_snapshot()
263 #if defined(__AROS__)
264 D(bug("[AROSTCP](amiga_gui.c) %s()\n", __func__));
265 #endif
266 /* TODO */
269 void gui_process_refresh()
271 struct ifnet *ifp;
272 struct timeval now;
273 unsigned long rate;
274 union {
275 unsigned long long q;
276 struct {
277 unsigned long hi;
278 unsigned long lo;
279 } l;
280 } total;
282 #if defined(__AROS__)
283 D(bug("[AROSTCP](amiga_gui.c) %s()\n", __func__));
284 #endif
286 if (GUI_Running) {
287 WaitIO ((struct IORequest *)gui_timerio);
288 GetSysTime(&now);
289 MiamiPanelInterfaceReport(-1, 0, now.tv_secs, 0, 0);
290 for (ifp = ifnet; ifp; ifp = ifp->if_next) {
291 if ((ifp->if_flags & (IFF_LOOPBACK | IFF_UP)) == IFF_UP) {
292 total.q = ifp->if_ibytes + ifp->if_obytes;
293 rate = (total.q - ifp->if_data.ifi_aros_lasttotal)/gui_refresh;
294 ifp->if_data.ifi_aros_lasttotal = total.q;
295 MiamiPanelInterfaceReport(ifp->if_index, rate, now.tv_secs, total.l.hi, total.l.lo);
298 gui_timerio->tr_node.io_Command = TR_ADDREQUEST;
299 gui_timerio->tr_time.tv_secs = gui_refresh;
300 gui_timerio->tr_time.tv_micro = 0;
301 SendIO ((struct IORequest *)gui_timerio);
305 void gui_process_msg(struct SysLogPacket *msg)
307 struct ifnet *ifp;
308 long state;
309 char ifspeed[16];
311 #if defined(__AROS__)
312 D(bug("[AROSTCP](amiga_gui.c) %s()\n", __func__));
313 #endif
315 if (GUI_Running) {
316 switch (msg->Level & GUICMD_MASK) {
317 case GUICMD_SET_INTERFACE_STATE:
318 ifp = (struct ifnet *)msg->Time;
319 state = (long)msg->Tag;
320 DGUI(KPrintF("Setting interface state for %s%u: 0x%08lx\n", ifp->if_name, ifp->if_unit, state);)
321 MiamiPanelSetInterfaceState(ifp->if_index, state, ifp->if_data.ifi_aros_ontime.tv_secs);
322 DGUI(KPrintF("Interface state set\n");)
323 if (state & (MIAMIPANELV_AddInterface_State_Online | MIAMIPANELV_AddInterface_State_Offline)) {
324 if (state == MIAMIPANELV_AddInterface_State_Online) {
325 getbaud(ifspeed, ifp->if_baudrate);
326 } else
327 ifspeed[0] = 0;
328 MiamiPanelSetInterfaceSpeed(ifp->if_index, ifspeed);
330 break;
331 case GUICMD_CLOSE:
332 gui_close();
333 break;
336 if ((msg->Level & GUICMD_MASK) == GUICMD_SET_INTERFACE_STATE) {
337 if (state & (MIAMIPANELV_AddInterface_State_Online | MIAMIPANELV_AddInterface_State_GoingOffline)) {
338 if ((state == MIAMIPANELV_AddInterface_State_Online) && (ifp->if_data.ifi_aros_usedhcp))
339 run_dhclient(ifp);
340 if (state == MIAMIPANELV_AddInterface_State_GoingOffline)
341 kill_dhclient(ifp);
346 void gui_set_interface_state(struct ifnet *ifp, long state)
348 struct SysLogPacket *msg;
350 #if defined(__AROS__)
351 D(bug("[AROSTCP](amiga_gui.c) %s()\n", __func__));
352 #endif
354 if (GUI_Running) {
355 if (msg = (struct SysLogPacket *)GetLogMsg(&logReplyPort)) {
356 msg->Level = LOG_GUIMSG | GUICMD_SET_INTERFACE_STATE;
357 msg->Time = (IPTR)ifp;
358 msg->Tag = (STRPTR)state;
359 PutMsg(logPort, (struct Message *)msg);
364 void error_request(STRPTR Text, ...)
366 struct EasyStruct es = {
367 sizeof(struct EasyStruct),
369 "AROSTCP error",
370 NULL,
371 "Ok"
374 es.es_TextFormat = Text;
375 AROS_SLOWSTACKFORMAT_PRE(Text);
376 EasyRequestArgs(NULL, &es, NULL, AROS_SLOWSTACKFORMAT_ARG(Text));
377 AROS_SLOWSTACKFORMAT_POST(Text);