/* * dir.x: 遠隔ディレクトリリストの * プロトコル * * このソースモジュールは rpcgen が生成したソースモジュールです。 * これを使用して rpcgen ツールの機能を説明します。 * * このプログラムは、rpcgen の -h -T のスイッチを使用して * ヘッダーファイル (.h) と付随するデータ構造体も同時に生成して * コンパイルします。 * */ const MAXNAMELEN = 255; /* ディレクトリエントリの最大長 */ typedef string nametype<MAXNAMELEN>; /* ディレクトリエントリ */ typedef struct namenode *namelist; /* リスト内のリンク */ /* * ディレクトリリスト内のノード struct namenode */ struct namenode { nametype name; /* ディレクトリエントリ名 */ namelist next; /* 次のエントリ */ }; /* * READDIR 操作の結果: * 完全に移植可能なアプリケーションにするには、ここで行なっているように * UNIX の errno を使用せずに、取り決めに従ったエラーコードリストを * 使用します。この例では、遠隔呼び出しが成功したか失敗したかを * 識別するのに共用体を使用しています。 */ union readdir_res switch (int errno) { case 0: namelist list; /* エラーなし: ディレクトリリストを返す */ default: void; /* エラー発生: 戻り値なし */ }; /* * ディレクトリリストプログラムの定義 */ program DIRPROG { version DIRVERS { readdir_res READDIR(nametype) = 1; } = 1; } = 0x20000076; |
/* * dir_proc.c: 遠隔手続き readdir */ #include <rpc/rpc.h> /* 必ず必要 */ #include <dirent.h> #include "dir.h" /* rpcgen が生成 */ extern int errno; extern char *malloc(); extern char *strdup(); /* 使用する引数 */ readdir_res * readdir_1(dirname,req) nametype *dirname; struct svc_req *req; { DIR *dirp; struct dirent *d; namelist nl; namelist *nlp; static readdir_res res; /* 必ず static で宣言 */ /* * ディレクトリのオープン */ dirp = opendir(*dirname); if (dirp == (DIR *)NULL) { res.errno = errno; return (&res); } /* * 以前の結果を解放 */ xdr_free(xdr_readdir_res, &res); /* * ディレクトリエントリの収集。ここで割り当てられたメモリーは、 * 次に readdir_1 が呼び出されたときに xdr_free によって解放されます。 */ nlp = &res.readdir_res_u.list; while (d = readdir(dirp)) { nl = *nlp = (namenode *) malloc(sizeof(namenode)); if (nl == (namenode *) NULL) { res.errno = EAGAIN; closedir(dirp); return(&res); } nl->name = strdup(d->d_name); nlp = &nl->next; } *nlp = (namelist)NULL; /* 結果を返す */ res.errno = 0; closedir(dirp); return (&res); } |
/* * rls.c: 遠隔ディレクトリリスト (クライアント側) */ #include <stdio.h> #include <rpc/rpc.h> /* 必ず必要 */ #include "dir.h" /* rpcgen が生成 */ extern int errno; main(argc, argv) int argc; char *argv[]; { CLIENT *cl; char *server; char *dir; readdir_res *result; namelist nl; if (argc != 3) { fprintf(stderr, "usage: %s host directory¥n", argv[0]); exit(1); } server = argv[1]; dir = argv[2]; /* * コマンド行で指定したサーバー上の MESSAGEPROG の呼び出しに使用する * クライアント「ハンドル」を作成します。 */ cl = clnt_create(server, DIRPROG, DIRVERS, "visible"); if (cl == (CLIENT *)NULL) { clnt_pcreateerror(server); exit(1); } result = readdir_1(&dir, cl); if (result == (readdir_res *)NULL) { clnt_perror(cl, server); exit(1); } /* 遠隔手続きの呼び出しに成功 */ if (result->errno != 0) { /* * 遠隔システムでエラーが発生。エラーメッセージを表示して終了。 */ } if (result->errno < sys_nerr) fprintf (stderr, "%s : %s¥n", dir, sys_enlist[result->errno]); errno = result->errno; perror(dir); exit(1); } /* ディレクトリリストの取り出しに成功。ディレクトリリストを表示 */ for(nl = result->readdir_res_u.list; nl != NULL; nl = nl- >next) { printf("%s¥n", nl->name); } exit(0); |