rexecクライアントを作る

ソースプログラム(C言語)です。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <netdb.h>

/*********************************************************************
 * rexec.c
 * 2002/06/14.
 *********************************************************************/
#define BUF_SIZE 4096

/*********************************************************************
 * 入力ストリームからの入力を出力ストリームにそのまま出力します。
 * 引数:
 *   fin  入力ストリーム
 *   fout 出力ストリーム
 * 戻り値
 *   処理コード(0以外はエラー)
 *********************************************************************/
static int readAndWrite(FILE* fout, FILE* fin){
  /* 標準出力の応答を出力します。 */
  char buf[BUF_SIZE];
  while(fgets(buf, BUF_SIZE, fin) != NULL){
    fprintf(fout, "%s", buf);
  }
  return 0;
}

/*********************************************************************
 * メイン
 *********************************************************************/
int main(int argc, char* argv[]){
  int i;
  char* hostName, * hostNamePtr = NULL;
  int port = 512; /* rexecプロトコルの標準ポート */
  char* userName = " ";
  char* password = " ";
  char command[BUF_SIZE];
  int fdstd, fderr = 0;

  char* stdoutFileName = NULL;
  char* stderrFileName = NULL;

  if((hostName = (char* )malloc(BUF_SIZE)) == NULL){
    fprintf(stderr, "ERROR: memory exhausted.\n");
    return 99;
  }
  command[0] = '\0';
  for(i=1; i<argc; i++){
    if(! strncmp(argv[i], "-l", 2) && i<argc-1){
      userName = argv[++i];
    }
    else if(! strncmp(argv[i], "-p", 2) && i<argc-1){
      password = argv[++i];
    }
    else if(! strncmp(argv[i], "-o", 2) && i<argc-1){
      stdoutFileName = argv[++i];
    }
    else if(! strncmp(argv[i], "-e", 2) && i<argc-1){
      stderrFileName = argv[++i];
    }
    else if(! hostNamePtr){
      hostNamePtr = argv[i];
    }
    else{
      if(! * command){
        strcpy(command, argv[i]);
      }
      else{
        strcat(command, " ");
        strcat(command, argv[i]);
      }
    }
  }
  if(! hostNamePtr || ! * command){
    fprintf(stderr, "ERROR: too few arguments, should be\n");
    fprintf(stderr, "%s [-l username] [-p password] [-o stdout-outfile] [-e stderr-outfile] host command\n",
      argv[0]);
    return 98;
  }

  strcpy(hostName, hostNamePtr);
  fdstd = rexec(& hostName, port, userName, password, command, & fderr);
  if(fdstd < 0){
    fprintf(stderr, "ERROR: command invocation failed:%s\n",
      strerror(errno));
    return 1;
  }

  /* 標準出力の応答を出力します。 */
  {
    FILE* fin, * fout;
    int r;

    if((fin = fdopen(fdstd, "r")) == NULL){
      fprintf(stderr, "ERROR: cannot open std channel:%s\n",
        strerror(errno));
      return 2;
    }
    if(stdoutFileName){
      if((fout = fopen(stdoutFileName, "w")) == NULL){
        fprintf(stderr, "ERROR: cannot open std-output channel for %s : %s\n",
          stdoutFileName, strerror(errno));
        return 3;
      }
    }
    else{
      fout = stdout;
    }
    r = readAndWrite(fout, fin);
    if(r != 0) return r;
    fclose(fin);
  }


  /* 標準エラー出力の応答を出力します。 */
  {
    FILE* fin, * fout;
    int r;

    if((fin = fdopen(fderr, "r")) == NULL){
      fprintf(stderr, "ERROR: cannot open err channel:%s\n",
        strerror(errno));
      return 4;
    }
    if(stderrFileName){
      if((fout = fopen(stderrFileName, "w")) == NULL){
        fprintf(stderr, "ERROR: cannot open std-output channel for %s : %s\n",
          stderrFileName, strerror(errno));
        return 5;
      }
    }
    else{
      fout = stderr;
    }
    r = readAndWrite(fout, fin);
    if(r != 0) return r;
    fclose(fin);
  }

  free(hostName);
  return 0;
}

使い方は、

rexec -l account -p password [-o stdoutの出力ファイル] [-e stderrの出力ファイル] \
  hostname command args...

こんな感じです。

Misc. Topics Top

(first uploaded 2001/06/16 last updated (not ever), URANO398)

Gポイントポイ活 Amazon Yahoo 楽天

無料ホームページ 楽天モバイル[UNLIMITが今なら1円] 海外格安航空券 海外旅行保険が無料!