Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include <u.h>
2
#include <libc.h>
3
#include <auth.h>
4
#include "authlocal.h"
5
 
6
static struct {
7
	char *verb;
8
	int val;
9
} tab[] = {
10
	"ok",			ARok,
11
	"done",		ARdone,
12
	"error",		ARerror,
13
	"needkey",	ARneedkey,
14
	"badkey",		ARbadkey,
15
	"phase",		ARphase,
16
	"toosmall",	ARtoosmall,
17
	"error",		ARerror,
18
};
19
 
20
static int
21
classify(char *buf, uint n, AuthRpc *rpc)
22
{
23
	int i, len;
24
 
25
	for(i=0; i<nelem(tab); i++){
26
		len = strlen(tab[i].verb);
27
		if(n >= len && memcmp(buf, tab[i].verb, len) == 0 && (n==len || buf[len]==' ')){
28
			if(n==len){
29
				rpc->narg = 0;
30
				rpc->arg = "";
31
			}else{
32
				rpc->narg = n - (len+1);
33
				rpc->arg = (char*)buf+len+1;
34
			}
35
			return tab[i].val;
36
		}
37
	}
38
	werrstr("malformed rpc response: %s", buf);
39
	return ARrpcfailure;
40
}
41
 
42
AuthRpc*
43
auth_allocrpc(int afd)
44
{
45
	AuthRpc *rpc;
46
 
47
	rpc = mallocz(sizeof(*rpc), 1);
48
	if(rpc == nil)
49
		return nil;
50
	rpc->afd = afd;
51
	return rpc;
52
}
53
 
54
void
55
auth_freerpc(AuthRpc *rpc)
56
{
57
	free(rpc);
58
}
59
 
60
uint
61
auth_rpc(AuthRpc *rpc, char *verb, void *a, int na)
62
{
63
	int l, n, type;
64
	char *f[4];
65
 
66
	l = strlen(verb);
67
	if(na+l+1 > AuthRpcMax){
68
		werrstr("rpc too big");
69
		return ARtoobig;
70
	}
71
 
72
	memmove(rpc->obuf, verb, l);
73
	rpc->obuf[l] = ' ';
74
	memmove(rpc->obuf+l+1, a, na);
75
	if((n=write(rpc->afd, rpc->obuf, l+1+na)) != l+1+na){
76
		if(n >= 0)
77
			werrstr("auth_rpc short write");
78
		return ARrpcfailure;
79
	}
80
 
81
	if((n=read(rpc->afd, rpc->ibuf, AuthRpcMax)) < 0)
82
		return ARrpcfailure;
83
	rpc->ibuf[n] = '\0';
84
 
85
	/*
86
	 * Set error string for good default behavior.
87
	 */
88
	switch(type = classify(rpc->ibuf, n, rpc)){
89
	default:
90
		werrstr("unknown rpc type %d (bug in auth_rpc.c)", type);
91
		break;
92
	case ARok:
93
		break;
94
	case ARrpcfailure:
95
		break;
96
	case ARerror:
97
		if(rpc->narg == 0)
98
			werrstr("unspecified rpc error");
99
		else
100
			werrstr("%s", rpc->arg);
101
		break;
102
	case ARneedkey:
103
		werrstr("needkey %s", rpc->arg);
104
		break;
105
	case ARbadkey:
106
		if(getfields(rpc->arg, f, nelem(f), 0, "\n") < 2)
107
			werrstr("badkey %s", rpc->arg);
108
		else
109
			werrstr("badkey %s", f[1]);
110
		break;
111
	case ARphase:
112
		werrstr("phase error %s", rpc->arg);
113
		break;
114
	}
115
	return type;
116
}