3.3.1 CUPとSPPの作成

CUPとSPPの構成例を次の図に示します。例題では,Windows環境以外の場合を示します。

図3-2 CUPとSPPの構成例

[図データ]

この例題で使用するCUPのコーディング例を次に示します。

000010  #include <stdio.h>
000020  #include <string.h>
000030  #include <dcvclt.h>
000040  #include <dcvrpc.h>
000050
000060  #define BUFSIZE    512
000070  #define SERVICE    "spp01"
000080
000090  main()
000100  {
000110    char    in[BUFSIZE];
000120    DCULONG    in_len;
000130    char    out[BUFSIZE];
000140    DCULONG    out_len;
000150    char    indata[BUFSIZE];
000160    DCLONG      rc;
000170    DCCLT_ID  cltid;
000180    char    clt_flag = 0;
000190    char    rpc_flag = 0;
000200
000210    /*
000220     *  クライアントユーザの認証要求
000230     */
000240    if((rc = dc_clt_cltin_s(NULL, &cltid, NULL, NULL, "user01", "puser01",
000250        NULL, DCNOFLAGS)) != DC_OK){
000260      printf("cup01: dc_clt_cltin_sに失敗しました。CODE=%d¥n", rc);
000270      goto PROG_EXIT;
000280    }
000290    clt_flag = 1;
000300
000310    /*
000320     *  RPC-OPEN(RPC環境の初期設定)
000330     */
000340    if((rc = dc_rpc_open_s(cltid, DCNOFLAGS)) != DC_OK) {
000350      printf("cup01: dc_rpc_open_sに失敗しました。CODE=%d¥n", rc);
000360      goto PROG_END;
000370    }
000380    rpc_flag = 1;
000390
000400    while (1) {
000410      printf("****** 伝言板メニュー ******¥n");
000420      printf("伝言の取り出し ... [1]    伝言の書き込み ... [2]¥n");
000430      printf("終了 ............. [9]¥n");
000440      printf("番号を入力して下さい。=>");
000450      gets(indata);
000460
000470      if(indata[0] == '1') {
000480
000490        /*
000500         *  RPC-CALL(RPCの実行)
000510         */
000520        strcpy(in, "cup01");
000530        in_len = strlen(in) + 1;
000540        out_len = sizeof(out);
000550        if((rc = dc_rpc_call_s(cltid, SERVICE, "get", in, &in_len, out,
000560            &out_len, DCNOFLAGS)) != DC_OK) {
000570          printf("cup01: dc_rpc_call_sに失敗しました。CODE=%d¥n", rc);
000580          goto PROG_END;
000590        }
000600        printf("伝言の内容: %s¥n", out);
000610      }
000620
000630      else if(indata[0] == '2') {  
000640        printf("伝言を入力して下さい =>");
000650        gets(indata);
000660        if(indata[0] == '¥0') {
000670          strcpy(indata, "伝言はありません。¥n");
000680        }
000690
000700        /*
000710         *  RPC-CALL(RPCの実行)
000720         */
000730        strcpy(in, indata);
000740        in_len = strlen(in) + 1;
000750        out_len = sizeof(out);
000760        if((rc = dc_rpc_call_s(cltid, SERVICE, "put", in, &in_len, out,
000770            &out_len, DCNOFLAGS)) != DC_OK) {
000780          printf("cup01: dc_rpc_call_sに失敗しました。CODE=%d¥n", rc);
000790          goto PROG_END;
000800        }
000810        printf("%s¥n", out);
000820      }
000830
000840      else if(indata[0] == '9') {
000850        break;
000860      }
000870
000880      else {
000890        continue;
000900      }
000910    }
000920
000930  PROG_END:
000940    /*
000950     *  RPC-CLOSE(RPC環境の解除)
000960     */
000970    if(rpc_flag) {
000980        dc_rpc_close_s(cltid, DCNOFLAGS);
000990    }
001000
001010  PROG_EXIT:
001020    if(clt_flag) {
001030        dc_clt_cltout_s(cltid, DCNOFLAGS);
001040    }
001050    exit(0);
001060  }

この例題で使用する,SPPのコーディング例(メイン関数 DAMアクセス)を次に示します。

000010  #include <stdio.h>
000020  #include <dcrpc.h>
000030  #include <dcdam.h>
000040  #define DAMFILE "damfile0"
000050  
000060  int damfd;
000070  
000080  main()
000090  {
000100    int rc;
000110  
000120    /*
000130     *  RPC-OPEN(UAPの開始)
000140     */
000150    if ((rc = dc_rpc_open(DCNOFLAGS)) != DC_OK) {
000160        printf("spp01: dc_rpc_openに失敗しました。CODE=%d¥n", rc);
000170        goto PROG_END;
000180    }
000190    /*
000200     *  DAM-OPEN(論理ファイルのオープン)
000210     */
000220    if ((rc = dc_dam_open(DAMFILE,DCDAM_BLOCK_EXCLUSIVE)) < 0) {
000230        printf("spp01: dc_dam_openに失敗しました。CODE=%d¥n", rc);
000240        goto PROG_END;
000250    }
000260    damfd = rc;
000270    /*
000280     *  RPC-MAINLOOP(SPPのサービス開始)
000290     */
000300    printf("spp01: mainloopに入ります。¥n");
000310    if ((rc = dc_rpc_mainloop(DCNOFLAGS)) != DC_OK) {
000320        printf("spp01: dc_rpc_mainloopに失敗しました。CODE=%d¥n",rc);
000330    }
000340    /*
000350     *  DAM-CLOSE(論理ファイルのクローズ)
000360     */
000370    if ((rc = dc_dam_close(damfd, DCNOFLAGS)) != DC_OK) {
000380        printf("spp01: dc_dam_closeに失敗しました。CODE=%d¥n", rc);
000390    }
000400  PROG_END:
000410    /*
000420     *  RPC-CLOSE(UAPの終了)
000430     */
000440    dc_rpc_close(DCNOFLAGS);
000450    printf("spp01: SPPのサービス処理を終了します。¥n");
000460    exit(0);
000470  }

この例題で使用する,SPPのコーディング例(サービス関数 DAMアクセス)を次に示します。

000010  #include <stdio.h>
000020  #include <string.h>
000030  #include <dcrpc.h>
000040  #include <dctrn.h>
000050  #include <dcdam.h>
000060  #define DAMBLKSIZE  504
000070  
000080  extern int  damfd;
000090  static char damblk[DAMBLKSIZE];
000100  
000110  void get(in, in_len, out, out_len)
000120      char              *in;
000130      DCULONG           *in_len;
000140      char              *out;
000150      DCULONG           *out_len;
000160  {
000170      int               rc;
000180      struct DC_DAMKEY  keyptr;
000190      static char       *service = "get";
000200  
000210    printf("%s: %sからのサービス要求を受け付けました。¥n", service, in);
000220  
000230    /*
000240     *  TRN-BEGIN(トランザクションの開始)
000250     */
000260    if ((rc = dc_trn_begin()) != DC_OK) {
000270      sprintf(out, "%s: dc_trn_beginに失敗しました。CODE=%d¥n",
000270              service,rc);
000280      printf("%s", out);
000290      goto PROG_END;
000300    }
000310    /*
000320     *  DAM_READ(DAMファイルの読み込み)
000330     */
000340    keyptr.fstblkno = 0;
000350    keyptr.endblkno = 0;
000360    if ((rc = dc_dam_read(damfd, &keyptr, 1, damblk, DAMBLKSIZE,
000370                DCDAM_REFERENCE | DCDAM_NOWAIT)) != DC_OK) {
000380        sprintf(out, "%s: dc_dam_readに失敗しました。CODE=%d¥n",
000270                service,rc);
000390        printf("%s", out);
000400        goto TRN_COMMIT;
000410    }
000420    strcpy(out, damblk);
000430  
000440  TRN_COMMIT:
000450    /*
000460     *  TRN_UNCHAINED_COMMIT(非連鎖モードのコミット)
000470     */
000480    if ((rc = dc_trn_unchained_commit()) != DC_OK) {
000490        sprintf(out, "%s: dc_trn_unchained_commitに失敗しました。
000500                CODE=%d¥n",service, rc);
000510        printf("%s", out);
000520    }
000530  PROG_END
000540      *out_len = strlen(out) + 1;
000550      return;
000560  }
000570  
000580  void put(in, in_len, out, out_len)
000590      char              *in;
000600      DCULONG           *in_len;
000610      char              *out;
000620      DCULONG           *out_len;
000630  {
000640      int               rc;
000650      struct DC_DAMKEY  keyptr;
000660      static char  *service = "put";
000670  
000680    printf("%s: サービス要求を受け付けました。¥n", service);
000690  
000700    /*
000710     *  TRN-BEGIN(トランザクションの開始)
000720     */
000730    if ((rc = dc_trn_begin()) != DC_OK) {
000740        sprintf(out, "%s: dc_trn_beginに失敗しました。CODE=%d¥n",
000270                service,rc);
000750        printf("%s", out);
000760        goto PROG_END;
000770    }
000780    /*
000790     *  DAM_WRITE(DAMファイルへ書き込み)
000800     */
000810    keyptr.fstblkno = 0;
000820    keyptr.endblkno = 0;
000830    strcpy(damblk, in);
000840    if ((rc = dc_dam_write(damfd, &keyptr, 1, damblk,
000850              DAMBLKSIZE, DCDAM_WAIT)) != DC_OK) {
000860      sprintf(out, "%s: dc_dam_writeに失敗しました。CODE=%d¥n",
000270              service, rc);
000870      printf("%s", out);
000880      dc_trn_unchained_rollback();
000890      goto PROG_END;
000900    }
000910    sprintf(out, "%s: 正常に処理を終了しました。¥n", service);
000920    /*
000930     *  TRN_UNCHAINED_COMMIT(非連鎖モードのコミット)
000940     */
000950    if ((rc = dc_trn_unchained_commit()) != DC_OK) {
000960        sprintf(out, "%s: dc_trn_unchained_commitに失敗しました。
000970                CODE=%d¥n",service, rc);
000980        printf("%s", out);
000990    }
001000  PROG_END:
001010    *out_len = strlen(out) + 1;
001020    return;
001030  }