Source file: /~heha/hs/finger.zip/SRC/FING32.C

#include <windows.h>
#include <stdio.h>
MSG Message;
HWND Window;
char s[256];
DWORD LastErr;
DWORD RegErr;
ATOM Atom;
HINSTANCE HInstance;
HWND hEdit;
HICON icClosed, icOpen;	
/* Icon-Handles für geschlossene und geöffnete Mailbox */
#define Klasse "hohO"
#define DEFAULT_SECTION "Finger Default"
#define WM_TRAYNOTIFY (WM_USER+10)
#define LoadIcon(x,y) LoadImage(x,y,IMAGE_ICON,GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),0)
char HelpFileName[]="FING32.HLP";
char IniName[]="FINGER.INI";
/* Die Konfigurationsvariablen, schön statisch! */
char Sektion[32]=DEFAULT_SECTION;
char Username[32];
char Servername[32];
char SearchString[256];
char ExecName[260];
UINT Delay;
UINT SRFlags;
UINT ExecCmd;
char FingerString[4096];	/* Platz für die gesamte Antwort */
struct hostent *Remote_Host=NULL;

HMENU TrayMenu;
HANDLE ThreadHandle;
DWORD ThreadID;

/* INI-Datei beharken */
void LoadSettings(LPCSTR Section){
 GetPrivateProfileString(Section,"User","[user]",Username,sizeof(Username),IniName);
 GetPrivateProfileString(Section,"Host","[host]",Servername,sizeof(Servername),IniName);
 Delay=GetPrivateProfileInt(Section,"Delay",15,IniName);
 GetPrivateProfileString(Section,"Match","New Mail",SearchString,sizeof(SearchString),IniName);
 SRFlags=GetPrivateProfileInt(Section,"MatchFlags",0,IniName);
 GetPrivateProfileString(Section,"Command","",ExecName,sizeof(ExecName),IniName);
 ExecCmd=GetPrivateProfileInt(Section,"ExecShow",SW_SHOWNORMAL,IniName);
}

BOOL WritePrivateProfileStringEvtl(LPCSTR Section,LPCSTR Key,LPCSTR Value,
  LPCSTR DefVal,LPCSTR IniName){
 if (!lstrcmpi(Value,DefVal)){
  return WritePrivateProfileString(Section,Key,NULL,IniName);
 }else{
  return WritePrivateProfileString(Section,Key,Value,IniName);
 }
}

void SaveSettings(LPCSTR Section){
 char S[8];
 WritePrivateProfileString(Section,"User",Username,IniName);
 WritePrivateProfileString(Section,"Host",Servername,IniName);
 WritePrivateProfileStringEvtl(Section,"Match",SearchString,
   "New Mail",IniName);
 wsprintf(S,"%d",SRFlags);
 WritePrivateProfileStringEvtl(Section,"MatchFlags",S,"0",IniName);
 wsprintf(S,"%d",Delay);
 WritePrivateProfileStringEvtl(Section,"Delay",S,"15",IniName);
 WritePrivateProfileStringEvtl(Section,"Command",ExecName,"",IniName);
 wsprintf(S,"%d",ExecCmd);
 WritePrivateProfileStringEvtl(Section,"ExecShow",S,"1",IniName);
 /* 1 ist SW_SHOWNORMAL */
}

/* Dialogfensterprozedur FINGER-Konfiguration */
BOOL CALLBACK KonfProc(HWND Window, UINT Message,
  WPARAM wParam, LPARAM lParam){
 FILE *f;	/* jawohl: INI-Datei muß von Hand beackert werden! */
 char Line[256];
 char *SP1,*SP2;
 UINT Nummer;
 BOOL Boo;
#define WM_SETEDITS (WM_USER+101)
 static DWORD Anzahl=0;

 switch (Message){
  case WM_INITDIALOG:
   Nummer=GetWindowsDirectory(Line,sizeof(Line));
   if (Line[Nummer-1]!='\\'){
    Line[Nummer]='\\';
    Line[Nummer+1]='\0';
   }
   lstrcat(Line,IniName);
   Anzahl=0; Boo=FALSE;
/* "Boo" protokolliert hier das Vorhandensein von "Finger Default" */
   f=fopen(Line,"r");
   if (f){
    while (fgets(Line,sizeof(Line),f)){	/* solange nicht EOF */
     SP1=strchr(Line,'[');
     if (SP1){
      SP1++;	/* Startpunkt festlegen */
      SP2=strchr(SP1,']');
      if (SP2){
       *SP2='\0';	/* String terminieren */
       if (!lstrcmpi(SP1,DEFAULT_SECTION)) Boo=TRUE;
       SendDlgItemMessage(Window,101,CB_ADDSTRING,0,(LPARAM)SP1);
       if (!lstrcmpi(SP1,Sektion)){
        SendDlgItemMessage(Window,101,CB_SETCURSEL,Anzahl,0);
       }
       Anzahl++;
      }/*if*/
     }/*if*/;
    }/*while*/;
    fclose(f);
   }/*if*/;
   if (!Boo){
    SendDlgItemMessage(Window,101,CB_ADDSTRING,0,(LPARAM)DEFAULT_SECTION);
    if (!lstrcmpi(DEFAULT_SECTION,Sektion)){
     SendDlgItemMessage(Window,101,CB_SETCURSEL,Anzahl,0);
    }
    Anzahl++;
   }
   SendMessage(Window,WM_SETEDITS,0,(LPARAM)Sektion);	/* SetEdit */
   return FALSE;

  case WM_SETEDITS:	/* SetEdit's, lParam=Sektions-Name */
    SetDlgItemText(Window,102,Username);
    SetDlgItemText(Window,103,Servername);
    SetDlgItemInt(Window,104,Delay,FALSE);
    SetDlgItemText(Window,105,SearchString);
    CheckDlgButton(Window,108,SRFlags);
    SetDlgItemText(Window,106,ExecName);
    CheckDlgButton(Window,109,ExecCmd==SW_SHOWNORMAL?0:1);
    EnableWindow(GetDlgItem(Window,107),
      lstrcmpi((LPCSTR)lParam,"Finger Default")?TRUE:FALSE);
    return FALSE;

  case WM_COMMAND:
    switch LOWORD(wParam){
     case 101: /* Combobox */
      if (HIWORD(wParam)==CBN_SELCHANGE){
       /*Neue Selektion: Strings neu setzen */
       Nummer=SendDlgItemMessage(Window,101,CB_GETCURSEL,0,0);
       SendDlgItemMessage(Window,101,CB_GETLBTEXT,Nummer,(LPARAM)Line);
       LoadSettings(Line);	/* Ini-Teil laden */
       SendMessage(Window,WM_SETEDITS,0,(LPARAM)Line);	/* Alle Felder neu setzen */
      }
      break;

     case 1:	/* OK-Taste: Abspeichern */
      Delay=GetDlgItemInt(Window,104,&Boo,FALSE);
      if (!Boo){
       SetFocus(GetDlgItem(Window,104));
       return FALSE;
      }
      GetDlgItemText(Window,101,Sektion,sizeof(Sektion));
      GetDlgItemText(Window,102,Username,sizeof(Username));
      GetDlgItemText(Window,103,Servername,sizeof(Servername));
      GetDlgItemText(Window,105,SearchString,sizeof(SearchString));
      SRFlags=IsDlgButtonChecked(Window,108);
      GetDlgItemText(Window,106,ExecName,sizeof(ExecName));
      ExecCmd=IsDlgButtonChecked(Window,109)?SW_MINIMIZE
        :SW_SHOWNORMAL;	/* wenn nicht markiert */
      if (lstrlen(Sektion)){ /* und nur benamstes speichern! */
       SaveSettings(Sektion);	/* Ini-Sektion speichern */
      }	
      EndDialog(Window,TRUE);
      break;

     case 2:	/* ID_CANCEL */
      LoadSettings(Sektion);	/* Ini laden ??? (unsauber) */
      EndDialog(Window,FALSE);
      break;

     case 107: /* Taste "Löschen" */
      Nummer=SendDlgItemMessage(Window,101,CB_GETCURSEL,0,0);
      SendDlgItemMessage(Window,101,CB_GETLBTEXT,Nummer,(LPARAM)Line);
      WritePrivateProfileString(Line,NULL,NULL,IniName);
      	/* aus der .INI löschen */
      SendDlgItemMessage(Window,101,CB_DELETESTRING,Nummer,0);
      	/* aus der Liste löschen */
      break;

     case 9:
      WinHelp(Window,HelpFileName,HELP_CONTEXT,102);
      break;
    }/*switch LOWORD(wParam)*/
    return FALSE;
  }/*switch Message*/
  return FALSE;
}

BOOL CALLBACK AboutProc(HWND Window, UINT Message,
  WPARAM wParam, LPARAM lParam){
 switch (Message){
  case WM_COMMAND:
  switch LOWORD(wParam){
   case IDOK:
   case IDCANCEL:
   EndDialog(Window,1);
  }
 }
 return FALSE;
}

DWORD CALLBACK FingerThread(LPVOID Window){
 WSADATA wd;
/* struct hostent *Remote_Host; GLOBAL */
 struct sockaddr_in Remote_Addr;
 SOCKET FingerSocket;
 char S[32],*SP;
 int rc,NochFrei;

 WSAStartup(0x101,&wd);
 Remote_Host=gethostbyname(Servername);
 if (Remote_Host){
  PostMessage((HWND)Window,WM_USER+11,0,0);
/* Melde Server-Verbindung OK! */
  for(;;){
   FingerSocket=socket(PF_INET, SOCK_STREAM, IPPROTO_IP);
   if (FingerSocket!=INVALID_SOCKET){
    memset(&Remote_Addr,0,sizeof(Remote_Addr));
    Remote_Addr.sin_family=PF_INET;
    Remote_Addr.sin_port=htons(79);
    memcpy(&Remote_Addr.sin_addr,Remote_Host->h_addr,
      Remote_Host->h_length);
    if (!connect(FingerSocket,(struct sockaddr *)&Remote_Addr,
      sizeof(Remote_Addr))){
     rc=wsprintf(S,"%s\r\n",Username);
     if (send(FingerSocket,S,rc,0)==rc){
      SP=FingerString; NochFrei=sizeof(FingerString)-1;
      do{
       rc=recv(FingerSocket,SP,NochFrei,0);
       if (rc==SOCKET_ERROR) break;
       SP+=rc;
       NochFrei-=rc;
      }while (rc);
      *SP='\0';		/* terminieren */
      PostMessage((HWND)Window,WM_USER+12,0,0);
/* Melde erfolgreich geFINGERt! */
     }
     closesocket(FingerSocket);
    }
   }
   Sleep(Delay*1000);
  }
 }
 return 0;
}

BOOL HaveMail(){
/* liefert TRUE, wenn Zeichenkette enthalten */
 char *SP1,*SP2,*SP3;
 if (!SearchString[0] || !FingerString[0])
  return FALSE;
 if (SRFlags & 1){	/* case-sensitiv */
  return strstr(FingerString,SearchString) ? TRUE : FALSE;
 }else{		/* case-insensitiv */
  SP1=strdup(SearchString); strlwr(SP1);
  SP2=strdup(FingerString); strlwr(SP2);
  SP3=strstr(SP2,SP1);
  free(SP1);
  free(SP2);
  return SP3 ? TRUE : FALSE;
 }
}

static NOTIFYICONDATA fData={
  /*cbSize:*/ sizeof(NOTIFYICONDATA),
  /*Wnd:*/ 0,
  /*uID:*/ 100,
  /*uFlags:*/ NIF_MESSAGE|NIF_ICON|NIF_TIP,
  /*uCallbackMessage:*/ WM_USER+10,
  /*hIcon:*/ 0,
  /*szTip:*/ "Fing32 Mail Checker (01/97)"};

/* Fensterprozedur des Hauptfensters [meist unsichtbar] */
LRESULT CALLBACK ShowStringProc(HWND Window, UINT Message,
  WPARAM wParam, LPARAM lParam){

 switch (Message){
  case WM_CREATE:
   hEdit=CreateWindowEx(0,"EDIT","",
     WS_CHILD|WS_VSCROLL|WS_VISIBLE|ES_AUTOVSCROLL|
     /*ES_READONLY|*/ES_MULTILINE,0,0,
     ((CREATESTRUCT *)lParam)->cx,
     ((CREATESTRUCT *)lParam)->cy,
     Window,0,HInstance,NULL);
   SendMessage(hEdit,WM_SETFONT,(WPARAM)GetStockObject(ANSI_FIXED_FONT),0);
   ThreadHandle=CreateThread(NULL,0x4000,FingerThread,(LPVOID)Window,0,&ThreadID);
   break;

  case WM_SIZE:
   SetWindowPos(hEdit,0,0,0,LOWORD(lParam),HIWORD(lParam),SWP_NOZORDER);
   break;

  case WM_TRAYNOTIFY:
   if (lParam==WM_RBUTTONUP){
    POINT point;
    HMENU PopMenu=GetSubMenu(TrayMenu,0);
    CheckMenuItem(PopMenu,202,MF_BYCOMMAND|
      (FingerString[0] ? MF_CHECKED : MF_UNCHECKED));
    CheckMenuItem(PopMenu,203,MF_BYCOMMAND|
      (Remote_Host ? MF_CHECKED : MF_UNCHECKED));
    GetCursorPos(&point);
    TrackPopupMenu(PopMenu,
      TPM_CENTERALIGN|TPM_RIGHTBUTTON,
      point.x,point.y,0,Window,NULL);
   }
   break;

  case WM_USER+11:
/*   MessageBox(Window,"Melde: Erfolgreich mit Server verbunden!","HURRA!",MB_OK);*/
   break;

  case WM_USER+12:
   SetWindowText(hEdit,FingerString);
/*   MessageBox(Window,"Melde: Erfolgreich geFINGERt!","HURRA!",MB_OK);*/
   if (HaveMail()){
    if (fData.hIcon!=icOpen){
     fData.hIcon=icOpen;	/* Fähnchen hoch! */
     lstrcpy(fData.szTip,Sektion);
     lstrcat(fData.szTip," (Mail!)");
     Shell_NotifyIcon(NIM_MODIFY,&fData);
     MessageBeep(0);
     if (ExecName[0]){
      UINT rc;
      char S[256];
      if (!lstrcmpi(ExecName+lstrlen(ExecName)-4,".WAV")){
       if (!PlaySound(ExecName,NULL,SND_ASYNC)){
        MessageBeep(MB_ICONEXCLAMATION);
        wsprintf(S,"Fehler beim Abspielen der Sound-Datei \"%s\"!",
          ExecName);
        MessageBox(Window,S,NULL,MB_OK|MB_ICONEXCLAMATION);
       }
      }else{
       rc=WinExec(ExecName,ExecCmd);
       if (rc<32){
        wsprintf(S,"Fehler Code %d beim Starten der Anwendung \"%s\"",
          rc,ExecName);
        MessageBox(Window,S,NULL,MB_OK);
       }
      }
     }
    }
   }else{
    if (fData.hIcon!=icClosed){
     fData.hIcon=icClosed;	/* Fähnchen 'runter */
     lstrcpy(fData.szTip,Sektion);
     lstrcat(fData.szTip," (No Mail)");
     Shell_NotifyIcon(NIM_MODIFY,&fData);
    }
   }
   break;

  case WM_COMMAND:
   switch LOWORD(wParam){
    case 9:
     WinHelp(Window,HelpFileName,HELP_CONTENTS,0);
     break;
    case 201: /* FINGER-Konfiguration via FINGER.INI */
     if (!TerminateThread(ThreadHandle,0)){
      MessageBox(Window,"TerminateThread versagt!",NULL,MB_OK);
     };
     ThreadHandle=0;
     Remote_Host=NULL;
     if (DialogBoxParam(HInstance,MAKEINTRESOURCE(201),Window,KonfProc,0)){
      FingerString[0]='\0';	/* Finger-String vernichten */
      SetWindowText(hEdit,FingerString);
      fData.hIcon=icClosed;	/* Fähnchen 'runter */
      lstrcpy(fData.szTip,Sektion);
      lstrcat(fData.szTip," (No Mail)");
      Shell_NotifyIcon(NIM_MODIFY,&fData);
     }
     ThreadHandle=CreateThread(NULL,0x4000,FingerThread,(LPVOID)Window,0,&ThreadID);
     break;

    case 202: /* Letzter Finger-String */
     ShowWindow(Window,SW_RESTORE);
     break;

    case 203: /* Server-Info */
     {
      char S[256];
      if (Remote_Host){
       wsprintf(S,"Server: %s\nIP-Adresse: %s",
         Remote_Host->h_name,
         inet_ntoa(*(struct in_addr *)Remote_Host->h_addr) );
      }else{
       wsprintf(S,"Keine Zuordnung zum Server %s"
         "via gethostbyname() gefunden,\n"
         "WSAGetLastError() liefert Fehlercode %d!",
         Servername,
         WSAGetLastError);
      };
      MessageBox(Window,S,"Server-Info",MB_OK);
     }
     break;

    case 800: /* Programm beenden */
     TerminateThread(ThreadHandle,0);
     DestroyWindow(Window);
     PostQuitMessage(0);
     break;

    case 909: /* About-Dialogfenster ausgeben */
     DialogBoxParam(HInstance,MAKEINTRESOURCE(909),Window,AboutProc,0);
     break;
   }
   break;

  case WM_CLOSE: /* Fenster nicht schließen, nur verbergen! */
   ShowWindow(Window,SW_HIDE);
   break;

  default:
   return DefWindowProc(Window,Message,wParam,lParam);
 }/*switch*/
}

static WNDCLASS wc={
  /*style:*/ CS_VREDRAW|CS_HREDRAW|CS_BYTEALIGNCLIENT,
  /*lpfnWndProc:*/ ShowStringProc,
  /*cbClsExtra:*/ 0,
  /*cbWndExtra:*/ 0,
  /*hInstance:*/ 0,
  /*hIcon:*/ 0,
  /*hCursor:*/ 0,
  /*hbrBackground:*/ COLOR_BACKGROUND+1,
  /*lpszMenuName:*/ NULL,
  /*lpszClassName:*/ Klasse};

char Titel[32];

static CREATESTRUCT cs={
  /*lpCreateParams:*/ NULL,
  /*hInstance:*/ 0,
  /*hMenu:*/ 0,
  /*hwndParent:*/ 0,
  /*cy:*/ CW_USEDEFAULT,
  /*cx:*/ CW_USEDEFAULT,
  /*y:*/ CW_USEDEFAULT,
  /*x:*/ CW_USEDEFAULT,
  /*style:*/ WS_OVERLAPPEDWINDOW,
  /*lpszName:*/ Titel,
  /*lpszClass:*/ Klasse,
  /*dwExStyle:*/ 0};

/* Hier geht's los: */
int WINAPI WinMain(HINSTANCE  hInstance,
    HINSTANCE  hPrevInstance,
    LPSTR  lpszCmdLine,
    int  nCmdShow)	{
 LOGFONT LogFont;
 HInstance=hInstance;		/* global machen */
 if (LOBYTE(LOWORD(GetVersion()))<4){
  MessageBox(0,"Dieses Programm benötigt Windows95\n"
    "oder Windows NT 4.0, pardon!",NULL,MB_OK);
  exit(-1);
 }
 TrayMenu=LoadMenu(HInstance,MAKEINTRESOURCE(100));
 if (lstrlen(lpszCmdLine)){
  lstrcpy(Sektion,lpszCmdLine);
 }
 LoadSettings(Sektion);

 wc.hInstance=HInstance;
 wc.hIcon=LoadIcon(0,IDI_ASTERISK);
 wc.hCursor=LoadCursor(0,IDC_ARROW);
 RegisterClass(&wc);
 RegErr=GetLastError();
 cs.hInstance=hInstance;
/* Ursprüngliche Fenstergröße für 80x8 Zeichen setzen */
 GetObject(GetStockObject(ANSI_FIXED_FONT),sizeof(LOGFONT),&LogFont);
 cs.cx=abs(LogFont.lfWidth)*80+2*GetSystemMetrics(SM_CXBORDER);
 cs.cy=abs(LogFont.lfHeight)*8+2*GetSystemMetrics(SM_CYBORDER)
   +GetSystemMetrics(SM_CYCAPTION);
 LoadString(HInstance,1004,Titel,sizeof(Titel));
 Window=CreateWindowEx(0,cs.lpszClass,cs.lpszName,
    cs.style,cs.x,cs.y,cs.cx,cs.cy,
    cs.hwndParent,cs.hMenu,cs.hInstance,&cs);
/* Window=CreateDialogParam(hInstance,MAKEINTRESOURCE(202),
   0,ShowStringProc,0);*/
/* wsprintf(s,"Fensterhandle=%d\n"
   "Letzter Fehler=%d\n"
   "Register-Fehler=%u\n"
   "TrayMenu-Handle=%d\n",Window,GetLastError(),RegErr,TrayMenu);
 MessageBox(0,s,"Fing32",0);*/
 icClosed=LoadIcon(hInstance,MAKEINTRESOURCE(100));
 icOpen=LoadIcon(hInstance,MAKEINTRESOURCE(101));
 fData.hWnd=Window;
 fData.hIcon=icClosed;
 Shell_NotifyIcon(NIM_ADD,&fData);
 while (GetMessage(&Message,0,0,0)){
  TranslateMessage(&Message);
  DispatchMessage(&Message);
 }
 Shell_NotifyIcon(NIM_DELETE,&fData);
 return Message.wParam;
}
Detected encoding: ANSI (CP1252)4
Wrong umlauts? - Assume file is ANSI (CP1252) encoded