#include <&stdio.h&>
#include <&stdlib.h&>
#include <&sys/socket.h&>
#include <&sys/un.h&>
#include <&stddef.h&>
#include <&errno.h&>
#include <&time.h&>
#define LOCAL_SOCK_PATH "/com/jeffliao/localserver"
#define MY_MAGIC "jeff-liao"
#define DEBUGFMT "%s(%d)-%s"
#define DEBUGARGS __FILE__,__LINE__,__FUNCTION__
struct my_msg {
char magic[32];
char buf[256];
};
int local_sock = -1;
static int init_local_server_socket(void);
static void get_local_msg(void);
static void send_local_msg(char * str);
int main (int argc, char *argv[], char *envp[]){
fd_set readfds;
int maxfd;
int fdcount;
struct timeval tv;
if(argc >= 2) {
if(!strcmp(argv[1],"client" )){
send_local_msg("Hello Jeff!");
}else if(!strcmp(argv[1],"server" )){
if ( init_local_server_socket() < 0){
err(" init_local_server_socket error!\n");
close(local_sock);
return 1;
}
maxfd=local_sock;
while (1){
FD_ZERO(&readfds);
FD_SET(local_sock, &readfds);
tv.tv_sec = 5;
tv.tv_usec = 0;
fdcount = select(maxfd+1, &readfds, NULL, NULL, &tv);
if (fdcount < 0) {
if (errno != EINTR)
err("error in select: %s\n", strerror(errno));
continue;
}
if (FD_ISSET(local_sock, &readfds))
//printf("get message!!\n");
get_local_msg();
}
}
}else{
printf("Please give one parameter.\n");
return 0;
}
return 0;
}
static void send_local_msg(char * str){
int sock = -1;
struct my_msg ctrl_msg;
struct sockaddr_un saddr;
socklen_t addrlen;
int retval = 1;
sock = socket(AF_LOCAL, SOCK_DGRAM, 0);
memset(&ctrl_msg, 0x00, sizeof(struct my_msg));
strcpy(ctrl_msg.magic, MY_MAGIC);
strcpy(ctrl_msg.buf, str);
if (sock == -1) {
err("error getting socket: %s\n", strerror(errno));
exit(0);
}
memset(&saddr, 0x00, sizeof(struct sockaddr_un));
saddr.sun_family = AF_LOCAL;
/* use abstract namespace for socket path */
strcpy(&saddr.sun_path[1], LOCAL_SOCK_PATH);
addrlen = offsetof(struct sockaddr_un, sun_path) + 1 + strlen(&saddr.sun_path[1]);
retval = sendto(sock, &ctrl_msg, sizeof(ctrl_msg), 0, (struct sockaddr *)&saddr, addrlen);
if (retval == -1) {
err("error sending message: %s\n", strerror(errno));
retval = 1;
} else {
printf("sent message=%s\n", ctrl_msg.buf);
retval = 0;
}
close(sock);
}
static void get_local_msg(void){
struct my_msg ctrl_msg;
ssize_t size;
struct msghdr smsg;
struct cmsghdr *cmsg;
struct iovec iov;
struct ucred *cred;
char cred_msg[CMSG_SPACE(sizeof(struct ucred))];
char *pos;
//printf (DEBUGFMT "\n",DEBUGARGS);
memset(&ctrl_msg, 0x00, sizeof(struct my_msg));
//printf (DEBUGFMT "\n",DEBUGARGS);
iov.iov_base = &ctrl_msg;
//printf (DEBUGFMT "\n",DEBUGARGS);
iov.iov_len = sizeof(struct my_msg);
//printf (DEBUGFMT "\n",DEBUGARGS);
memset(&smsg, 0x00, sizeof(struct msghdr));
//printf (DEBUGFMT "\n",DEBUGARGS);
smsg.msg_iov = &iov;
//printf (DEBUGFMT "\n",DEBUGARGS);
smsg.msg_iovlen = 1;
//printf (DEBUGFMT "\n",DEBUGARGS);
smsg.msg_control = cred_msg;
//printf (DEBUGFMT "\n",DEBUGARGS);
smsg.msg_controllen = sizeof(cred_msg);
//printf (DEBUGFMT "\n",DEBUGARGS);
size = recvmsg(local_sock, &smsg, 0);
if (size < 0) {
printf (DEBUGFMT "\n",DEBUGARGS);
if (errno != EINTR)
err("unable to receive user udevd message: %s\n", strerror(errno));
return;
}
//printf (DEBUGFMT "\n",DEBUGARGS);
cmsg = CMSG_FIRSTHDR(&smsg);
//printf (DEBUGFMT "\n",DEBUGARGS);
cred = (struct ucred *) CMSG_DATA(cmsg);
//printf (DEBUGFMT "\n",DEBUGARGS);
if (cmsg == NULL || cmsg->cmsg_type != SCM_CREDENTIALS) {
//printf (DEBUGFMT "\n",DEBUGARGS);
err("no sender credentials received, message ignored\n");
return;
}
printf("sender uid=%i\n",cred->uid);
//printf (DEBUGFMT "\n",DEBUGARGS);
//if (cred->uid != 0) {
// printf (DEBUGFMT "\n",DEBUGARGS);
// err("sender uid=%i, message ignored\n", cred->uid);
// return;
//}
//printf (DEBUGFMT "\n",DEBUGARGS);
if (strncmp(ctrl_msg.magic, MY_MAGIC, sizeof(MY_MAGIC)) != 0 ) {
//printf (DEBUGFMT "\n",DEBUGARGS);
err("message magic '%s' doesn't match, ignore it\n", ctrl_msg.magic);
return;
}
//printf (DEBUGFMT "\n",DEBUGARGS);
printf("recieve message=%s\n", ctrl_msg.buf);
}
static int init_local_server_socket(void){
struct sockaddr_un saddr;
socklen_t addrlen;
const int feature_on = 1;
int retval;
memset(&saddr, 0x00, sizeof(saddr));
saddr.sun_family = AF_LOCAL;
/* use abstract namespace for socket path */
strcpy(&saddr.sun_path[1], LOCAL_SOCK_PATH );
addrlen = offsetof(struct sockaddr_un, sun_path) + 1 + strlen(&saddr.sun_path[1]);
local_sock = socket(AF_LOCAL, SOCK_DGRAM, 0);
if (local_sock == -1) {
printf("error getting socket: %s\n", strerror(errno));
return -1;
}
/* the bind takes care of ensuring only one copy running */
retval = bind(local_sock, (struct sockaddr *) &saddr, addrlen);
if (retval < 0) {
printf("bind failed: %s\n", strerror(errno));
close(local_sock);
local_sock = -1;
return -1;
}
/* enable receiving of the sender credentials */
setsockopt(local_sock, SOL_SOCKET, SO_PASSCRED, &feature_on, sizeof(feature_on));
return 0;
}
沒有留言:
張貼留言