afpfs-ng-mac/lib/proto_map.c

179 lines
4.1 KiB
C

/*
* map.c
*
* Copyright (C) 2007 Alex deVries
*
*/
#include <stdlib.h>
#include <string.h>
#include "afpfs-ng/dsi.h"
#include "afpfs-ng/afp.h"
#include "afpfs-ng/utils.h"
#include "dsi_protocol.h"
#include "afpfs-ng/afp_protocol.h"
/* This is used to pass the return values back from afp_getuserinfo_reply() */
struct uidgid {
unsigned int uid;
unsigned int gid;
};
int afp_getuserinfo(struct afp_server * server, int thisuser,
unsigned int userid, unsigned short bitmap,
unsigned int *newuid, unsigned int *newgid)
{
struct {
struct dsi_header dsi_header __attribute__((__packed__));
uint8_t command;
uint8_t thisuser;
uint32_t userid __attribute__((__packed__));
uint16_t bitmap __attribute__((__packed__));
} __attribute__((__packed__)) request;
struct uidgid uidgid;
int ret;
dsi_setup_header(server,&request.dsi_header,DSI_DSICommand);
request.command=afpGetUserInfo;
request.thisuser=(thisuser!=0);
request.userid=htonl(userid);
request.bitmap=htons(bitmap);
ret=dsi_send(server, (char *) &request,sizeof(request),
DSI_DEFAULT_TIMEOUT,afpGetUserInfo, (void *) &uidgid);
if (bitmap & kFPGetUserInfo_USER_ID)
*newuid=uidgid.uid;
if (bitmap & kFPGetUserInfo_PRI_GROUPID)
*newgid=uidgid.gid;
return ret;
}
int afp_getuserinfo_reply(struct afp_server *server, char * buf, unsigned int size, void *other)
{
struct {
struct dsi_header header __attribute__((__packed__));
uint16_t bitmap;
uint32_t id1;
uint32_t id2;
} __attribute__((__packed__)) * reply= (void *) buf;
struct uidgid *uidgid = other;
unsigned short bitmap;
uidgid->uid=0;
uidgid->gid=0;
if (size < sizeof (struct dsi_header))
return -1;
bitmap=ntohs(reply->bitmap);
if (reply->header.return_code.error_code!=kFPNoErr) return -1;
if (bitmap & kFPGetUserInfo_USER_ID) {
uidgid->uid=ntohl(reply->id1);
if (bitmap & kFPGetUserInfo_PRI_GROUPID)
uidgid->gid=ntohl(reply->id2);
goto out;
}
if (bitmap & kFPGetUserInfo_PRI_GROUPID) {
uidgid->gid=ntohl(reply->id1);
}
out:
return 0;
}
int afp_mapid(struct afp_server * server, unsigned char subfunction,
unsigned int id, char *name)
{
struct {
struct dsi_header dsi_header __attribute__((__packed__));
uint8_t command;
uint8_t subfunction;
uint32_t id;
} __attribute__((__packed__)) request;
int ret;
dsi_setup_header(server,&request.dsi_header,DSI_DSICommand);
request.command=afpMapID;
request.subfunction=subfunction;
request.id=htonl(id);
ret=dsi_send(server, (char *) &request,sizeof(request),
DSI_DEFAULT_TIMEOUT,afpMapID,(void *) name);
return ret;
}
int afp_mapid_reply(struct afp_server *server, char * buf, unsigned int size, void *other)
{
struct {
struct dsi_header header __attribute__((__packed__));
char * name ;
} __attribute__((__packed__)) * reply= (void *) buf;
char * name = other;
if (size < sizeof (struct dsi_header))
return -1;
if (reply->header.return_code.error_code!=kFPNoErr) return -1;
copy_from_pascal_two(name, &reply->name, 255);
return 0;
}
int afp_mapname(struct afp_server * server, unsigned char subfunction,
char * name, unsigned int * id)
{
struct {
struct dsi_header dsi_header __attribute__((__packed__));
uint8_t command;
uint8_t subfunction;
} __attribute__((__packed__)) * request;
unsigned int len=sizeof(*request)+
1 + strlen(name);
char * msg, * nameptr;
int ret;
if ((msg=malloc(len)) == NULL)
return -1;
memset(msg,0x4b,len);
nameptr=msg+sizeof(*request);
request = (void *) msg;
copy_to_pascal(nameptr,name);
dsi_setup_header(server,&request->dsi_header,DSI_DSICommand);
request->command=afpMapName;
request->subfunction=subfunction;
ret=dsi_send(server, (char *) request,len,
DSI_DEFAULT_TIMEOUT,afpMapName,(void *) id);
free(msg);
return ret;
}
int afp_mapname_reply(struct afp_server *server, char * buf, unsigned int size, void *other)
{
struct {
struct dsi_header header __attribute__((__packed__));
uint32_t id ;
} __attribute__((__packed__))* reply= (void *) buf;
unsigned int * id = (void *) other;
if (size < sizeof (struct dsi_header))
return -1;
*id=ntohl(reply->id);
return 0;
}