Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/libcs/msgblast.c
1808 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1990-2011 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* Glenn Fowler <[email protected]> *
18
* *
19
***********************************************************************/
20
#pragma prototyped
21
22
/*
23
* syscall message server side receipt
24
*/
25
26
#include "msglib.h"
27
28
/*
29
* blast message from msg->data,msg->size into msg->argv
30
*/
31
32
ssize_t
33
msgblast(register Msg_call_t* msg)
34
{
35
register long n;
36
register unsigned long at;
37
register Msg_arg_t* ap;
38
long r;
39
char* b;
40
char* e;
41
long* np;
42
Msg_file_t* ip;
43
struct dirent* dp;
44
struct statvfs* fp;
45
struct stat* sp;
46
char** vp = (char**)msg->value;
47
48
b = msg->data + MSG_SIZE_SIZE;
49
e = msg->data + msg->size;
50
if ((msg->version = msggetu(&b, e)) != MSG_VERSION)
51
return -1;
52
msg->channel = msggetu(&b, e);
53
msg->call = msggetu(&b, e);
54
msg->stamp = msggetu(&b, e);
55
if (msg->call & MSG_ACK)
56
{
57
msg->ack.addr = msggetu(&b, e);
58
msg->ack.port = msggetu(&b, e);
59
}
60
at = msg->call >> MSG_ARG_CALL;
61
if (msg->call & MSG_VALUE) switch (at & ((1 << MSG_ARG_TYPE) - 1))
62
{
63
case 0:
64
break;
65
case MSG_ARG_file:
66
for (n = 0; n < sizeof(msg->ret.file) / sizeof(msg->ret.file.fid[0]); n++)
67
msg->ret.file.fid[n] = msggetu(&b, e);
68
break;
69
default:
70
msg->ret.number = msggetu(&b, e);
71
break;
72
}
73
ap = msg->argv;
74
while (ap < msg->argv + elementsof(msg->argv))
75
{
76
switch ((at >>= MSG_ARG_TYPE) & ((1 << MSG_ARG_TYPE) - 1))
77
{
78
case MSG_ARG_array:
79
(ap++)->number = r = msggetu(&b, e);
80
(ap++)->array = np = (long*)vp;
81
while (r-- > 0)
82
{
83
n = msggetu(&b, e);
84
if (np < (((long*)&msg->value[sizeof(msg->value)]) - 1))
85
*np++ = n;
86
if (e - b >= n) b += n;
87
}
88
if (np < (((long*)&msg->value[sizeof(msg->value)]) - 1)) np++;
89
vp = (char**)np;
90
continue;
91
case MSG_ARG_file:
92
(ap++)->file = ip = (Msg_file_t*)vp;
93
for (n = 0; n < sizeof(*ip) / sizeof(ip->fid[0]); n++)
94
ip->fid[n] = msggetu(&b, e);
95
vp = (char**)(((char*)ip) + sizeof(*ip));
96
continue;
97
case MSG_ARG_input:
98
n = msggetu(&b, e);
99
(ap++)->pointer = b;
100
(ap++)->number = n;
101
if (e - b >= n) b += n;
102
at >>= MSG_ARG_TYPE;
103
continue;
104
case MSG_ARG_number:
105
(ap++)->number = msggetu(&b, e);
106
continue;
107
case MSG_ARG_output:
108
if (msg->call & MSG_VALUE) switch (MSG_CALL(msg->call))
109
{
110
case MSG_CALL(MSG_getdents):
111
(ap++)->pointer = (void*)(dp = (struct dirent*)vp);
112
while (n = msggetz(&b, e, dp->d_name, sizeof(dp->d_name)))
113
{
114
n--;
115
#if _mem_d_namlen_dirent
116
dp->d_namlen = n;
117
#endif
118
#if _mem_d_fileno_dirent
119
dp->d_fileno =
120
#endif
121
msggetu(&b, e);
122
#if _mem_d_off_dirent
123
dp->d_off = 0;
124
#endif
125
n = D_RECSIZ(dp, n);
126
#if _mem_d_reclen_dirent
127
dp->d_reclen = n;
128
#endif
129
dp = (struct dirent*)((char*)dp + n);
130
}
131
(ap++)->number = (char*)dp - (char*)vp;
132
msggetu(&b, e);
133
at >>= MSG_ARG_TYPE;
134
break;
135
case MSG_CALL(MSG_pipe):
136
(ap++)->file = ip = (Msg_file_t*)vp;
137
for (r = 0; r < 2; r++)
138
{
139
for (n = 0; n < sizeof(*ip) / sizeof(ip->fid[0]); n++)
140
ip->fid[n] = msggetu(&b, e);
141
ip++;
142
}
143
vp = (char**)ip;
144
break;
145
case MSG_CALL(MSG_stat):
146
(ap++)->pointer = (void*)(sp = (struct stat*)vp);
147
sp->st_dev = msggetu(&b, e);
148
sp->st_ino = msggetu(&b, e);
149
sp->st_mode = msggetu(&b, e);
150
sp->st_nlink = msggetu(&b, e);
151
sp->st_uid = msggetu(&b, e);
152
sp->st_gid = msggetu(&b, e);
153
sp->st_size = msggetu(&b, e);
154
sp->st_atime = msggetu(&b, e);
155
sp->st_mtime = msggetu(&b, e);
156
sp->st_ctime = msggetu(&b, e);
157
#if _mem_st_blksize_stat
158
sp->st_blksize =
159
#endif
160
msggetu(&b, e);
161
#if _mem_st_blocks_stat
162
sp->st_blocks =
163
#endif
164
msggetu(&b, e);
165
break;
166
case MSG_CALL(MSG_statfs):
167
(ap++)->pointer = (void*)(fp = (struct statvfs*)vp);
168
fp->f_bsize = msggetu(&b, e);
169
fp->f_frsize = msggetu(&b, e);
170
fp->f_blocks = msggetu(&b, e);
171
fp->f_bfree = msggetu(&b, e);
172
fp->f_bavail = msggetu(&b, e);
173
fp->f_files = msggetu(&b, e);
174
fp->f_ffree = msggetu(&b, e);
175
fp->f_favail = msggetu(&b, e);
176
#if _mem_f_fsid_statvfs
177
fp->f_fsid =
178
#endif
179
msggetu(&b, e);
180
#if _mem_f_basetype_statvfs
181
msggetz(&b, e, fp->f_basetype, sizeof(fp->f_basetype));
182
#else
183
msggetz(&b, e, NiL, 0);
184
#endif
185
fp->f_flag = msggetu(&b, e);
186
fp->f_namemax = msggetu(&b, e);
187
#if _mem_f_fstr_statvfs
188
msggetz(&b, e, fp->f_fstr, sizeof(fp->f_fstr));
189
#endif
190
break;
191
default:
192
n = msggetu(&b, e);
193
(ap++)->pointer = (void*)b;
194
(ap++)->number = n;
195
at >>= MSG_ARG_TYPE;
196
if (e - b >= n) b += n;
197
break;
198
}
199
else (ap++)->pointer = 0;
200
continue;
201
case MSG_ARG_string:
202
if (n = msggetu(&b, e))
203
{
204
(ap++)->string = b;
205
if (e - b >= n) b += n;
206
}
207
else (ap++)->string = 0;
208
continue;
209
case MSG_ARG_vector:
210
(ap++)->vector = vp;
211
while (n = msggetu(&b, e))
212
{
213
if (vp < (((char**)&msg->value[sizeof(msg->value)]) - 1))
214
*vp++ = b;
215
if (e - b >= n) b += n;
216
}
217
*vp = 0;
218
if (vp < (((char**)&msg->value[sizeof(msg->value)]) - 1)) vp++;
219
continue;
220
}
221
break;
222
}
223
msg->argc = ap - msg->argv;
224
return msg->size;
225
}
226
227