📄 answer.c
字号:
/*
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
char answerOutFileName[MAX_PATH] = ""; // Answering machine outgoing message 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 = fProtocol | fPlayback | (((r.itemTime - lastPacket) > newMessageCriterion) ?
fAnsNewMsg : 0) /* | (scomp & fComp2X) */ ;
lastPacket = r.itemTime;
fwrite(sb, r.soundBufLength, 1, answerFile);
if ((hDlgAnswer != NULL) && (sb->compression & fAnsNewMsg) &&
(msgTable != NULL)) {
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;
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);
}
hDlgAnswer = 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);
}
if (answerOutFileName != NULL) {
SetDlgItemText(hwnd, IDC_RP_OUTMSGFILE, answerOutFileName);
}
SetDlgItemText(hwnd, IDC_RP_SITE, "");
SetDlgItemText(hwnd, IDC_RP_TIME, "");
currentMessage = -1; // Nothing played yet
buttonPushed = 0;
setMessageCount();
return TRUE;
case WM_CLOSE:
/*{ static double zee = 1.0;
static double grex = 0.0;
static char ig[8];
// Divide by zero to test floating point exception mode settings
zee = zee / sin(grex);
_fmemcpy(ig, &zee, 8);
zee++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -