home *** CD-ROM | disk | FTP | other *** search
- /*
-
- Answering Machine
-
- */
-
- #include "netfone.h"
-
- #define answerBufferSize 2048 // Buffer for reading message file
-
- #ifdef answerBufferSize
- static char answerBuffer[answerBufferSize];
- #endif
-
- char answerFileName[MAX_PATH] = ""; // Answering machine file name
- int answerRecord = TRUE; // Record incoming messages
-
- static FILE *answerFile = NULL; // Answering machine file descriptor
- static long answerLen; // Length of answering machine file
- static long answerPlayPos; // Current replay address
- static int replaying = FALSE; // Nonzero when replay is active
- static int currentMessage; // Current message being replayed
- static time_t lastPacket = 0; // Time of last packet recorded
-
- static long FAR *msgTable = NULL; // Pointers to messages in file
- static int msgMax = 0; // Message table size
- static int msgCount = 0; // Messages currently in table
-
- #define newMessageCriterion 2 // Gap length, in seconds, defining a new message
-
- /* SETMESSAGECOUNT -- If answering machine is displayed, update the
- number of messages in the file. */
-
- static void setMessageCount(void)
- {
- if (hDlgAnswer != NULL) {
- char mno[24];
-
- if (currentMessage >= 0) {
- wsprintf(mno, Format(42), currentMessage + 1, msgCount);
- } else {
- if (msgCount > 1) {
- wsprintf(mno, Format(43), msgCount);
- } else {
- strcpy(mno, msgCount == 1 ? rstring(IDS_T_ONE_MESSAGE) :
- rstring(IDS_T_NO_MESSAGES));
- }
- }
- SetDlgItemText(hDlgAnswer, IDC_RP_MSGBOX, mno);
- }
- }
-
- // GROWMESSAGETABLE -- Expand in-memory message table if needed
-
- static int growMessageTable(HWND hwnd, int currentMessage)
- {
- if (currentMessage >= msgMax) {
- msgMax += 50;
- msgTable = GlobalReAllocPtr(msgTable, msgMax * sizeof(long), 0);
- if (msgTable == NULL) {
- MessageBox(hwnd, rstring(IDS_T_EXPAND_MSG_TABLE_ERR),
- NULL, MB_OK | MB_ICONEXCLAMATION);
- return FALSE;
- }
- }
- return TRUE;
- }
-
- /* ANSWEROPEN -- Open the answering machine file. */
-
- int answerOpen(void)
- {
- answerFile = fopen(answerFileName, "r+b");
- if (answerFile == NULL) {
- answerFile = fopen(answerFileName, "w+b");
- }
- if (answerFile != NULL) {
- #ifdef answerBufferSize
- setvbuf(answerFile, answerBuffer, _IOFBF, sizeof answerBuffer);
- #endif
- fseek(answerFile, 0L, 2);
- answerLen = ftell(answerFile);
- rewind(answerFile);
- }
- replaying = FALSE;
- return answerFile != NULL;
- }
-
- // ANSWERENABLED -- Determine if recording messages is possible
-
- int answerEnabled(void)
- {
- return answerFile != NULL;
- }
-
- /* ANSWERSAVE -- If the answering machine is on, save a sound
- buffer in the answering machine file. */
-
- void answerSave(struct in_addr IPaddr, LPSTR hostName, soundbuf *sb)
- {
- if (answerRecord && answerFile != NULL) {
- struct respHeader r;
- char lh[MAX_HOST];
- long scomp;
-
- fseek(answerFile, answerLen, 0);
- r.hostIPnumber = IPaddr;
- r.itemTime = time(NULL);
- r.hostNameLength = lstrlen(hostName) + 1;
- r.soundBufLength = (WORD) (sb->buffer.buffer_len + (sizeof(soundbuf) - BUFL));
- fwrite(&r, sizeof r, 1, answerFile);
- _fmemcpy(lh, hostName, r.hostNameLength);
- fwrite(lh, r.hostNameLength, 1, answerFile);
- scomp = sb->compression;
- sb->compression = fPlayback | (((r.itemTime - lastPacket) > newMessageCriterion) ?
- fAnsNewMsg : 0) | (scomp & fComp2X);
- lastPacket = r.itemTime;
- fwrite(sb, r.soundBufLength, 1, answerFile);
- if ((hDlgAnswer != NULL) && (sb->compression & fAnsNewMsg)) {
- if (growMessageTable(hDlgAnswer, msgCount + 1)) {
- msgTable[msgCount++] = answerLen;
- setMessageCount();
- }
- }
- sb->compression = scomp;
- answerLen = ftell(answerFile);
- if (hDlgAnswer != NULL) {
- EnableWindow(GetDlgItem(hDlgAnswer, IDC_RP_NEXT), answerLen > 0);
- EnableWindow(GetDlgItem(hDlgAnswer, IDC_RP_ERASE), answerLen > 0);
- }
- }
- }
-
- /* ANSWERSYNC -- Make sure output data are written to file. */
-
- void answerSync(void)
- {
- if (answerFile != NULL) {
- fflush(answerFile);
- }
- }
-
- /* ANSWERCLOSE -- Close the answering machine. */
-
- void answerClose(void)
- {
- if (answerFile != NULL) {
- fclose(answerFile);
- answerFile = NULL;
- }
- }
-
- /* ANSWERREPLAY -- Begin replay of answering machine. */
-
- static void answerReplay(void)
- {
- answerSync();
- replaying = TRUE;
- }
-
- /* ANSWERREAD -- Read the next buffer from the answering machine. */
-
- static int answerRead(struct in_addr *IPaddr, time_t *rtime,
- char *hostName, soundbuf *sb)
- {
- struct respHeader r;
-
- fseek(answerFile, answerPlayPos, 0);
- if (fread(&r, sizeof r, 1, answerFile) != 1) {
- return FALSE;
- }
- *IPaddr = r.hostIPnumber;
- *rtime = r.itemTime;
- if (fread(hostName, r.hostNameLength, 1, answerFile) != 1) {
- return FALSE;
- }
- if (fread(sb, r.soundBufLength, 1, answerFile) != 1) {
- return FALSE;
- }
- answerPlayPos = ftell(answerFile);
- return TRUE;
- }
-
- /* ANSWERREPLAYDONE -- End replay of answer file. */
-
- static void answerReplayDone(void)
- {
- replaying = FALSE;
- answerPlayPos = 0;
- }
-
- // SCANMESSAGEFILE -- Built in-memory message table
-
- static void scanMessageFile(HWND hwnd)
- {
- struct in_addr IPaddr;
- char hostName[MAX_HOST];
- time_t t;
- long lp;
-
- answerPlayPos = 0;
- msgCount = 0;
- if (answerFile != NULL) {
- while (lp = answerPlayPos, answerRead(&IPaddr, &t, hostName, &ebuf)) {
- if (ebuf.compression & fAnsNewMsg) {
- if (!growMessageTable(hwnd, msgCount + 1)) {
- return;
- }
- msgTable[msgCount++] = lp;
- }
- }
- answerPlayPos = 0;
- }
- }
-
- // ANSWERDLGPROC -- Answering machine dialogue procedure
-
- BOOL CALLBACK answerDlgProc(HWND hwnd, UINT nMessage,
- WPARAM wParam, LPARAM lParam)
- {
- static int replaying;
- static int firstPacket, hostShown, hostPrelim;
- static int buttonPushed;
-
- switch (nMessage) {
- case WM_INITDIALOG:
- replaying = FALSE;
- hDlgAnswer = hwnd;
- msgMax = 50;
- msgTable = (long FAR *) GlobalAllocPtr(GPTR, msgMax * sizeof(long));
- if (msgTable == NULL) {
- MessageBox(hwnd, rstring(IDS_T_ALLOC_MSG_TABLE_ERR),
- NULL, MB_OK | MB_ICONEXCLAMATION);
- DestroyWindow(hwnd);
- }
- scanMessageFile(hwnd);
- setIdle: EnableWindow(GetDlgItem(hwnd, IDC_RP_PREV), FALSE);
- EnableWindow(GetDlgItem(hwnd, IDC_RP_REPLAY), FALSE);
- EnableWindow(GetDlgItem(hwnd, IDC_RP_REWIND), FALSE);
- EnableWindow(GetDlgItem(hwnd, IDC_RP_NEXT), answerFile && msgCount > 0);
- EnableWindow(GetDlgItem(hwnd, IDC_RP_ERASE), answerFile && answerLen > 0);
- EnableWindow(GetDlgItem(hwnd, IDC_RP_RECORD), answerFile != NULL);
- CheckDlgButton(hwnd, IDC_RP_RECORD, answerFile && answerRecord);
- if (answerFileName != NULL) {
- SetDlgItemText(hwnd, IDC_RP_MSGFILE, answerFileName);
- }
- SetDlgItemText(hwnd, IDC_RP_SITE, "");
- SetDlgItemText(hwnd, IDC_RP_TIME, "");
- currentMessage = -1; // Nothing played yet
- buttonPushed = 0;
- setMessageCount();
- return TRUE;
-
- case WM_CLOSE:
- DestroyWindow(hwnd);
- return TRUE;
-
- case WM_COMMAND:
- switch ((int) wParam) {
-
- case IDC_RP_PREV:
- currentMessage--;
- goto playCurrent;
-
- case IDC_RP_NEXT:
- currentMessage++;
-
- case IDC_RP_REPLAY:
- playCurrent: setMessageCount();
- buttonPushed = wParam;
- if (obtainOutput(hwndMDIFrame)) {
- answerReplay();
- answerPlayPos = msgTable[currentMessage];
- // Disable controls to prevent mischief while we're playing
- EnableWindow(GetDlgItem(hwnd, IDC_RP_PREV), FALSE);
- EnableWindow(GetDlgItem(hwnd, IDC_RP_NEXT), FALSE);
- EnableWindow(GetDlgItem(hwnd, IDC_RP_REPLAY), FALSE);
- EnableWindow(GetDlgItem(hwnd, IDC_RP_ERASE), FALSE);
- EnableWindow(GetDlgItem(hwnd, IDC_RP_REWIND), FALSE);
- EnableWindow(GetDlgItem(hwnd, IDC_RP_BROWSE), FALSE);
- replaying = TRUE;
- firstPacket = TRUE;
- hostShown = hostPrelim = FALSE;
- SetTimer(hwnd, 5, 1, NULL);
- }
- break;
-
- case IDC_RP_ERASE:
- fclose(answerFile);
- answerFile = fopen(answerFileName, "w+b");
- msgCount = 0;
- answerLen = 0;
- // Note fall-through
-
- case IDC_RP_REWIND:
- goto setIdle;
-
- case IDC_RP_BROWSE:
- {
- OPENFILENAME ofn;
- char szString[MAX_PATH];
-
- memset(&ofn, 0, sizeof(ofn));
- ofn.lStructSize = sizeof(OPENFILENAME);
- ofn.hwndOwner = hwnd;
- ofn.lpstrFilter = rfilter(IDS_T_ANSWER_MESSAGE_FILTER);
- ofn.lpstrCustomFilter = NULL;
- strcpy(szString, answerFileName);
- ofn.lpstrFile = (LPSTR) szString;
- ofn.nMaxFile = sizeof(szString);
- ofn.lpstrInitialDir = NULL;
- ofn.lpstrTitle = rstring(IDS_T_ANSWER_OPEN_TITLE);
- ofn.Flags = OFN_NOREADONLYRETURN | OFN_HIDEREADONLY | OFN_SHOWHELP;
- fileHelpKey = rstring(IDS_HELP_ANSWER);
- if (GetOpenFileName((LPOPENFILENAME) &ofn)) {
- SetDlgItemText(hwnd, IDC_RP_MSGFILE, szString);
- _fstrcpy(answerFileName, szString);
- answerClose();
- answerOpen();
- currentMessage = -1;
- scanMessageFile(hwnd);
- EnableWindow(GetDlgItem(hwnd, IDC_RP_PREV), FALSE);
- EnableWindow(GetDlgItem(hwnd, IDC_RP_REWIND), FALSE);
- EnableWindow(GetDlgItem(hwnd, IDC_RP_REPLAY), FALSE);
- EnableWindow(GetDlgItem(hwnd, IDC_RP_NEXT), answerFile && msgCount > 0);
- EnableWindow(GetDlgItem(hwnd, IDC_RP_ERASE), answerFile && answerLen > 0);
- EnableWindow(GetDlgItem(hwnd, IDC_RP_RECORD), answerFile != NULL);
- SetDlgItemText(hwnd, IDC_RP_SITE, "");
- SetDlgItemText(hwnd, IDC_RP_TIME, "");
- setMessageCount();
- }
- }
- break;
-
- case IDC_RP_RECORD:
- answerRecord = IsDlgButtonChecked(hwnd, IDC_RP_RECORD);
- break;
-
- case IDOK:
- answerRecord = IsDlgButtonChecked(hwnd, IDC_RP_RECORD);
- PostMessage(hwnd, WM_CLOSE, 0, 0L);
- break;
-
- case ID_HELP:
- WinHelp(hwndMDIFrame, rstring(IDS_HELPFILE), HELP_KEY,
- ((DWORD) (Lrstring(IDS_HELP_ANSWER))));
- holped = TRUE;
- break;
- }
- return FALSE;
-
- case WM_DESTROY:
- if (replaying) {
- KillTimer(hwnd, 5);
- }
- if (msgTable != NULL) {
- GlobalFreePtr(msgTable);
- msgTable = NULL;
- }
- hDlgAnswer = NULL;
- return 0;
-
- case WM_TIMER:
- {
- struct in_addr IPaddr;
- char hostName[MAX_HOST];
- time_t t;
- DWORD startTicks = GetTickCount();
- long et, sfp;
- int ateof = FALSE;
-
- if (replaying) {
- sfp = answerPlayPos;
- if (answerRead(&IPaddr, &t, hostName, &ebuf)) {
- if (firstPacket || !(ebuf.compression & fAnsNewMsg)) {
- firstPacket = FALSE;
- playSound(hwndMDIFrame, NULL, &ebuf, aboutOutBits, aboutOutSamples);
-
- if (!hostShown) {
- char ft[24];
- struct tm *lt;
-
- // Update host when definitive name seen
- if (hostName[0] != '(') {
- hostShown = TRUE;
- hostPrelim = FALSE;
- }
-
- if (!hostPrelim) {
- lt = localtime(&t);
- sprintf(ft, Format(49), rstring(IDS_WEEKDAYS + lt->tm_wday),
- lt->tm_year, lt->tm_mon + 1, lt->tm_mday,
- lt->tm_hour, lt->tm_min, lt->tm_sec);
- SetDlgItemText(hwnd, IDC_RP_TIME, ft);
- SetDlgItemText(hwnd, IDC_RP_SITE, hostName);
- hostPrelim = TRUE;
- }
- }
-
- /* The following code is needed because when we're reading
- sound from a file, as opposed to receiving it in real
- time from the CODEC, we must meter out the samples
- at the rate they will actually be played by the destination
- machine. For 8000 samples per second, this amounts
- to 125 microseconds per sample. */
-
- #define kOverhead 30000L
- et = ((ebuf.buffer.buffer_len * 125L) - kOverhead) -
- ((GetTickCount() - startTicks) * 1000);
- if (et <= 0) {
- et = 1;
- }
- SetTimer(hwnd, 5, (UINT) (et / 1000), NULL);
- } else {
- answerPlayPos = sfp;
- replaying = FALSE;
- }
- } else {
- replaying = FALSE;
- ateof = TRUE;
- }
- }
- if (!replaying) {
- answerReplayDone();
- KillTimer(hwnd, 5);
- EnableWindow(GetDlgItem(hwnd, IDC_RP_PREV), currentMessage > 0);
- EnableWindow(GetDlgItem(hwnd, IDC_RP_NEXT), !ateof);
- EnableWindow(GetDlgItem(hwnd, IDC_RP_REPLAY), currentMessage >= 0);
- EnableWindow(GetDlgItem(hwnd, IDC_RP_REWIND), TRUE);
- EnableWindow(GetDlgItem(hwnd, IDC_RP_ERASE), TRUE);
- EnableWindow(GetDlgItem(hwnd, IDC_RP_BROWSE), TRUE);
-
- /* Restore focus to the button we pushed, or the logical
- successor if it isn't enabled any more. */
-
- if (buttonPushed != 0 && !IsWindowEnabled(GetDlgItem(hwnd, buttonPushed))) {
- if (IsWindowEnabled(GetDlgItem(hwnd, IDC_RP_NEXT))) {
- buttonPushed = IDC_RP_NEXT;
- } else if (IsWindowEnabled(GetDlgItem(hwnd, IDC_RP_PREV))) {
- buttonPushed = IDC_RP_PREV;
- } else if (IsWindowEnabled(GetDlgItem(hwnd, IDC_RP_REPLAY))) {
- buttonPushed = IDC_RP_REPLAY;
- } else {
- buttonPushed = IDOK;
- }
- }
- SetFocus(GetDlgItem(hwnd, buttonPushed));
- }
- }
- break;
-
- default:
- if (nMessage == fileOpenHelpButton && fileHelpKey != NULL) {
- WinHelp(hwndMDIFrame, rstring(IDS_HELPFILE), HELP_KEY,
- ((DWORD) (LPSTR) fileHelpKey));
- holped = TRUE;
- }
- break;
- }
- return FALSE;
- }
-
- // ANSWERDIALOGUE -- Answering machine dialogue
-
- VOID answerDialogue(HWND hwndParent)
- {
- hDlgAnswer = CreateDialog(hInst, MAKEINTRESOURCE(IDD_REPONDEUR),
- hwndParent, (DLGPROC) pfnAnswer);
- }
-
-
-