-
Notifications
You must be signed in to change notification settings - Fork 0
/
duckchat.h
182 lines (153 loc) · 4.57 KB
/
duckchat.h
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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
#ifndef DUCKCHAT_H
#define DUCKCHAT_H
/* Path names to unix domain sockets should not be longer than this */
#ifndef UNIX_PATH_MAX
#define UNIX_PATH_MAX 108
#endif
#include <stdio.h> //required for perror
#include <stdlib.h>
#include <inttypes.h> //required for uint64_t
/* This tells gcc to "pack" the structure. Normally, gcc will
* inserting padding into a structure if it feels it is convenient.
* When the structure is packed, gcc gaurantees that all the bytes
* will fall exactly where specified. */
#define packed __attribute__((packed))
/* Define the length limits */
#define USERNAME_MAX 32
#define CHANNEL_MAX 32
#define SAY_MAX 64
#define COMMON "Common"
#define BUFLEN 512
#define KEEP_ALIVE 60
#define SJOIN 60
#define CLEANUP 120
#define MAXSERVERS 20
/* Define some types for designating request and text codes */
typedef int request_t;
typedef int text_t;
typedef uint64_t s_id; //For P2
/* Define codes for request types. These are the messages sent to the server. */
#define REQ_LOGIN 0
#define REQ_LOGOUT 1
#define REQ_JOIN 2
#define REQ_LEAVE 3
#define REQ_SAY 4
#define REQ_LIST 5
#define REQ_WHO 6
#define REQ_KEEP_ALIVE 7 /* Only needed by graduate students */
/* For Program 2 */
#define SREQ_JOIN 8
#define SREQ_LEAVE 9
#define S_SAY 10
/* Define codes for text types. These are the messages sent to the client. */
#define TXT_SAY 0
#define TXT_LIST 1
#define TXT_WHO 2
#define TXT_ERROR 3
/* This structure is used for a generic request type, to the server. */
struct request {
request_t req_type;
} packed;
/* Once we've looked at req_type, we then cast the pointer to one of
* the types below to look deeper into the structure. Each of these
* corresponds with one of the REQ_ codes above. */
struct request_login {
request_t req_type; /* = REQ_LOGIN */
char req_username[USERNAME_MAX];
} packed;
struct request_logout {
request_t req_type; /* = REQ_LOGOUT */
} packed;
struct request_join {
request_t req_type; /* = REQ_JOIN */
char req_channel[CHANNEL_MAX];
} packed;
struct request_leave {
request_t req_type; /* = REQ_LEAVE */
char req_channel[CHANNEL_MAX];
} packed;
struct request_say {
request_t req_type; /* = REQ_SAY */
char req_channel[CHANNEL_MAX];
char req_text[SAY_MAX];
} packed;
struct request_list {
request_t req_type; /* = REQ_LIST */
} packed;
struct request_who {
request_t req_type; /* = REQ_WHO */
char req_channel[CHANNEL_MAX];
} packed;
struct request_keep_alive {
request_t req_type; /* = REQ_KEEP_ALIVE */
} packed;
/* This structure is used for a generic text type, to the client. */
struct text {
text_t txt_type;
} packed;
/* Once we've looked at txt_type, we then cast the pointer to one of
* the types below to look deeper into the structure. Each of these
* corresponds with one of the TXT_ codes above. */
struct text_say {
text_t txt_type; /* = TXT_SAY */
char txt_channel[CHANNEL_MAX];
char txt_username[USERNAME_MAX];
char txt_text[SAY_MAX];
} packed;
/* This is a substructure used by struct text_list. */
struct channel_info {
char ch_channel[CHANNEL_MAX];
} packed;
struct text_list {
text_t txt_type; /* = TXT_LIST */
int txt_nchannels;
struct channel_info txt_channels[0]; // May actually be more than 0
} packed;
struct text_list_s {
text_t txt_type; /* = TXT_LIST */
int txt_nchannels;
} packed;
/* This is a substructure used by text_who. */
struct user_info {
char us_username[USERNAME_MAX];
};
struct text_who {
text_t txt_type; /* = TXT_WHO */
int txt_nusernames;
char txt_channel[CHANNEL_MAX]; // The channel requested
struct user_info txt_users[0]; // May actually be more than 0
} packed;
struct text_who_s {
text_t txt_type; /* = TXT_WHO */
int txt_nusernames;
char txt_channel[CHANNEL_MAX]; // The channel requested
} packed;
struct text_error {
text_t txt_type; /* = TXT_ERROR */
char txt_error[SAY_MAX]; // Error message
};
/* structs for program 2 */
struct s_join {
request_t req_type; /* = SREQ_JOIN */
char req_channel[CHANNEL_MAX];
} packed;
struct s_leave {
request_t req_type; /* = SREQ_LEAVE */
char req_channel[CHANNEL_MAX];
} packed;
struct s_say {
request_t req_type; /* = S_SAY */
s_id say_id;
char txt_username[USERNAME_MAX];
char req_channel[CHANNEL_MAX];
char req_text[SAY_MAX];
} packed;
/*-----------------------------------------------------------------------------
* Method: diep
*---------------------------------------------------------------------------*/
void diep(const char *s)
{
perror(s);
exit(1);
} /* -- diep -- */
#endif