📄 server.c
字号:
/* $Header: /home/cvs/wavplay/server.c,v 1.2 1999/12/04 00:01:20 wwg Exp $ * Warren W. Gay VE3WWG Tue Feb 25 21:46:16 1997 * * SERVER MODE FUNCTIONS: * * X LessTif WAV Play : * * Copyright (C) 1997 Warren W. Gay VE3WWG * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details (see enclosed file COPYING). * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. * * Send correspondance to: * * Warren W. Gay VE3WWG * * Email: * ve3wwg@yahoo.com * wgay@mackenziefinancial.com * * $Log: server.c,v $ * Revision 1.2 1999/12/04 00:01:20 wwg * Implement wavplay-1.4 release changes * * Revision 1.1.1.1 1999/11/21 19:50:56 wwg * Import wavplay-1.3 into CVS * * Revision 1.5 1997/04/19 01:25:26 wwg * 1.0pl2 : Fixed so that Server() now initializes the char * array svr.path[0] = 0; so that the potentially garbage * path does not cause trouble. * * Revision 1.4 1997/04/17 00:41:56 wwg * Fixed to use member name .Errno vs original dangerous * .errno reference. This presents a problem on platforms * that make extern errno thread safe, but defining errno * as a macro. * * Revision 1.3 1997/04/14 01:40:41 wwg * Unlock the record semaphore, if Wav open failed, * since we've already locked it by this time! * * Revision 1.2 1997/04/14 01:36:21 wwg * WavOpenForWrite() now reports error message back to client * * Revision 1.1 1997/04/14 00:24:16 wwg * Initial revision * */static const char rcsid[] = "@(#)server.c $Revision: 1.2 $";#include <stdio.h>#include <stdlib.h>#include <stdarg.h>#include <unistd.h>#include <errno.h>#include <fcntl.h>#include <malloc.h>#include <string.h>#include <memory.h>#include <signal.h>#include <sys/types.h>#include <sys/ipc.h>#include <sys/msg.h>#include <sys/sem.h>#include <sys/ioctl.h>#include <sys/stat.h>#include <assert.h>#ifdef SCHED_PRIORITY#include <sched.h>#endif#include <linux/soundcard.h>#include "wavplay.h"#include "server.h"static void toclnt_errmsg(int msg_errno,const char *message,int flags);int clntIPC = -1; /* Client IPC ID for message queue */int bExit = 0; /* TRUE once the server is requested to exit */DSPPROC svr_work_proc = NULL; /* DSP/Server work process */struct S_SVR svr; /* Server state information */static char ermsg[2048]; /* Captured error message *//* * This function captures message text (only) */static voidz_erf(const char *format,va_list ap) { vsprintf(ermsg,format,ap);}/* * This function formats and processes an error message: */static voidx_erf(const char *format,va_list ap) { int msg_errno = errno; vsprintf(ermsg,format,ap); /* Format the message */ toclnt_errmsg(msg_errno,ermsg,0); fputs(ermsg,stderr); /* Copy to stderr also */ fputc('\n',stderr);}/* * Format a message for the client to popup: */static voidClntMsg(const char *format,...) { va_list ap; va_start(ap,format); x_erf(format,ap); va_end(ap);}/* * Service a client request: */intServe(SVRMSG *pmsg,int bWorkProc) { int len; SVRMSG msg; static char *argv[2] = { NULL, NULL }; if ( pmsg->msg_type == ToSvr_Bits ) { /* * Change bits override (only when not busy) : */ if ( bWorkProc ) /* In a work proc? */ return 1; /* Tell DSP play to exit */ svr.opts.DataBits.optChar = 'b'; svr.opts.DataBits.optValue = pmsg->u.tosvr_bits.DataBits; toclnt_settings(0,svr.wfile,&svr.opts); return 0; } else if ( pmsg->msg_type == ToSvr_Bye ) { /* * Exit server: */ if ( cmdopt_x ) fputs("->ToSvr_Bye\n",stderr); bExit = 1; /* Server requested to exit */ return 1; /* Tell DSP play to exit */ } else if ( pmsg->msg_type == ToSvr_Path ) { /* * Register a pathname: */ if ( bWorkProc ) /* In a work proc? */ return 1; /* Tell DSP play to exit */ if ( svr.wfile != NULL ) { WavClose(svr.wfile,x_erf); /* Close last wav file */ svr.wfile = NULL; } /* * Reset any overrides: */ svr.opts.StartSample = 0; svr.opts.SamplingRate.optChar = 0; svr.opts.Channels.optChar = 0; svr.opts.DataBits.optChar = 0; if ( (len = pmsg->bytes) > sizeof svr.path ) len = sizeof svr.path; if ( len > 0 ) strncpy(svr.path,pmsg->u.tosvr_path.path,len)[len] = 0; else *svr.path = 0; /* * We send the same message back to the client so that it now * can update the label widget with the pathname showing. Note that this * message has the same size and format as ToSvr_Path, so we reuse it here: */ pmsg->msg_type = ToClnt_Path; /* Send it back to client now */ MsgToClient(clntIPC,pmsg,0); /* So it can update its display */ /* * Now do a stat on this pathname: */ if ( !*svr.path ) msg.u.toclnt_stat.Errno = ENOENT; /* No path: then not found */ else if ( stat(svr.path,&msg.u.toclnt_stat.sbuf) ) msg.u.toclnt_stat.Errno = errno; /* Pass back errno value */ else msg.u.toclnt_stat.Errno = 0; /* stat() succeeded */ msg.msg_type = ToClnt_Stat; /* We're sending stat info back */ msg.bytes = sizeof msg.u.toclnt_stat; /* This substructure going back */ MsgToClient(clntIPC,&msg,0); /* Send back the response */ if ( msg.u.toclnt_stat.Errno != 0 ) return 0; /* Don't try opening file if error */ /* * Wav info file requested: */ if ( !*svr.path ) msg.u.toclnt_wavinfo.Errno = ENOENT; /* No path: Not found */ else if ( (svr.wfile = WavOpenForRead(svr.path,x_erf)) == NULL ) { msg.u.toclnt_wavinfo.Errno = errno; strncpy(msg.u.toclnt_wavinfo.errmsg,ermsg,sizeof msg.u.toclnt_wavinfo.errmsg) [sizeof msg.u.toclnt_wavinfo.errmsg - 1] = 0; } else { WavReadOverrides(svr.wfile,&svr.opts); msg.u.toclnt_wavinfo.Errno = 0; msg.u.toclnt_wavinfo.wavinfo = svr.wfile->wavinfo; } msg.msg_type = ToClnt_WavInfo; /* We're sending WAV Hdr info back */ msg.bytes = sizeof msg.u.toclnt_wavinfo; /* This substructure going back */ MsgToClient(clntIPC,&msg,0); /* Send back the response */ toclnt_settings(0,svr.wfile,&svr.opts); /* Send back other settings too */ return 0; } else if ( pmsg->msg_type == ToSvr_Restore ) { /* * Reset all overrides: */ svr.opts.StartSample = 0; svr.opts.SamplingRate.optChar = 0; svr.opts.Channels.optChar = 0; svr.opts.DataBits.optChar = 0;rfrsh: if ( svr.wfile != NULL ) { WavClose(svr.wfile,x_erf); svr.wfile = NULL;updt: if ( *svr.path != 0 && (svr.wfile = WavOpenForRead(svr.path,z_erf)) != NULL ) WavReadOverrides(svr.wfile,&svr.opts); } toclnt_settings(0,svr.wfile,&svr.opts); return bWorkProc ? 1 : 0; } else if ( pmsg->msg_type == ToSvr_Chan ) { svr.opts.Channels.optChar = 'S'; svr.opts.Channels.optValue = pmsg->u.tosvr_chan.Channels; goto rfrsh; } else if ( pmsg->msg_type == ToSvr_Play ) { /* * Play a WAV file: */ if ( bWorkProc ) /* In a work proc? */ return 0; /* Tell DSP play to continue */ /* * Not playing yet, start playing: */ argv[0] = svr.path; /* Point to pathname */ if ( *argv[0] == 0 ) { if ( cmdopt_x ) fputs("No pathname to play!\n",stderr); return 1; } /* * Try to acquire the lock on the device: */ if ( svr.lockIPCID >= 0 && LockDSP(svr.lockIPCID,0,x_erf,PLAYLOCK_SECS) ) return 0; /* No lock acquired */ svr_work_proc = ServerWorkProc; wavplay(&svr.opts,argv,x_erf); /* Play file */ svr_work_proc = NULL; /* * Release the Play lock on the device: */ if ( svr.lockIPCID >= 0 ) UnlockDSP(svr.lockIPCID,0,x_erf); return 0; } else if ( pmsg->msg_type == ToSvr_StartSample ) { if ( bWorkProc ) /* In a work proc? */ return 1; /* Tell DSP play to exit */ svr.opts.StartSample = pmsg->u.tosvr_start_sample.StartSample; goto rfrsh; } else if ( pmsg->msg_type == ToSvr_SamplingRate ) { if ( pmsg->u.tosvr_sampling_rate.SamplingRate >= DSP_MIN ) { svr.opts.SamplingRate.optChar = 's'; svr.opts.SamplingRate.optValue = (UInt32) pmsg->u.tosvr_sampling_rate.SamplingRate; } else svr.opts.SamplingRate.optChar = 0; /* Turn off override */ goto rfrsh; /* Refresh client settings */ } else if ( pmsg->msg_type == ToSvr_Stop ) { return 1; /* Tell DSP play/record to exit */ } else if ( pmsg->msg_type == ToSvr_Pause ) { return 0; /* Ignore this */ } else if ( pmsg->msg_type == ToSvr_Record ) { /* * Play a WAV file: */ if ( bWorkProc ) /* In a work proc? */ return 0; /* Yes, ignore this event */ /* * Not recording yet, start recording: */ if ( svr.wfile != NULL ) { WavClose(svr.wfile,x_erf); svr.wfile = NULL; } /* * Tell client the pathname we're using for the recording:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -