/
main.c
168 lines (140 loc) · 5.67 KB
/
main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#include "header.h"
/*
main.cで行う機能
設定ファイルの読み込み
コマンドライン引数の読み取り
クライアントモード、サーバーモードへの遷移
エラー表示
終了
*/
#include "server.c"
#include "client.c"
int main(int argc, char *argv[]){
commandline_t mode = { 0 , 0 } ;
config_t config; //コンフィグ読み込み構造体
config_load(&config);
error_message( mode_check( argv, &mode , argc) );
if ( mode.server != 0 ){
error_message(server_main()); //サーバーモードへ
} else if ( mode.client != 0 ){
error_message(client_main(&config)); //クライアントモードへ
}
return 0;
}
//コマンドラインオプションを読み込むーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
int mode_check(char *argv[], commandline_t *commandline,int argc){
// ループ毎に1つずつコマンドラインオプションを取得する:arg_check(argv[i])
if ( argc > 2 ){ //引数は最大2個まで
return ERROR_ARG_TOO_MANY;
}
for(int i = 1; i < argc; i++){ //1つ目のパラメータは実行ファイルなので弾く
switch ( arg_check(argv[i]) ) {
case 's':
commandline->server = i;
break;
case 'c':
commandline->client = i;
break;
default:
return ERROR_ARG_UNKNOWN;
break;
}
}
return NO_ERROR;
}
int arg_check(char* arg){
if ( (arg[0] == '-') && (arg[1] > 32) ){ //制御文字,空白文字指定は無視
return arg[1];
} //オプションの2文字目を返す
return 0;
}
//コンフィグを読み込む
int config_load(config_t *cfg){
char configfile[256];
memset(cfg,'\0',sizeof(config_t));
memset(configfile,'\0', 256);
FILE *fp;
fp = fopen(CONFIG_FILE,"r"); //readモードで開く
if ( fp == NULL ){ //コンフィグファイルがない
fclose(fp); //ファイルを閉じる
return CONFIG_NOTFOUND;
} else {
while( fgets(configfile , 255 , fp) != NULL ){ //1行ずつ読み出す(最大255バイト)
config_param(configfile, "host", cfg);
}
fclose(fp);
}
return NO_ERROR;
}
//configのパラメータを切り出し、cfg->symbolnameに代入する
int config_param(char *configfile, char *symbolname, config_t *cfg){
char param[256];
int i = 0;
int j = 0;
memset(param,'\0',256);
if ( !strncmp(configfile , symbolname, strlen(symbolname)) ){ //文頭がsymbolname
while ( configfile[i++] != '=') { //=が来るまで送る 1バイト目が=でないことは前条件式で保障されている
if ( i > strlen(configfile)){
break; //=がなければループ抜け
}
}
while ( configfile[i] == ' ') {
i++; //スベースが入っていればその分文字を進める
}
while ( !( (configfile[i] == '\n') || (configfile[i] == '\0')) ){
param[j] = configfile[i]; //\0でも\nでもない場合にコピー
i++;
j++;
}
param[j] = '\0';
strncpy(cfg->host,param,119); //コンフィグ構造体にコピーする
return 1;
}
return 0;
}
//エラーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
void error_message(int err){
switch (err){ //エラーが来ていなければ素通り
case NO_ERROR:
break;
case ERROR_ARG_UNKNOWN:
printf("モード指定が不正です。\n");
exit(0);
case ERROR_ARG_TOO_MANY:
printf("モード指定が多すぎます。\n");
exit(0);
case ERROR_ARG_SEVERAL_MODES:
printf("モードが複数指定されています。\n");
exit(0);
case ERROR_SOCKET:
printf("ソケットの作成に失敗しました。\n");
exit(0);
case ERROR_SOCKET_OPTION:
printf("ソケットオプションの設定に失敗しました。\n");
exit(0);
case ERROR_SOCKET_BIND:
printf("ソケットのバインドに失敗しました。\n");
exit(0);
case ERROR_SOCKET_ACCEPT:
printf("ソケット通信の受付に失敗しました。\n");
exit(0);
case ERROR_GETHOSTBY_FAILED:
printf("相手のホスト・ポート番号の取得に失敗しました。");
exit(0);
case ERROR_SOCKET_CLOSE:
printf("ソケットのクローズに失敗しました。\n");
exit(0);
case ERROR_HOST_UNKNOWN:
printf("ホスト名を解決できませんでした。\n");
exit(0);
case ERROR_CONNECT:
printf("サーバに接続できませんでした。");
break;
case ERROR_FILENOTFOUND:
printf("ファイルがありません。\n");
break;
default:
printf("不正なエラーです。\nエラーコード:%d\n" , err);
exit(0);
}
}