~ubuntu-branches/ubuntu/oneiric/likewise-open/oneiric

« back to all changes in this revision

Viewing changes to krb5/src/windows/wintel/telnet.c

  • Committer: Bazaar Package Importer
  • Author(s): Scott Salley
  • Date: 2010-11-22 12:06:00 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20101122120600-8lba1fpceot71wlb
Tags: 6.0.0.53010-1
Likewise Open 6.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
  
 
3
  Program: telnet.c
 
4
  
 
5
  PURPOSE: Windows networking kernel - Telnet
 
6
  
 
7
  FUNCTIONS:
 
8
  
 
9
  WinMain() - calls initialization function, processes message loop
 
10
  InitApplication() - initializes window data and registers window
 
11
  InitInstance() - saves instance handle and creates main window
 
12
  MainWndProc() - processes messages
 
13
  About() - processes messages for "About" dialog box
 
14
  
 
15
  COMMENTS:
 
16
  
 
17
  Windows can have several copies of your application running at the
 
18
  same time.  The variable hInst keeps track of which instance this
 
19
  application is so that processing will be to the correct window.
 
20
  
 
21
  ****************************************************************************/
 
22
 
 
23
#include <windows.h>
 
24
#include <stdlib.h>
 
25
#include <string.h>
 
26
#include <assert.h>
 
27
#include "telnet.h"
 
28
#include "auth.h"
 
29
 
 
30
static HANDLE hInst;
 
31
static HWND hWnd;
 
32
static CONFIG *tmpConfig;
 
33
static CONNECTION *con = NULL;
 
34
static char hostdata[MAXGETHOSTSTRUCT];
 
35
static SCREEN *pScr;
 
36
static int debug = 1;
 
37
 
 
38
char strTmp[1024];                      /* Scratch buffer */
 
39
BOOL bAutoConnection = FALSE; 
 
40
short port_no = 23;
 
41
char szUserName[64];                    /* Used in auth.c */
 
42
char szHostName[64];
 
43
 
 
44
#ifdef KRB4
 
45
#define WINDOW_CLASS   "K4_telnetWClass"
 
46
#endif
 
47
 
 
48
#ifdef KRB5
 
49
krb5_context k5_context;
 
50
#define WINDOW_CLASS   "K5_telnetWClass"
 
51
#endif
 
52
 
 
53
/*
 
54
 *
 
55
 * FUNCTION: WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
 
56
 * 
 
57
 * PURPOSE: calls initialization function, processes message loop
 
58
 * 
 
59
 * COMMENTS:
 
60
 * 
 
61
 * Windows recognizes this function by name as the initial entry point 
 
62
 * for the program.  This function calls the application initialization 
 
63
 * routine, if no other instance of the program is running, and always 
 
64
 * calls the instance initialization routine.  It then executes a message 
 
65
 * retrieval and dispatch loop that is the top-level control structure 
 
66
 * for the remainder of execution.  The loop is terminated when a WM_QUIT 
 
67
 * message is received, at which time this function exits the application 
 
68
 * instance by returning the value passed by PostQuitMessage(). 
 
69
 * 
 
70
 * If this function must abort before entering the message loop, it 
 
71
 * returns the conventional value NULL.  
 
72
 */
 
73
 
 
74
int PASCAL
 
75
WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
 
76
{
 
77
  MSG msg;
 
78
 
 
79
  if (!hPrevInstance)
 
80
    if (!InitApplication(hInstance))
 
81
      return(FALSE);
 
82
  
 
83
  /*
 
84
   * Perform initializations that apply to a specific instance
 
85
   */
 
86
  bAutoConnection = parse_cmdline(lpCmdLine);
 
87
  
 
88
  if (!InitInstance(hInstance, nCmdShow))
 
89
    return(FALSE);
 
90
 
 
91
#ifdef _WIN32
 
92
  SetDebugErrorLevel(SLE_WARNING);
 
93
#endif
 
94
 
 
95
  /*
 
96
   * Acquire and dispatch messages until a WM_QUIT message is received.
 
97
   */
 
98
  while (GetMessage(&msg, NULL, 0, 0)) {
 
99
    TranslateMessage(&msg);
 
100
    DispatchMessage(&msg);
 
101
 
 
102
    /* Process all non-network messages */
 
103
    while (PeekMessage(&msg, NULL, 0, WM_NETWORKEVENT-1, PM_REMOVE) ||
 
104
           PeekMessage(&msg, NULL, WM_NETWORKEVENT+1, (UINT)-1, PM_REMOVE))
 
105
    {
 
106
        if (msg.message == WM_QUIT)     // Special case: WM_QUIT -- return
 
107
            return msg.wParam;          //   the value from PostQuitMessage
 
108
        
 
109
        TranslateMessage(&msg);
 
110
        DispatchMessage(&msg);
 
111
    }
 
112
  }
 
113
 
 
114
  return (msg.wParam);          /* Returns the value from PostQuitMessage */
 
115
}
 
116
 
 
117
/*
 
118
 * FUNCTION: InitApplication(HINSTANCE)
 
119
 * 
 
120
 * PURPOSE: Initializes window data and registers window class
 
121
 * 
 
122
 * COMMENTS:
 
123
 * 
 
124
 * This function is called at initialization time only if no other 
 
125
 * instances of the application are running.  This function performs 
 
126
 * initialization tasks that can be done once for any number of running 
 
127
 * instances.  
 
128
 * 
 
129
 * In this case, we initialize a window class by filling out a data 
 
130
 * structure of type WNDCLASS and calling the Windows RegisterClass() 
 
131
 * function.  Since all instances of this application use the same window 
 
132
 * class, we only need to do this when the first instance is initialized.  
 
133
 */
 
134
 
 
135
BOOL
 
136
InitApplication(HINSTANCE hInstance)
 
137
{
 
138
  WNDCLASS  wc;
 
139
  
 
140
  ScreenInit(hInstance);
 
141
  
 
142
  /*
 
143
   * Fill in window class structure with parameters that describe the
 
144
   * main window.
 
145
   */
 
146
  wc.style = CS_HREDRAW | CS_VREDRAW; /* Class style(s). */
 
147
  wc.lpfnWndProc = MainWndProc;       /* Function to retrieve messages for 
 
148
                                       * windows of this class.
 
149
                                       */
 
150
  wc.cbClsExtra = 0;                  /* No per-class extra data. */
 
151
  wc.cbWndExtra = 0;                  /* No per-window extra data. */
 
152
  wc.hInstance = hInstance;           /* Application that owns the class. */
 
153
  wc.hIcon = NULL;                    /* LoadIcon(hInstance, "NCSA"); */
 
154
  wc.hCursor = NULL;                  /* Cursor(NULL, IDC_ARROW); */
 
155
  wc.hbrBackground = NULL;            /* GetStockObject(WHITE_BRUSH); */
 
156
  wc.lpszMenuName =  NULL;            /* Name of menu resource in .RC file. */
 
157
  wc.lpszClassName = WINDOW_CLASS;    /* Name used in call to CreateWindow. */
 
158
  
 
159
  return(RegisterClass(&wc));
 
160
}
 
161
 
 
162
 
 
163
/*
 
164
 * FUNCTION:  InitInstance(HANDLE, int)
 
165
 * 
 
166
 * PURPOSE:  Saves instance handle and creates main window
 
167
 * 
 
168
 * COMMENTS:
 
169
 * 
 
170
 * This function is called at initialization time for every instance of 
 
171
 * this application.  This function performs initialization tasks that 
 
172
 * cannot be shared by multiple instances.  
 
173
 * 
 
174
 * In this case, we save the instance handle in a static variable and 
 
175
 * create and display the main program window.  
 
176
 */
 
177
BOOL
 
178
InitInstance(HINSTANCE hInstance, int nCmdShow)
 
179
{
 
180
  int xScreen = 0;
 
181
  int yScreen = 0;
 
182
  WSADATA wsaData;
 
183
  
 
184
  SetScreenInstance(hInstance);
 
185
  
 
186
  /*
 
187
   * Save the instance handle in static variable, which will be used in
 
188
   * many subsequence calls from this application to Windows.
 
189
   */
 
190
  hInst = hInstance;
 
191
  
 
192
  /*
 
193
   * Create a main window for this application instance.
 
194
   */
 
195
  hWnd = CreateWindow(
 
196
                      WINDOW_CLASS,     /* See RegisterClass() call. */
 
197
                      "TCPWin",         /* Text for window title bar. */
 
198
                      WS_SYSMENU,       /* Window style. */
 
199
                      xScreen / 3,      /* Default horizontal position. */
 
200
                      yScreen / 3,      /* Default vertical position. */
 
201
                      xScreen / 3,      /* Default width. */
 
202
                      yScreen / 3,      /* Default height. */
 
203
                      NULL,             /* Overlapped windows have no parent */
 
204
                      NULL,             /* Use the window class menu. */
 
205
                      hInstance,        /* This instance owns this window. */
 
206
                      NULL);            /* Pointer not needed. */
 
207
 
 
208
  if (!hWnd)
 
209
    return (FALSE);
 
210
                
 
211
  if (WSAStartup(0x0101, &wsaData) != 0) {   /* Initialize the network */
 
212
    MessageBox(NULL, "Couldn't initialize Winsock!", NULL,
 
213
               MB_OK | MB_ICONEXCLAMATION);
 
214
    return(FALSE);
 
215
  }             
 
216
 
 
217
  if (!OpenTelnetConnection()) {
 
218
    WSACleanup();
 
219
    return(FALSE);
 
220
  }
 
221
 
 
222
#ifdef KRB5
 
223
  krb5_init_context(&k5_context);
 
224
#endif
 
225
 
 
226
  return (TRUE);
 
227
}
 
228
 
 
229
char buf[2048];
 
230
 
 
231
/*
 
232
 * FUNCTION: MainWndProc(HWND, UINT, WPARAM, LPARAM)
 
233
 *
 
234
 * PURPOSE:  Processes messages
 
235
 *
 
236
 * MESSAGES:
 
237
 *
 
238
 * WM_COMMAND    - application menu (About dialog box)
 
239
 * WM_DESTROY    - destroy window
 
240
 */
 
241
LRESULT CALLBACK
 
242
MainWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
 
243
{
 
244
  HGLOBAL hBuffer;
 
245
  LPSTR lpBuffer; 
 
246
  int iEvent, cnt, ret;
 
247
  char *tmpCommaLoc;
 
248
  struct sockaddr_in remote_addr;
 
249
  struct hostent *remote_host;
 
250
        
 
251
  switch (message) {
 
252
  case WM_MYSCREENCHANGEBKSP:
 
253
    if (!con)
 
254
      break;
 
255
    con->backspace = wParam;
 
256
    if (con->backspace == VK_BACK) {
 
257
      con->ctrl_backspace = 0x7f;
 
258
      WritePrivateProfileString(INI_TELNET, INI_BACKSPACE, 
 
259
                                INI_BACKSPACE_BS, TELNET_INI);
 
260
    }
 
261
    else {
 
262
      con->ctrl_backspace = VK_BACK;
 
263
      WritePrivateProfileString(INI_TELNET, INI_BACKSPACE, 
 
264
                                INI_BACKSPACE_DEL, TELNET_INI);
 
265
    }
 
266
    GetPrivateProfileString(INI_HOSTS, INI_HOST "0", "", buf, 128, TELNET_INI);
 
267
    tmpCommaLoc = strchr(buf, ',');
 
268
    if (tmpCommaLoc == NULL) {
 
269
      strcat (buf, ",");
 
270
      tmpCommaLoc = strchr(buf, ',');
 
271
    }
 
272
    if (tmpCommaLoc) {
 
273
      tmpCommaLoc++;
 
274
      if (con->backspace == VK_BACK)
 
275
        strcpy(tmpCommaLoc, INI_HOST_BS);
 
276
      else
 
277
        strcpy(tmpCommaLoc, INI_HOST_DEL);
 
278
    }
 
279
    WritePrivateProfileString(INI_HOSTS, INI_HOST "0", buf, TELNET_INI);
 
280
    break;
 
281
 
 
282
  case WM_MYSCREENCHAR:
 
283
    {
 
284
      unsigned char c;
 
285
 
 
286
      if (!con)
 
287
        break;
 
288
      if (wParam == VK_BACK)
 
289
        c = con->backspace;
 
290
      else if (wParam == 0x7f)
 
291
        c = con->ctrl_backspace;
 
292
      else if (wParam == VK_SPACE && GetKeyState(VK_CONTROL) < 0)
 
293
        c = 0;
 
294
      else
 
295
        c = wParam;
 
296
      TelnetSend(con->ks, &c, 1, 0);
 
297
    }
 
298
  break;
 
299
 
 
300
  case WM_MYCURSORKEY:
 
301
    /* Acts as a send through: buffer is lParam and length in wParam */
 
302
    if (!con)
 
303
      break;
 
304
    memcpy(buf, (char *)lParam, wParam);
 
305
    TelnetSend (con->ks, buf, wParam, 0);
 
306
    break;
 
307
 
 
308
  case WM_MYSCREENBLOCK:
 
309
    if (!con)
 
310
      break;
 
311
    hBuffer = (HGLOBAL) wParam;
 
312
    lpBuffer = GlobalLock(hBuffer);
 
313
    TelnetSend(con->ks, lpBuffer, lstrlen(lpBuffer), 0);
 
314
    GlobalUnlock(hBuffer);
 
315
    break;
 
316
 
 
317
  case WM_MYSCREENCLOSE:
 
318
#if 0
 
319
    if (con)
 
320
    {
 
321
        kstream_destroy(con->ks);
 
322
        con->ks = NULL;
 
323
    }
 
324
#endif
 
325
    DestroyWindow(hWnd);
 
326
    break;        
 
327
 
 
328
  case WM_QUERYOPEN:
 
329
    return(0);
 
330
    break;
 
331
 
 
332
  case WM_DESTROY:          /* message: window being destroyed */
 
333
    if (con)
 
334
    {
 
335
        kstream_destroy(con->ks);
 
336
        free(con);
 
337
        WSACleanup();
 
338
    }
 
339
    PostQuitMessage(0);
 
340
    break;
 
341
 
 
342
  case WM_NETWORKEVENT: 
 
343
    iEvent = WSAGETSELECTEVENT(lParam);
 
344
 
 
345
    switch (iEvent) {           
 
346
 
 
347
    case FD_READ:
 
348
      if (con == NULL)
 
349
        break;
 
350
      cnt = kstream_read(con->ks, buf, 1500);
 
351
      buf[cnt] = 0;
 
352
      parse((CONNECTION *)con, (unsigned char *)buf, cnt);
 
353
      ScreenEm(buf, cnt, con->pScreen);
 
354
      break;
 
355
 
 
356
    case FD_CLOSE:
 
357
      kstream_destroy(con->ks);
 
358
      free(con);
 
359
      con = NULL;
 
360
      WSACleanup();
 
361
      PostQuitMessage(0);
 
362
      break;
 
363
 
 
364
    case FD_CONNECT:
 
365
      ret = WSAGETSELECTERROR(lParam);
 
366
      if (ret) {
 
367
        wsprintf(buf, "Error %d on Connect", ret);
 
368
        MessageBox(NULL, buf, NULL, MB_OK | MB_ICONEXCLAMATION);
 
369
        kstream_destroy(con->ks);
 
370
        free(con);
 
371
        WSACleanup();
 
372
        PostQuitMessage(0);
 
373
        break;
 
374
      }
 
375
      start_negotiation(con->ks);
 
376
      break;            
 
377
    }
 
378
 
 
379
    break;              
 
380
 
 
381
  case WM_HOSTNAMEFOUND:
 
382
    ret = WSAGETASYNCERROR(lParam);
 
383
    if (ret) {
 
384
      wsprintf(buf, "Error %d on GetHostbyName", ret);
 
385
      MessageBox(NULL, buf, NULL, MB_OK | MB_ICONEXCLAMATION);
 
386
      kstream_destroy(con->ks);
 
387
      free(con);
 
388
      WSACleanup();
 
389
      PostQuitMessage(0);
 
390
      break;
 
391
    }
 
392
 
 
393
    remote_host = (struct hostent *)hostdata;
 
394
    remote_addr.sin_family = AF_INET;
 
395
    memcpy(&(remote_addr.sin_addr), &(remote_host->h_addr[0]), 4);
 
396
    remote_addr.sin_port = htons(port_no);
 
397
 
 
398
    connect(con->socket, (struct sockaddr *)&remote_addr, sizeof(struct sockaddr));
 
399
    break;
 
400
 
 
401
  case WM_MYSCREENSIZE:
 
402
    con->width = LOWORD(lParam);                /* width in characters */
 
403
    con->height = HIWORD(lParam);               /* height in characters */
 
404
    if (con->bResizeable && con->ks)
 
405
      send_naws(con);
 
406
    wsprintf(buf, "%d", con->height);
 
407
    WritePrivateProfileString(INI_TELNET, INI_HEIGHT, buf, TELNET_INI);
 
408
    wsprintf(buf, "%d", con->width);
 
409
    WritePrivateProfileString(INI_TELNET, INI_WIDTH, buf, TELNET_INI);
 
410
    break;
 
411
                
 
412
  default:                              /* Passes it on if unproccessed */
 
413
    return(DefWindowProc(hWnd, message, wParam, lParam));
 
414
  }
 
415
  return (0);
 
416
}
 
417
 
 
418
 
 
419
/*
 
420
 *
 
421
 * FUNCTION: SaveHostName(hostname, port)
 
422
 *
 
423
 * PURPOSE: Saves the currently selected host name and port number
 
424
 * in the KERBEROS.INI file and returns the preferred backspace
 
425
 * setting if one exists for that host.
 
426
 *
 
427
 * RETURNS: VK_BACK or 0x7f depending on the desired backspace setting.
 
428
 */
 
429
int
 
430
SaveHostName(char *host, int port)
 
431
{
 
432
  char buf[128];                /* Scratch buffer */
 
433
  char fullhost[128];           /* Host & port combination */
 
434
  char hostName[10][128];       /* Entries from INI files */
 
435
  char *comma;                  /* For parsing del/bs info */
 
436
  int len;                      /* Length of fullhost */
 
437
  int n;                        /* Number of items written */
 
438
  int i;                        /* Index */
 
439
  int bs;                       /* What we return */
 
440
 
 
441
  if (port == 23)                               /* Default telnet port */
 
442
    strcpy(fullhost, host);                     /* ...then don't add it on */
 
443
  else
 
444
    wsprintf(fullhost, "%s %d", host, port);
 
445
  len = strlen(fullhost);
 
446
 
 
447
  comma = NULL;
 
448
  for (i = 0; i < 10; i++) {
 
449
    wsprintf(buf, INI_HOST "%d", i); /* INI item to fetch */
 
450
    GetPrivateProfileString(INI_HOSTS, buf, "", hostName[i], 
 
451
                            128, TELNET_INI);
 
452
 
 
453
    if (!hostName[i][0])
 
454
      break;
 
455
 
 
456
    if (strncmp (hostName[i], fullhost, len))   /* A match?? */
 
457
      continue;                                 /* Nope, keep going */
 
458
    comma = strchr (hostName[i], ',');
 
459
  }
 
460
 
 
461
  if (comma) {
 
462
    ++comma;                                    /* Past the comma */
 
463
    while (*comma == ' ')                       /* Past leading white space */
 
464
      ++comma;
 
465
    bs = VK_BACK;                               /* Default for unknown entry */
 
466
    if (_stricmp(comma, INI_HOST_DEL) == 0)
 
467
      bs = 0x7f;
 
468
  }
 
469
  else {                                        /* No matching entry */
 
470
    GetPrivateProfileString(INI_TELNET, INI_BACKSPACE, INI_BACKSPACE_BS, 
 
471
                            buf, sizeof(buf), TELNET_INI);
 
472
    bs = VK_BACK;                               /* Default value */
 
473
    if (_stricmp(buf, INI_BACKSPACE_DEL) == 0)
 
474
      bs = 0x7f;
 
475
  }
 
476
 
 
477
  /*
 
478
   * Build up default host name
 
479
   */
 
480
  strcpy(buf, fullhost);
 
481
  strcat(buf, ", ");
 
482
  strcat(buf, (bs == VK_BACK) ? INI_BACKSPACE_BS : INI_BACKSPACE_DEL);
 
483
  WritePrivateProfileString(INI_HOSTS, INI_HOST "0", buf, TELNET_INI);
 
484
 
 
485
  n = 0;
 
486
  for (i = 0; i < 10; i++) {
 
487
    if (!hostName[i][0])                        /* End of the list? */
 
488
      break;
 
489
    if (strncmp(hostName[i], fullhost, len) != 0) {
 
490
      wsprintf(buf, INI_HOST "%d", ++n);
 
491
      WritePrivateProfileString(INI_HOSTS, buf, hostName[i], TELNET_INI);
 
492
    }
 
493
  }
 
494
  return(bs);
 
495
}
 
496
 
 
497
 
 
498
int
 
499
OpenTelnetConnection(void)
 
500
{
 
501
  int nReturn, ret;
 
502
  struct sockaddr_in sockaddr;
 
503
  char *p;
 
504
  static struct kstream_crypt_ctl_block ctl;
 
505
  char buf[128];
 
506
 
 
507
  tmpConfig = calloc(sizeof(CONFIG), 1);
 
508
        
 
509
  if (bAutoConnection) {
 
510
    tmpConfig->title = calloc(lstrlen(szHostName), 1);
 
511
    lstrcpy(tmpConfig->title, (char *) szHostName);
 
512
  } else {
 
513
    nReturn = DoDialog("OPENTELNETDLG", OpenTelnetDlg);
 
514
    if (nReturn == FALSE)
 
515
      return(FALSE);
 
516
  }
 
517
                                                
 
518
  con = (CONNECTION *) GetNewConnection();
 
519
  if (con == NULL)
 
520
    return(0);
 
521
 
 
522
  tmpConfig->width =
 
523
    GetPrivateProfileInt(INI_TELNET, INI_WIDTH, DEF_WIDTH, TELNET_INI);
 
524
 
 
525
  tmpConfig->height =
 
526
    GetPrivateProfileInt(INI_TELNET, INI_HEIGHT, DEF_HEIGHT, TELNET_INI);
 
527
  con->width = tmpConfig->width;
 
528
  con->height = tmpConfig->height;
 
529
 
 
530
  con->backspace = SaveHostName(tmpConfig->title, port_no);
 
531
 
 
532
  if (con->backspace == VK_BACK) {
 
533
    tmpConfig->backspace = TRUE;
 
534
    con->ctrl_backspace = 0x7f;
 
535
  } else {
 
536
    tmpConfig->backspace = FALSE;
 
537
    con->ctrl_backspace = 0x08;
 
538
  }
 
539
 
 
540
  tmpConfig->hwndTel = hWnd;
 
541
  con->pScreen = InitNewScreen(tmpConfig);
 
542
  if (!con->pScreen) {
 
543
    assert(FALSE);
 
544
    free(con->pScreen);
 
545
    free(con);
 
546
    free(tmpConfig);
 
547
    return(-1);
 
548
  }
 
549
 
 
550
  ret = (SOCKET) socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
 
551
        
 
552
  if (ret == SOCKET_ERROR) {
 
553
    wsprintf(buf, "Socket error on socket = %d!", WSAGetLastError());
 
554
    MessageBox(NULL, buf, NULL, MB_OK | MB_ICONEXCLAMATION);
 
555
    if (con->pScreen != NULL)
 
556
      DestroyWindow(con->pScreen->hWnd);
 
557
    free(con);
 
558
    free(tmpConfig);
 
559
    return(-1);
 
560
  } 
 
561
        
 
562
  con->socket = ret;
 
563
        
 
564
  sockaddr.sin_family = AF_INET;  
 
565
  sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
 
566
  sockaddr.sin_port = htons(0);
 
567
        
 
568
  ret = bind(con->socket, (struct sockaddr *) &sockaddr, 
 
569
             (int) sizeof(struct sockaddr_in));
 
570
        
 
571
  if (ret == SOCKET_ERROR) {
 
572
    wsprintf(buf, "Socket error on bind!");
 
573
    MessageBox(NULL, buf, NULL, MB_OK | MB_ICONEXCLAMATION);
 
574
    if (con->pScreen != NULL)
 
575
      DestroyWindow(con->pScreen->hWnd);
 
576
    free(con);
 
577
    free(tmpConfig);
 
578
    return(-1);
 
579
  }
 
580
 
 
581
  WSAAsyncSelect(con->socket, hWnd, WM_NETWORKEVENT,
 
582
                 FD_READ | FD_CLOSE | FD_CONNECT);
 
583
 
 
584
  lstrcpy(szHostName, tmpConfig->title);
 
585
  p = strchr(szHostName, '@');
 
586
  if (p != NULL) {
 
587
    *p = 0;
 
588
    strcpy (szUserName, szHostName);
 
589
    strcpy(szHostName, ++p);
 
590
  }
 
591
 
 
592
  WSAAsyncGetHostByName(hWnd, WM_HOSTNAMEFOUND, szHostName, hostdata, 
 
593
                        MAXGETHOSTSTRUCT);
 
594
 
 
595
  ctl.encrypt = auth_encrypt;
 
596
  ctl.decrypt = auth_decrypt;
 
597
  ctl.init = auth_init;
 
598
  ctl.destroy = auth_destroy;
 
599
 
 
600
  con->ks = kstream_create_from_fd(con->socket, &ctl, NULL);
 
601
 
 
602
  if (con->ks == NULL)
 
603
    return(-1);
 
604
 
 
605
  kstream_set_buffer_mode(con->ks, 0);
 
606
 
 
607
  return(1);
 
608
}
 
609
 
 
610
 
 
611
CONNECTION *
 
612
GetNewConnection(void)
 
613
{
 
614
  CONNECTION *pCon;
 
615
 
 
616
  pCon = calloc(sizeof(CONNECTION), 1);
 
617
  if (pCon == NULL)
 
618
    return NULL;
 
619
  pCon->backspace = TRUE;
 
620
  pCon->bResizeable = TRUE;
 
621
  return(pCon);
 
622
}
 
623
 
 
624
 
 
625
int
 
626
DoDialog(char *szDialog, DLGPROC lpfnDlgProc)
 
627
{
 
628
  int nReturn;
 
629
        
 
630
  nReturn = DialogBox(hInst, szDialog, hWnd, lpfnDlgProc);
 
631
  return (nReturn);
 
632
}
 
633
 
 
634
 
 
635
/*
 
636
 * FUNCTION: OpenTelnetDlg(HWND, unsigned, WORD, LONG)
 
637
 *
 
638
 * PURPOSE:  Processes messages for "Open New Telnet Connection" dialog box
 
639
 *
 
640
 * MESSAGES:
 
641
 *
 
642
 * WM_INITDIALOG - initialize dialog box
 
643
 * WM_COMMAND    - Input received
 
644
 */
 
645
INT_PTR CALLBACK
 
646
OpenTelnetDlg(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
 
647
{
 
648
  char szConnectName[256];
 
649
  HDC hDC;
 
650
  int xExt, yExt;
 
651
  DWORD Ext;
 
652
  HWND hEdit;
 
653
  int n;
 
654
  int iHostNum = 0;
 
655
  char tmpName[128];
 
656
  char tmpBuf[80];
 
657
  char *tmpCommaLoc;
 
658
        
 
659
  switch (message) {
 
660
  case WM_INITDIALOG:
 
661
    hDC = GetDC(hDlg);
 
662
    Ext = GetDialogBaseUnits();
 
663
    xExt = (190 *LOWORD(Ext)) /4 ;
 
664
    yExt = (72 * HIWORD(Ext)) /8 ;
 
665
    GetPrivateProfileString(INI_HOSTS, INI_HOST "0", "", tmpName, 
 
666
                            128, TELNET_INI);
 
667
    if (tmpName[0]) {
 
668
      tmpCommaLoc = strchr(tmpName, ',');
 
669
      if (tmpCommaLoc)
 
670
        *tmpCommaLoc = '\0';
 
671
      SetDlgItemText(hDlg, TEL_CONNECT_NAME, tmpName);
 
672
    }   
 
673
    hEdit = GetWindow(GetDlgItem(hDlg, TEL_CONNECT_NAME), GW_CHILD);
 
674
    while (TRUE) {
 
675
      wsprintf(tmpBuf, INI_HOST "%d", iHostNum++);
 
676
      GetPrivateProfileString(INI_HOSTS, tmpBuf, "", tmpName, 
 
677
                              128, TELNET_INI);
 
678
      tmpCommaLoc = strchr(tmpName, ',');  
 
679
      if (tmpCommaLoc)
 
680
        *tmpCommaLoc = '\0';
 
681
      if (tmpName[0])
 
682
        SendDlgItemMessage(hDlg, TEL_CONNECT_NAME, CB_ADDSTRING, 0, 
 
683
                           (LPARAM) ((LPSTR) tmpName));
 
684
      else
 
685
        break;
 
686
    }
 
687
#ifdef FORWARD
 
688
    EnableWindow(GetDlgItem(hDlg, IDC_FORWARD), 1);
 
689
    SendDlgItemMessage(hDlg, IDC_FORWARD, BM_SETCHECK, forward_flag, 0);
 
690
    if (forward_flag)
 
691
      EnableWindow(GetDlgItem(hDlg, IDC_FORWARDFORWARD), 1);
 
692
    else
 
693
      EnableWindow(GetDlgItem(hDlg, IDC_FORWARDFORWARD), 0);
 
694
    SendDlgItemMessage(hDlg, IDC_FORWARDFORWARD, BM_SETCHECK,
 
695
                       forwardable_flag, 0);
 
696
#endif
 
697
 
 
698
#ifdef ENCRYPTION
 
699
    EnableWindow(GetDlgItem(hDlg, IDC_ENCRYPT), 1);
 
700
    SendDlgItemMessage(hDlg, IDC_ENCRYPT,
 
701
                       BM_SETCHECK, encrypt_flag, 0);
 
702
#endif
 
703
 
 
704
    EnableWindow(GetDlgItem(hDlg, TEL_CONNECT_USERID), 1);
 
705
 
 
706
    SetWindowPos(hDlg, NULL,
 
707
                 (GetSystemMetrics(SM_CXSCREEN)/2)-(xExt/2),
 
708
                 (GetSystemMetrics(SM_CYSCREEN)/2)-(yExt/2),
 
709
                 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW);
 
710
    ReleaseDC(hDlg, hDC);      
 
711
    SendMessage(hEdit, WM_USER + 1, 0, 0);
 
712
    SendMessage(hDlg, WM_SETFOCUS, 0, 0);
 
713
    return (TRUE);
 
714
 
 
715
  case WM_COMMAND:
 
716
    switch (wParam) {
 
717
    case TEL_CANCEL:
 
718
    case IDCANCEL:                      /* From the menu */
 
719
      EndDialog(hDlg, FALSE);
 
720
      break;
 
721
 
 
722
#ifdef FORWARD
 
723
    case IDC_FORWARD:
 
724
      forward_flag = (BOOL)SendDlgItemMessage(hDlg, IDC_FORWARD,
 
725
                                              BM_GETCHECK, 0, 0);
 
726
      if (forward_flag)
 
727
        EnableWindow(GetDlgItem(hDlg, IDC_FORWARDFORWARD), 1);
 
728
      else
 
729
        EnableWindow(GetDlgItem(hDlg, IDC_FORWARDFORWARD), 0);
 
730
      break;
 
731
                                
 
732
    case IDC_FORWARDFORWARD:
 
733
      forwardable_flag = (BOOL)SendDlgItemMessage(hDlg, IDC_FORWARDFORWARD,
 
734
                                                  BM_GETCHECK, 0, 0);
 
735
      break;
 
736
#endif
 
737
 
 
738
#if ENCRYPTION
 
739
    case IDC_ENCRYPT:
 
740
      encrypt_flag = (BOOL)SendDlgItemMessage(hDlg, IDC_ENCRYPT,
 
741
                                              BM_GETCHECK, 0, 0);
 
742
      break;
 
743
#endif
 
744
    case TEL_CONNECT_USERID:
 
745
      GetDlgItemText(hDlg, TEL_CONNECT_USERID, szUserName, sizeof(szUserName));
 
746
      break;
 
747
 
 
748
    case TEL_OK:
 
749
      GetDlgItemText(hDlg, TEL_CONNECT_NAME, szConnectName, 256);
 
750
                        
 
751
      n = parse_cmdline (szConnectName);
 
752
      if (! n) {
 
753
        MessageBox(hDlg, "You must enter a session name!",
 
754
                   NULL, MB_OK);
 
755
        break;
 
756
      }
 
757
      tmpConfig->title = calloc(lstrlen(szHostName) + 1, 1);
 
758
      lstrcpy(tmpConfig->title, szConnectName);
 
759
      EndDialog(hDlg, TRUE);
 
760
      break;
 
761
    }                
 
762
    return (FALSE);                    
 
763
  }
 
764
  return(FALSE);
 
765
}
 
766
 
 
767
 
 
768
/*
 
769
 *
 
770
 * FUNCTION: TelnetSend(kstream ks, char *buf, int len, int flags)
 
771
 *
 
772
 * PURPOSE:     This is a replacement for the WinSock send() function, to
 
773
 *              send a buffer of characters to an output socket.  It differs
 
774
 *              by retrying endlessly if sending the bytes would cause
 
775
 *              the send() to block.  <gnu@cygnus.com> observed EWOULDBLOCK
 
776
 *              errors when running using TCP Software's PC/TCP 3.0 stack, 
 
777
 *              even when writing as little as 109 bytes into a socket
 
778
 *              that had no more than 9 bytes queued for output.  Note also
 
779
 *              that a kstream is used during output rather than a socket
 
780
 *              to facilitate encryption.
 
781
 *
 
782
 *              Eventually, for cleanliness and responsiveness, this
 
783
 *              routine should not loop; instead, if the send doesn't
 
784
 *              send all the bytes, it should put them into a buffer
 
785
 *              and return.  Message handling code would send out the
 
786
 *              buffer whenever it gets an FD_WRITE message.
 
787
 */
 
788
int
 
789
TelnetSend(kstream ks, char *buf, int len, int flags)
 
790
{
 
791
  int writelen;
 
792
  int origlen = len;
 
793
 
 
794
  while (TRUE) {
 
795
    writelen = kstream_write(ks, buf, len);
 
796
 
 
797
    if (writelen == len)           /* Success, first or Nth time */
 
798
      return (origlen);
 
799
 
 
800
    if (writelen == SOCKET_ERROR) {
 
801
      if (WSAGetLastError() != WSAEWOULDBLOCK)
 
802
        return (SOCKET_ERROR);  /* Some error */
 
803
      /* For WOULDBLOCK, immediately repeat the send. */
 
804
    }
 
805
    else {
 
806
      /* Partial write; update the pointers and retry. */
 
807
      len -= writelen;
 
808
      buf += writelen;
 
809
    }
 
810
  }
 
811
}
 
812
 
 
813
 
 
814
/*
 
815
 * Function: Trim leading and trailing white space from a string.
 
816
 *
 
817
 * Parameters:
 
818
 *      s - the string to trim.
 
819
 */
 
820
void
 
821
trim(char *s)
 
822
{
 
823
  int l;
 
824
  int i;
 
825
 
 
826
  for (i = 0; s[i]; i++)
 
827
    if (s[i] != ' ' && s[i] != '\t')
 
828
      break;
 
829
 
 
830
  l = strlen(&s[i]);
 
831
  memmove(s, &s[i], l + 1);
 
832
 
 
833
  for (l--; l >= 0; l--) {
 
834
    if (s[l] != ' ' && s[l] != '\t')
 
835
      break;
 
836
  }
 
837
  s[l + 1] = 0;
 
838
}
 
839
 
 
840
 
 
841
/*
 
842
 * 
 
843
 * Parse_cmdline
 
844
 * 
 
845
 * Reads hostname and port number off the command line.
 
846
 *
 
847
 * Formats: telnet
 
848
 *          telnet <host>
 
849
 *          telnet <host> <port no>
 
850
 *          telnet -p <port no>
 
851
 *
 
852
 * Returns: TRUE if we have a hostname
 
853
 */
 
854
BOOL
 
855
parse_cmdline(char *cmdline)
 
856
{
 
857
  char *ptr;
 
858
        
 
859
  *szHostName = '\0';                 /* Nothing yet */
 
860
  if (*cmdline == '\0')               /* Empty command line? */
 
861
    return(FALSE);
 
862
 
 
863
  trim (cmdline);                     /* Remove excess spaces */
 
864
  ptr = strchr (cmdline, ' ');        /* Find 2nd token */
 
865
 
 
866
  if (ptr != NULL) {                  /* Port number given */
 
867
    *ptr++ = '\0';                  /* Separate into 2 words */
 
868
    port_no = atoi (ptr);
 
869
  }
 
870
 
 
871
  if (*cmdline != '-' && *cmdline != '/') {   /* Host name given */
 
872
    lstrcpy (szHostName, cmdline);
 
873
    return(TRUE);
 
874
  }
 
875
 
 
876
  return(FALSE);
 
877
}
 
878
 
 
879
#ifdef DEBUG
 
880
void
 
881
hexdump(char *msg, unsigned char *st, int cnt)
 
882
{
 
883
  int i;
 
884
  char strTmp[128];
 
885
 
 
886
  OutputDebugString("\r\n");
 
887
  if (msg != NULL) {
 
888
    OutputDebugString(msg);
 
889
    OutputDebugString("\r\n");
 
890
  }
 
891
  for(i = 0 ; i < cnt ; i++) {
 
892
    int j;
 
893
 
 
894
    for(j = 0 ; (j < 16) && ((i + j) < cnt) ; j++) {
 
895
      wsprintf(strTmp,"%02x  ", st[i + j]);
 
896
      if (j == 8)
 
897
        OutputDebugString("| ");
 
898
      OutputDebugString(strTmp);
 
899
    }    
 
900
    i += j - 1;
 
901
    OutputDebugString("\r\n");
 
902
  } /* end for */
 
903
}
 
904
#endif