/* * The Unix Channel * * by Michel Beaudouin-Lafon * * Copyright 1990-1993 * Laboratoire de Recherche en Informatique (LRI) * * Send a request to a server * * $Id$ * $CurLog$ */ /* Usage: * tellagent agentname request * tellagent agentname -f file * tellagent agentname */ #include "TextStream.h" #include "Multiplexer.h" #include "error.h" #include #include #include #include #include class INPUT; class TELLER; class INPUT : public UchChannel { protected: TELLER* tell; UchMsgBuffer input; public: INPUT (TELLER* t, int fd) : UchChannel (fd) { tell = t; } void HandleRead (); }; class TELLER : public UchTextService { protected: pUchChannel in; pUchChannel out; cmd_res Execute (const UchTextLine&); void AbandonRestart (); public: TELLER () : UchTextService () { in = 0; out = 0; } void SetOutput (int); void SetInput (int fd); void Close (); }; //---------------- INPUT void INPUT :: HandleRead () { input.NeedSize (128); int n = Read (input); if (n < 0) SysError (ErrFatal, "read input"); if (n == 0) { if (input.BufLength ()) { input.WriteChar ('\n'); input.WriteChar ('\0'); tell->Send ((const char*) input.Buffer ()); input.Flush (); } tell->Close (); return; } input.Append ('\0'); tell->Send ((const char*) input.Buffer ()); input.Flush (); } void TELLER :: SetOutput (int fd) { out = new UchChannel (fd); } void TELLER :: SetInput (int fd) { in = new INPUT (this, fd); in->SetMode (IORead); if (Mpx) Mpx->Add (*in); } UchTextService::cmd_res TELLER :: Execute (const UchTextLine& l) { if (! out) return isCmdOk; UchMsgBuffer buf; l.Unparse (&buf); buf.WriteChar ('\n'); out->WriteBuffer (buf); return isCmdOk; } void TELLER :: AbandonRestart () { if (in) { Mpx->Remove (*in); in = 0; } out = 0; UchTextService::AbandonRestart (); } void TELLER :: Close () { if (in) { Mpx->Remove (*in); in = 0; } out = 0; UchTextService::Close (); } //---------------- Usage void Usage () { Error (ErrUsage, NULL, "server[@host] [request | -f file]"); } //---------------- main main (int argc, char** argv) { ProgramName (argv [0]); // LogfileName ("tellagent.log"); if (argc < 2) Usage (); const char* sname = argv [1]; const char* host = 0; char* p = strchr (sname, '@'); if (p) { *p++ = '\0'; host = p; } UchMultiplexer mpx; TELLER* tell = new TELLER; tell->Init (mpx, sname, host); int fdin = 0; /*stdin*/ if (argc == 2) { // tellagent server : start interactive session } else if (strcmp (argv [2], "-f") == 0) { // tellagent server -f file: read from file if (argc != 4) Usage (); const char* fname = argv [3]; fdin = open (fname, O_RDONLY); if (fdin < 0) SysError (ErrFatal, fname); } else { // tellagent server request: send request and close UchTextLine line; for (int i = 2; i < argc; i++) line << argv [i]; tell->SetOutput (1 /*stdout*/); tell->Send (line); tell->Close (); while (tell->GetStatus () != UchTextService::isRunning) { mpx.LoopScan (); wait (0); } exit (1); } if (fdin >= 0) tell->SetInput (fdin); tell->SetOutput (1 /*stdout*/); #if 0 if (MpxRun () == isMpxEmpty) exit (0); #else mpx.LoopScan (); #endif exit (1); }