2 * amtterm -- Intel AMT serial-over-lan client, gtk version.
4 * Copyright (C) 2007 Gerd Hoffmann <kraxel@redhat.com
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
36 #include "parseconfig.h"
39 #define APPNAME "gamt"
50 GtkActionGroup
*hosts_ag
;
59 static const char *state_stock
[] = {
60 [ REDIR_NONE
] = GTK_STOCK_DISCONNECT
,
62 [ REDIR_CONNECT
] = GTK_STOCK_
,
63 [ REDIR_INIT
] = GTK_STOCK_
,
64 [ REDIR_AUTH
] = GTK_STOCK_
,
65 [ REDIR_INIT_SOL
] = GTK_STOCK_
,
67 [ REDIR_RUN_SOL
] = GTK_STOCK_CONNECT
,
69 [ REDIR_INIT_IDER
] = GTK_STOCK_
,
70 [ REDIR_RUN_IDER
] = GTK_STOCK_
,
71 [ REDIR_CLOSING
] = GTK_STOCK_
,
73 [ REDIR_CLOSED
] = GTK_STOCK_DISCONNECT
,
74 [ REDIR_ERROR
] = GTK_STOCK_DISCONNECT
,
77 static char amt_host
[64];
78 static char amt_port
[16];
79 static char amt_user
[32] = "admin";
80 static char amt_pass
[32];
84 static int gamt_getstring(GtkWidget
*window
, char *title
, char *message
,
85 char *dest
, int dlen
, int hide
);
86 static int gamt_connect(struct gamt_window
*gamt
);
87 static void gamt_rebuild_hosts(struct gamt_window
*gamt
);
89 /* ------------------------------------------------------------------ */
91 #define CFG_SECTION "config", "config"
92 #define CFG_FONT CFG_SECTION, "font"
93 #define CFG_FOREGROUND CFG_SECTION, "foreground"
94 #define CFG_BACKGROUND CFG_SECTION, "background"
95 #define CFG_BLINK CFG_SECTION, "blink-cursor"
97 /* ------------------------------------------------------------------ */
99 static void menu_cb_connect(GtkAction
*action
, void *data
)
101 struct gamt_window
*gamt
= data
;
104 if (gamt
->redir
.state
!= REDIR_NONE
&&
105 gamt
->redir
.state
!= REDIR_CLOSED
&&
106 gamt
->redir
.state
!= REDIR_ERROR
)
107 /* already have an active connection */
110 rc
= gamt_getstring(gamt
->win
, "Connecting",
112 amt_host
, sizeof(amt_host
), 0);
119 static void menu_cb_connect_to(GtkAction
*action
, void *data
)
121 struct gamt_window
*gamt
= data
;
123 if (gamt
->redir
.state
!= REDIR_NONE
&&
124 gamt
->redir
.state
!= REDIR_CLOSED
&&
125 gamt
->redir
.state
!= REDIR_ERROR
)
126 /* already have an active connection */
129 if (1 != sscanf(gtk_action_get_name(action
), "ConnectTo_%s", amt_host
))
134 static void menu_cb_disconnect(GtkAction
*action
, void *data
)
136 struct gamt_window
*gamt
= data
;
138 if (gamt
->redir
.state
!= REDIR_RUN_SOL
)
140 redir_sol_stop(&gamt
->redir
);
143 static void menu_cb_config_font(GtkAction
*action
, void *data
)
145 struct gamt_window
*gamt
= data
;
149 dialog
= gtk_font_selection_dialog_new("Terminal font");
150 fontname
= cfg_get_str(CFG_FONT
);
151 gtk_font_selection_dialog_set_font_name
152 (GTK_FONT_SELECTION_DIALOG(dialog
), fontname
);
154 gtk_widget_show_all(dialog
);
155 switch (gtk_dialog_run(GTK_DIALOG(dialog
))) {
156 case GTK_RESPONSE_OK
:
157 fontname
= gtk_font_selection_dialog_get_font_name
158 (GTK_FONT_SELECTION_DIALOG(dialog
));
159 vte_terminal_set_font_from_string(VTE_TERMINAL(gamt
->vte
), fontname
);
160 cfg_set_str(CFG_FONT
, fontname
);
163 gtk_widget_destroy(dialog
);
166 static int pickcolor(char *title
, GdkColor
*color
)
169 GtkColorSelection
*csel
;
172 dialog
= gtk_color_selection_dialog_new(title
);
173 csel
= GTK_COLOR_SELECTION(GTK_COLOR_SELECTION_DIALOG(dialog
)->colorsel
);
174 gtk_color_selection_set_has_opacity_control(csel
, FALSE
);
175 gtk_color_selection_set_current_color(csel
, color
);
177 gtk_widget_show_all(dialog
);
178 switch (gtk_dialog_run(GTK_DIALOG(dialog
))) {
179 case GTK_RESPONSE_OK
:
180 gtk_color_selection_get_current_color(csel
, color
);
183 gtk_widget_destroy(dialog
);
187 static void menu_cb_config_fg(GtkAction
*action
, void *data
)
189 struct gamt_window
*gamt
= data
;
190 GdkColor color
= {0,0,0,0};
193 gdk_color_parse(cfg_get_str(CFG_FOREGROUND
), &color
);
194 if (0 != pickcolor("Text color", &color
))
196 vte_terminal_set_color_foreground(VTE_TERMINAL(gamt
->vte
), &color
);
197 snprintf(name
, sizeof(name
), "#%04x%04x%04x",
198 color
.red
, color
.green
, color
.blue
);
199 cfg_set_str(CFG_FOREGROUND
, name
);
202 static void menu_cb_config_bg(GtkAction
*action
, void *data
)
204 struct gamt_window
*gamt
= data
;
205 GdkColor color
= {0,0,0,0};
208 gdk_color_parse(cfg_get_str(CFG_BACKGROUND
), &color
);
209 if (0 != pickcolor("Background color", &color
))
211 vte_terminal_set_color_background(VTE_TERMINAL(gamt
->vte
), &color
);
212 snprintf(name
, sizeof(name
), "#%04x%04x%04x",
213 color
.red
, color
.green
, color
.blue
);
214 cfg_set_str(CFG_BACKGROUND
, name
);
217 static void menu_cb_blink_cursor(GtkToggleAction
*action
, gpointer user_data
)
219 struct gamt_window
*gamt
= user_data
;
220 gboolean state
= gtk_toggle_action_get_active(action
);
223 fprintf(stderr
, "%s: %s\n", __FUNCTION__
, state
? "on" : "off");
224 cfg_set_bool(CFG_BLINK
, state
);
225 vte_terminal_set_cursor_blinks(VTE_TERMINAL(gamt
->vte
), state
);
228 static void menu_cb_quit(GtkAction
*action
, void *data
)
230 struct gamt_window
*gamt
= data
;
232 gtk_widget_destroy(gamt
->win
);
235 static void show_manpage(char *page
, char *section
)
245 /* child: try xdg-open first ... */
246 snprintf(buf
, sizeof(buf
), "man:%s(%s)", page
, section
);
247 execlp("xdg-open", "xdg-open", buf
, NULL
);
248 perror("execlp(xdg-open)");
249 /* ... fallback is an xterm with man */
250 snprintf(buf
, sizeof(buf
), "manual page: %s(%s)", page
, section
);
251 execlp("xterm", "xterm",
253 "-e", "man", section
, page
,
255 perror("execlp(xterm)");
264 static void menu_cb_man_gamt(GtkAction
*action
, void *data
)
266 show_manpage("gamt", "1");
269 static void menu_cb_man_amt_howto(GtkAction
*action
, void *data
)
271 show_manpage("amt-howto", "7");
274 static void menu_cb_about(GtkAction
*action
, void *data
)
276 static char *comments
= "Intel AMT serial-over-lan client";
277 static char *copyright
= "(c) 2007 Gerd Hoffmann";
278 static char *website
= "http://dl.bytesex.org/releases/amtterm/";
279 static char *authors
[] = { "Gerd Hoffmann <kraxel@redhat.com>", NULL
};
280 struct gamt_window
*gamt
= data
;
282 gtk_show_about_dialog(GTK_WINDOW(gamt
->win
),
284 "comments", comments
,
285 "copyright", copyright
,
286 "logo-icon-name", GTK_STOCK_ABOUT
,
289 // "license", "GPLv2+",
293 static void destroy_cb(GtkWidget
*widget
, gpointer data
)
295 struct gamt_window
*gamt
= data
;
301 /* ------------------------------------------------------------------ */
303 static int recv_gtk(void *cb_data
, unsigned char *buf
, int len
)
305 struct gamt_window
*gamt
= cb_data
;
306 vte_terminal_feed(VTE_TERMINAL(gamt
->vte
), buf
, len
);
310 static void state_gtk(void *cb_data
, enum redir_state old
, enum redir_state
new)
312 struct gamt_window
*gamt
= cb_data
;
313 unsigned char buf
[128];
319 snprintf(buf
, sizeof(buf
), "%s: %s FAILED (%s)", gamt
->redir
.host
,
320 redir_state_desc(old
), gamt
->redir
.err
);
322 snprintf(buf
, sizeof(buf
), "%s: ERROR: %s", gamt
->redir
.host
,
325 if (old
== REDIR_AUTH
) {
326 /* ask for a new password next time ... */
327 strcpy(amt_pass
, "");
331 last
= cfg_get_int("config", "hosts", gamt
->redir
.host
, 0);
332 cfg_set_int("config", "hosts", gamt
->redir
.host
, time(NULL
));
334 gamt_rebuild_hosts(gamt
);
337 snprintf(buf
, sizeof(buf
), "%s: %s", gamt
->redir
.host
,
338 redir_state_desc(new));
341 if (state_stock
[new])
342 gtk_image_set_from_stock(GTK_IMAGE(gamt
->icon
), state_stock
[new],
343 GTK_ICON_SIZE_SMALL_TOOLBAR
);
344 gtk_label_set_text(GTK_LABEL(gamt
->status
), buf
);
347 static void user_input(VteTerminal
*vte
, gchar
*buf
, guint len
,
350 struct gamt_window
*gamt
= data
;
352 if (gamt
->redir
.state
== REDIR_RUN_SOL
)
353 redir_sol_send(&gamt
->redir
, buf
, len
);
356 /* ------------------------------------------------------------------ */
358 static const GtkActionEntry entries
[] = {
363 .name
= "ConfigMenu",
375 .stock_id
= GTK_STOCK_CONNECT
,
376 .label
= "_Connect ...",
377 .callback
= G_CALLBACK(menu_cb_connect
),
379 .name
= "Disconnect",
380 .stock_id
= GTK_STOCK_DISCONNECT
,
381 .label
= "_Disconnect",
382 .callback
= G_CALLBACK(menu_cb_disconnect
),
385 .stock_id
= GTK_STOCK_QUIT
,
387 .callback
= G_CALLBACK(menu_cb_quit
),
392 .stock_id
= GTK_STOCK_SELECT_FONT
,
393 .label
= "Terminal _font ...",
394 .callback
= G_CALLBACK(menu_cb_config_font
),
396 .name
= "VteForeground",
397 // .stock_id = GTK_STOCK_SELECT_COLOR,
398 .label
= "_Text Color ...",
399 .callback
= G_CALLBACK(menu_cb_config_fg
),
401 .name
= "VteBackground",
402 .label
= "_Background Color ...",
403 .callback
= G_CALLBACK(menu_cb_config_bg
),
408 .stock_id
= GTK_STOCK_HELP
,
409 .label
= "Manual Page",
410 .callback
= G_CALLBACK(menu_cb_man_gamt
),
412 .name
= "ManAmtHowto7",
413 .stock_id
= GTK_STOCK_INFO
,
414 .label
= "AMT HowTo",
415 .callback
= G_CALLBACK(menu_cb_man_amt_howto
),
418 .stock_id
= GTK_STOCK_ABOUT
,
419 .label
= "_About ...",
420 .callback
= G_CALLBACK(menu_cb_about
),
424 static const GtkToggleActionEntry tentries
[] = {
426 .name
= "BlinkCursor",
427 .label
= "Blinking cursor",
428 .callback
= G_CALLBACK(menu_cb_blink_cursor
),
432 static char ui_xml
[] =
434 " <menubar action='MainMenu'>\n"
435 " <menu action='FileMenu'>\n"
436 " <menuitem action='Connect'/>\n"
437 " <menuitem action='Disconnect'/>\n"
439 " <menuitem action='Quit'/>\n"
441 " <menu action='HostMenu'>\n"
443 " <menu action='ConfigMenu'>\n"
444 " <menuitem action='VteFont'/>\n"
445 " <menuitem action='VteForeground'/>\n"
446 " <menuitem action='VteBackground'/>\n"
448 " <menuitem action='BlinkCursor'/>\n"
450 " <menu action='HelpMenu'>\n"
451 " <menuitem action='ManGamt1'/>\n"
452 " <menuitem action='ManAmtHowto7'/>\n"
454 " <menuitem action='About'/>\n"
457 " <toolbar action='ToolBar'>\n"
458 " <toolitem action='Quit'/>\n"
459 " <toolitem action='Connect'/>\n"
460 " <toolitem action='Disconnect'/>\n"
464 static char hosts_xml_start
[] =
466 " <menubar name='MainMenu'>\n"
467 " <menu action='HostMenu'>\n";
469 static char hosts_xml_end
[] =
474 /* ------------------------------------------------------------------ */
476 static int gamt_getstring(GtkWidget
*window
, char *title
, char *message
,
477 char *dest
, int dlen
, int hide
)
479 GtkWidget
*dialog
, *label
, *entry
;
483 /* Create the widgets */
484 dialog
= gtk_dialog_new_with_buttons(title
,
486 GTK_DIALOG_DESTROY_WITH_PARENT
,
492 gtk_dialog_set_default_response(GTK_DIALOG(dialog
), GTK_RESPONSE_ACCEPT
);
494 label
= gtk_label_new(message
);
495 gtk_misc_set_alignment(GTK_MISC(label
), 0, 0.5);
497 entry
= gtk_entry_new();
498 gtk_entry_set_text(GTK_ENTRY(entry
), dest
);
499 gtk_entry_set_activates_default(GTK_ENTRY(entry
), TRUE
);
501 gtk_entry_set_visibility(GTK_ENTRY(entry
), FALSE
);
503 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog
)->vbox
), label
);
504 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog
)->vbox
), entry
);
505 gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dialog
)->vbox
), 10);
506 #if 0 /* FIXME: doesn't work ... */
507 gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(dialog
)->vbox
), 10);
510 /* show and wait for response */
511 gtk_widget_show_all(dialog
);
512 switch (gtk_dialog_run(GTK_DIALOG(dialog
))) {
513 case GTK_RESPONSE_ACCEPT
:
514 txt
= gtk_entry_get_text(GTK_ENTRY(entry
));
515 snprintf(dest
, dlen
, "%s", txt
);
522 gtk_widget_destroy(dialog
);
526 static gboolean
gamt_data(GIOChannel
*source
, GIOCondition condition
,
529 struct gamt_window
*gamt
= data
;
531 redir_data(&gamt
->redir
);
533 if (gamt
->redir
.state
== REDIR_CLOSED
||
534 gamt
->redir
.state
== REDIR_ERROR
) {
535 g_source_destroy(g_main_context_find_source_by_id
536 (g_main_context_default(), gamt
->id
));
543 static void gamt_rebuild_hosts(struct gamt_window
*gamt
)
545 int count
, size
, pos
;
546 char *hosts_xml
, *host
, action
[128];
547 GtkActionEntry entry
;
551 if (gamt
->hosts_id
) {
552 gtk_ui_manager_remove_ui(gamt
->ui
, gamt
->hosts_id
);
555 if (gamt
->hosts_ag
) {
556 gtk_ui_manager_remove_action_group(gamt
->ui
, gamt
->hosts_ag
);
557 g_object_unref(gamt
->hosts_ag
);
558 gamt
->hosts_ag
= NULL
;
562 memset(&entry
, 0, sizeof(entry
));
563 entry
.callback
= G_CALLBACK(menu_cb_connect_to
);
564 gamt
->hosts_ag
= gtk_action_group_new("HostActions");
565 count
= cfg_entries_count("config", "hosts");
566 size
= 128 * count
+ sizeof(hosts_xml_start
) + sizeof(hosts_xml_end
);
567 hosts_xml
= malloc(size
); pos
= 0;
568 pos
+= sprintf(hosts_xml
+pos
, "%s", hosts_xml_start
);
569 for (host
= cfg_entries_first("config", "hosts");
571 host
= cfg_entries_next("config", "hosts", host
)) {
572 snprintf(action
, sizeof(action
), "ConnectTo_%s", host
);
573 pos
+= snprintf(hosts_xml
+pos
, 128,
574 " <menuitem action='%s'/>\n",
578 gtk_action_group_add_actions(gamt
->hosts_ag
, &entry
, 1, gamt
);
580 pos
+= sprintf(hosts_xml
+pos
, "%s", hosts_xml_end
);
583 gtk_ui_manager_insert_action_group(gamt
->ui
, gamt
->hosts_ag
, 1);
584 gamt
->hosts_id
= gtk_ui_manager_add_ui_from_string(gamt
->ui
, hosts_xml
, -1, &err
);
585 if (!gamt
->hosts_id
) {
586 g_message("building host menu failed: %s", err
->message
);
591 static int gamt_connect(struct gamt_window
*gamt
)
595 if (0 == strlen(amt_pass
)) {
598 snprintf(msg
, sizeof(msg
), "AMT password for %s@%s ?",
600 rc
= gamt_getstring(gamt
->win
, "Authentication", msg
,
601 amt_pass
, sizeof(amt_pass
), 1);
606 memset(&gamt
->redir
, 0, sizeof(gamt
->redir
));
607 memcpy(&gamt
->redir
.type
, "SOL ", 4);
609 snprintf(gamt
->redir
.host
, sizeof(gamt
->redir
.host
), "%s", amt_host
);
610 snprintf(gamt
->redir
.port
, sizeof(gamt
->redir
.port
), "%s", amt_port
);
611 snprintf(gamt
->redir
.user
, sizeof(gamt
->redir
.user
), "%s", amt_user
);
612 snprintf(gamt
->redir
.pass
, sizeof(gamt
->redir
.pass
), "%s", amt_pass
);
614 gamt
->redir
.verbose
= 1;
615 gamt
->redir
.trace
= amt_trace
;
616 gamt
->redir
.cb_data
= gamt
;
617 gamt
->redir
.cb_recv
= recv_gtk
;
618 gamt
->redir
.cb_state
= state_gtk
;
620 if (-1 == redir_connect(&gamt
->redir
))
623 fcntl(gamt
->redir
.sock
, F_SETFD
, FD_CLOEXEC
);
624 vte_terminal_reset(VTE_TERMINAL(gamt
->vte
), TRUE
, TRUE
);
625 gamt
->ch
= g_io_channel_unix_new(gamt
->redir
.sock
);
626 gamt
->id
= g_io_add_watch(gamt
->ch
, G_IO_IN
, gamt_data
, gamt
);
627 redir_start(&gamt
->redir
);
631 static struct gamt_window
*gamt_window()
633 GtkWidget
*vbox
, *hbox
, *frame
, *item
;
637 struct gamt_window
*gamt
;
640 gamt
= malloc(sizeof(*gamt
));
643 memset(gamt
,0,sizeof(*gamt
));
646 gamt
->win
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
647 g_signal_connect(G_OBJECT(gamt
->win
), "destroy",
648 G_CALLBACK(destroy_cb
), gamt
);
651 gamt
->ui
= gtk_ui_manager_new();
652 gamt
->ag
= gtk_action_group_new("MenuActions");
653 gtk_action_group_add_actions(gamt
->ag
, entries
, G_N_ELEMENTS(entries
), gamt
);
654 gtk_action_group_add_toggle_actions(gamt
->ag
, tentries
,
655 G_N_ELEMENTS(tentries
), gamt
);
656 gtk_ui_manager_insert_action_group(gamt
->ui
, gamt
->ag
, 0);
658 GtkAccelGroup
*accel
= gtk_ui_manager_get_accel_group(gamt
->ui
);
659 gtk_window_add_accel_group(GTK_WINDOW(gamt
->win
), accel
);
663 if (!gtk_ui_manager_add_ui_from_string(gamt
->ui
, ui_xml
, -1, &err
)) {
664 g_message("building menus failed: %s", err
->message
);
668 gamt_rebuild_hosts(gamt
);
671 gamt
->vte
= vte_terminal_new();
672 g_signal_connect(gamt
->vte
, "commit", G_CALLBACK(user_input
), gamt
);
673 vte_terminal_set_scrollback_lines(VTE_TERMINAL(gamt
->vte
), 4096);
674 str
= cfg_get_str(CFG_FONT
);
675 vte_terminal_set_font_from_string(VTE_TERMINAL(gamt
->vte
), str
);
677 /* FIXME: make configurable */
678 vte_terminal_set_backspace_binding(VTE_TERMINAL(gamt
->vte
),
679 VTE_ERASE_ASCII_BACKSPACE
);
680 vte_terminal_set_delete_binding(VTE_TERMINAL(gamt
->vte
),
683 item
= gtk_ui_manager_get_widget(gamt
->ui
, "/MainMenu/ConfigMenu/BlinkCursor");
684 state
= cfg_get_bool(CFG_BLINK
, 0);
685 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item
), state
);
686 vte_terminal_set_cursor_blinks(VTE_TERMINAL(gamt
->vte
), state
);
689 gamt
->status
= gtk_label_new("idle");
690 gtk_misc_set_alignment(GTK_MISC(gamt
->status
), 0, 0.5);
691 gtk_misc_set_padding(GTK_MISC(gamt
->status
), 3, 1);
692 gamt
->icon
= gtk_image_new_from_stock(GTK_STOCK_DISCONNECT
,
693 GTK_ICON_SIZE_SMALL_TOOLBAR
);
695 /* Make a vbox and put stuff in */
696 vbox
= gtk_vbox_new(FALSE
, 1);
697 hbox
= gtk_hbox_new(FALSE
, 1);
698 gtk_container_set_border_width(GTK_CONTAINER(vbox
), 1);
699 gtk_container_add(GTK_CONTAINER(gamt
->win
), vbox
);
700 item
= gtk_ui_manager_get_widget(gamt
->ui
, "/MainMenu");
701 gtk_box_pack_start(GTK_BOX(vbox
), item
, FALSE
, FALSE
, 0);
703 item
= gtk_ui_manager_get_widget(gamt
->ui
, "/ToolBar");
704 gtk_box_pack_start(GTK_BOX(vbox
), item
, FALSE
, FALSE
, 0);
706 gtk_box_pack_start(GTK_BOX(vbox
), gamt
->vte
, TRUE
, TRUE
, 0);
707 gtk_box_pack_end(GTK_BOX(vbox
), hbox
, FALSE
, TRUE
, 0);
709 frame
= gtk_frame_new(NULL
);
710 gtk_container_add(GTK_CONTAINER(frame
), gamt
->status
);
711 gtk_box_pack_start(GTK_BOX(hbox
), frame
, TRUE
, TRUE
, 0);
713 frame
= gtk_frame_new(NULL
);
714 gtk_container_add(GTK_CONTAINER(frame
), gamt
->icon
);
715 gtk_box_pack_end(GTK_BOX(hbox
), frame
, FALSE
, TRUE
, 0);
718 gtk_widget_show_all(gamt
->win
);
720 str
= cfg_get_str(CFG_FOREGROUND
);
722 gdk_color_parse(str
, &color
);
723 vte_terminal_set_color_foreground(VTE_TERMINAL(gamt
->vte
), &color
);
725 str
= cfg_get_str(CFG_BACKGROUND
);
727 gdk_color_parse(str
, &color
);
728 vte_terminal_set_color_background(VTE_TERMINAL(gamt
->vte
), &color
);
734 /* ------------------------------------------------------------------ */
736 static void usage(FILE *fp
)
740 "This is " APPNAME
", release " VERSION
", I'll establish\n"
741 "serial-over-lan (sol) connections to your Intel AMT boxes.\n"
743 "usage: " APPNAME
" [options] host\n"
745 " -h print this text\n"
746 " -u user username (default: admin)\n"
747 " -p pass password (default: $AMT_PASSWORD)\n"
748 " -f font terminal font\n"
749 " -c color text color\n"
750 " -b color backgrounf color\n"
752 "By default port 16994 is used.\n"
753 "If no password is given " APPNAME
" will ask for one.\n"
756 "(c) 2007 Gerd Hoffmann <kraxel@redhat.com>\n"
761 main(int argc
, char *argv
[])
764 struct gamt_window
*gamt
;
765 char configfile
[256];
769 if (NULL
!= (h
= getenv("AMT_PASSWORD")))
770 snprintf(amt_pass
, sizeof(amt_pass
), "%s", h
);
772 /* read config, make sure we have sane defaults */
773 snprintf(configfile
, sizeof(configfile
), "%s/.gamtrc", getenv("HOME"));
774 cfg_parse_file("config", configfile
);
775 if (!cfg_get_str(CFG_FONT
))
776 cfg_set_str(CFG_FONT
, "monospace 12");
777 if (!cfg_get_str(CFG_FOREGROUND
))
778 cfg_set_str(CFG_FOREGROUND
, "gray");
779 if (!cfg_get_str(CFG_BACKGROUND
))
780 cfg_set_str(CFG_BACKGROUND
, "black");
782 gtk_init(&argc
, &argv
);
783 dpy
= gdk_x11_display_get_xdisplay(gdk_display_get_default());
784 fcntl(ConnectionNumber(dpy
),F_SETFD
,FD_CLOEXEC
);
787 if (-1 == (c
= getopt(argc
, argv
, "hdtu:p:f:c:b:")))
797 snprintf(amt_user
, sizeof(amt_user
), "%s", optarg
);
800 snprintf(amt_pass
, sizeof(amt_pass
), "%s", optarg
);
801 memset(optarg
,'*',strlen(optarg
)); /* rm passwd from ps list */
804 cfg_set_str(CFG_FONT
, optarg
);
807 cfg_set_str(CFG_FOREGROUND
, optarg
);
810 cfg_set_str(CFG_BACKGROUND
, optarg
);
822 gamt
= gamt_window();
826 if (optind
+1 <= argc
) {
827 snprintf(amt_host
, sizeof(amt_host
), "%s", argv
[optind
]);
832 cfg_write_file("config", configfile
);