/* Ce programme est celui utilisĂ©par l'utilisateur pour exĂcuter une commande cfshell_cmd commande argument ... ou encore ln -s cfshell_cmd commande commande argument ... Ce programme se connecte au serveur cfshell_local. */ #include #include #include #include #include #include #include #include "cfshell.h" using namespace std; static string homepath (const char *path) { string ret; if (path[0] != '/'){ ret = string(getenv("HOME")) + "/" + path; }else{ ret = path; } return ret; } #define _TLMP_cfshell_talk struct _F_cfshell_talk{ _F_tcpconnect *con; #define _F_cfshell_talk_init(x) void x init() virtual _F_cfshell_talk_init( )=0; #define _F_cfshell_talk_data(x) void x data(const void *buf, int len) virtual _F_cfshell_talk_data( ); #define _F_cfshell_talk_stdout(x) void x stdout(const char *buf, int len) virtual _F_cfshell_talk_stdout( ); #define _F_cfshell_talk_stderr(x) void x stderr(const char *buf, int len) virtual _F_cfshell_talk_stderr( ); #define _F_cfshell_talk_retcode(x) void x retcode(int retcode, int reterrno) virtual _F_cfshell_talk_retcode( )=0; void exec (int cmd, const char *arg); }; void _F_cfshell_talk::data(const void *, int len) { tlmp_error ("cfshell_talk::data non traite: len=%d\n",len); } void _F_cfshell_talk::stderr(const char *, int len) { tlmp_error ("cfshell_talk::stderr non traite: len=%d\n",len); } void _F_cfshell_talk::stdout(const char *, int len) { tlmp_error ("cfshell_talk::stdout non traite: len=%d\n",len); } void _F_cfshell_talk::exec (int cmd, const char *arg) { CFSHELL_PROTOCOL proto; proto.command = CFSHELL_EXEC; proto.execcmd = cmd; proto.len = strlen(arg)+1; con->send (&proto,sizeof(proto)); con->send (arg,proto.len); } static string unixport; static int cfshell_talk(_F_cfshell_talk &c) { glocal _F_cfshell_talk *c = &c; glocal STREAMP_BUF str; ("unix:",unixport.c_str(),1); glocal.c->con = this; setrawmode (true); glocal.c->init (); (glocal.str,line,info.linelen); int ret = 0; CFSHELL_PROTOCOL *proto = (CFSHELL_PROTOCOL*)buf; if ((unsigned)len >= sizeof(CFSHELL_PROTOCOL)){ int need_len = proto->len + sizeof(CFSHELL_PROTOCOL); if (need_len <= len){ printf ("command=%d len=%d\n",proto->command,proto->len); const char *data = ((const char*)buf+sizeof(CFSHELL_PROTOCOL)); if (proto->command == CFSHELL_DATA){ glocal.c->data (data,proto->len); }else if (proto->command == CFSHELL_STDOUT){ glocal.c->stdout (data,proto->len); }else if (proto->command == CFSHELL_STDERR){ glocal.c->stderr (data,proto->len); }else if (proto->command == CFSHELL_RETCODE){ CFSHELL_DATA_RETCODE *code = (CFSHELL_DATA_RETCODE*)data; glocal.c->retcode (code->retcode,code->errno); } ret = need_len; } } return ret; return 0; } static int cfshell_exec_simple (int _cmd, const char *_fname) { glocal int ret = -1; glocal const char *fname = _fname; glocal int cmd = _cmd; (); exec (glocal.cmd,glocal.fname); printf ("stat data len=%d\n",len); glocal.ret = retcode; //if (retcode != 0) errno = reterrno; return glocal.ret; } static int cfshell_stat (const char *_fname) { glocal int ret = -1; glocal const char *fname = _fname; (); exec (CFSHELL_STAT,glocal.fname); printf ("stat data len=%d\n",len); glocal.ret = retcode; //if (retcode != 0) errno = reterrno; return glocal.ret; } static int cfshell_command (const char *cmd, int argc, char *argv[]) { int ret = -1; if (strcmp(cmd,"cp")==0){ if (argc == 3){ } }else if (strcmp(cmd,"mkdir")==0){ for (int i=0; i int main (int argc, char *argv[]) { glocal int ret = -1; glocal const char *unixport = ".cfshell/cfshell_local.sock"; glocal const char *argv0 = argv[0]; glocal.ret = (argc,argv); setproginfo ("cfshell_cmd",VERSION ,"Execute une commande distante\n" "\n" "cfshell_cmd commande argument ...\n" "commande argument ...\n"); setarg ('p',"unixport","Socket unix",glocal.unixport,false); int ret = -1; signal (SIGPIPE,SIG_IGN); signal (SIGCHLD,SIG_IGN); glocal string cmd; glocal.cmd = argv[0]; unixport = homepath(glocal.unixport); const char *pt = strrchr(glocal.argv0,'/'); if (pt == NULL){ pt = glocal.argv0; }else{ pt++; } if (strcmp(pt,"cfshell_cmd")==0){ // Le premier argument determine la semantique ret = cfshell_command (argv[0],argc-1,argv+1); }else{ // Le programme cfshell_cmd est appele via un lien symbolique // ln -s cfshell_cmd cp // et donc l'argv0 original determine la semantique ret = cfshell_command (pt,argc,argv); } return ret; return glocal.ret; }