aboutsummaryrefslogtreecommitdiff
path: root/src/libsunrpc/prog.c
blob: 914d61fc2f0fdc5e30ba2d811ca5b68acbae1f22 (plain)
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
#include <u.h>
#include <libc.h>
#include <thread.h>
#include <sunrpc.h>

SunStatus
suncallpack(SunProg *prog, uchar *a, uchar *ea, uchar **pa, SunCall *c)
{
	uchar *x;
	int (*pack)(uchar*, uchar*, uchar**, SunCall*);

	if(pa == nil)
		pa = &x;
	if(c->type < 0 || c->type >= prog->nproc || (pack=prog->proc[c->type].pack) == nil)
		return SunProcUnavail;
	if((*pack)(a, ea, pa, c) < 0)
		return SunGarbageArgs;
	return SunSuccess;
}

SunStatus
suncallunpack(SunProg *prog, uchar *a, uchar *ea, uchar **pa, SunCall *c)
{
	uchar *x;
	int (*unpack)(uchar*, uchar*, uchar**, SunCall*);

	if(pa == nil)
		pa = &x;
	if(c->type < 0 || c->type >= prog->nproc || (unpack=prog->proc[c->type].unpack) == nil)
		return SunProcUnavail;
	if((*unpack)(a, ea, pa, c) < 0){
		fprint(2, "%lud %d: '%.*H' unpack failed\n", prog->prog, c->type, (int)(ea-a), a);
		return SunGarbageArgs;
	}
	return SunSuccess;
}

SunStatus
suncallunpackalloc(SunProg *prog, SunCallType type, uchar *a, uchar *ea, uchar **pa, SunCall **pc)
{
	uchar *x;
	uint size;
	int (*unpack)(uchar*, uchar*, uchar**, SunCall*);
	SunCall *c;

	if(pa == nil)
		pa = &x;
	if(type < 0 || type >= prog->nproc || (unpack=prog->proc[type].unpack) == nil)
		return SunProcUnavail;
	size = prog->proc[type].sizeoftype;
	if(size == 0)
		return SunProcUnavail;
	c = mallocz(size, 1);
	if(c == nil)
		return SunSystemErr;
	c->type = type;
	if((*unpack)(a, ea, pa, c) < 0){
		fprint(2, "in: %.*H unpack failed\n", (int)(ea-a), a);
		free(c);
		return SunGarbageArgs;
	}
	*pc = c;
	return SunSuccess;
}

uint
suncallsize(SunProg *prog, SunCall *c)
{
	uint (*size)(SunCall*);

	if(c->type < 0 || c->type >= prog->nproc || (size=prog->proc[c->type].size) == nil)
		return ~0;
	return (*size)(c);
}