root后台service

Android里面权限控制的比较严,一般的应用当需要使用系统或者root权限是,比较麻烦,所以编写一个root service用来处理root权限请求,通过socket通信

/* 标准头文件放在前面,否则有些函数定义会被覆盖掉 */
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>

#define LOG_TAG "ROOT_SERVER"
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/un.h>

#include <sys/wait.h>

#include "mjson.h"

#include <cutils/log.h>
#include <cutils/sockets.h>

#define SERVER_NAME "@server_root_permission_socket"


#define MAX_PARAM_NUM  10

typedef enum e_root_call_type
{
	ROOT_SYSTEM_CALL,
	ROOT_SYSTEM_EXE,
};


static inline long long current_time_millis(){
	struct timeval tv[1];
	gettimeofday(tv, NULL);
	return((long long)tv->tv_sec) * 1000 + tv->tv_usec/1000;
}


/* 检测状态,timeout单位ms, timeout=-1表示无限等待 */
int main(int argc, char **argv)
{

	int server_sockfd ;
	int client_sockfd ;
	socklen_t server_len, client_len;
	struct sockaddr_un client_addr;
	int nread;
	int i = 0;
	json_t*root = NULL, *q = NULL;
	char* json = NULL;
	int  recv_len;
	int param_len = 0;
	char buffer[1024];
	int ret = -1;
	fd_set read_fds;
	int max = 0;
	e_root_call_type type = ROOT_SYSTEM_CALL;

	//delete the old server socket
	unlink(SERVER_NAME);
	//create socket
	server_sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
	LOGI("server_sockfd = %d", server_sockfd);
	if( -1 == server_sockfd )
	{
		LOGE("[%s] [%s] [%d] server_sockefd creat error",__FUNCTION__, __FILE__, __LINE__);
		return -1;
	}
	//set server addr_param
	struct sockaddr_un server_addr;  
	server_addr.sun_family = AF_UNIX;  
	strncpy(server_addr.sun_path, SERVER_NAME, sizeof(server_addr.sun_path) - 1);
	
	ret = bind(server_sockfd,(struct sockaddr*)&server_addr,sizeof(server_addr));
	if (ret == -1) {
		LOGI("cannot bind server socket");
		return -1;
	}

	//listen the server
	listen(server_sockfd, 5);
	client_sockfd = -1;
	memset(&client_addr,0,sizeof(struct sockaddr_un));
	client_len = sizeof(client_addr);
	sleep(1);
	
	FD_SET(server_sockfd, &read_fds);
	max = server_sockfd;
	mjson_init();
	while(1)
	{
		LOGI("before select");
		usleep(100*1000);
		memset(buffer, 0x0, sizeof(buffer));
		if ((ret = select(max + 1, &read_fds, NULL, NULL, NULL)) < 0) {
            LOGI("select failed (%s)", strerror(errno));
            sleep(1);
            continue;
        } else if (!ret)
            continue; 
		LOGI("ret select-------------");

		if ((client_sockfd = accept(server_sockfd,(struct sockaddr*)&client_addr, &client_len)) < 0) 
		{
		    LOGI("accept failed (%s)", strerror(errno));
		    sleep(1);
		    continue;
		}
		LOGI("client_sockfd = %d", client_sockfd);
		//read  data from client socket
		nread = read( client_sockfd, ¶m_len, 4);
		if (nread != 0) {//client disconnected
			LOGI("client %d receive nothing\n", client_sockfd);
		}  
		LOGI("param_len = %d", param_len);
		nread = read( client_sockfd, buffer, param_len);
		if (nread != 0) {//client disconnected
			LOGI("client %d receive nothing\n", client_sockfd);
		} 
		LOGI("nread = %d", nread);
		LOGI("buffer = %s", buffer);
		json = buffer;

		if (mjson_parse(&root, (char*) json) != 0) 
		{
			LOGE("json parse failed11!\n");
			ret = -1;
			goto BAIL;
		}

		if (mjson_try_begin() < 0) 
		{
			LOGE("invalid !!!\n");
			ret = -1;
			goto BAIL;
		}
		
		q = root;

		type =(e_root_call_type) mjson_locate_number(q, "call_type");
		LOGI("call_type = %d", type);
		if(ROOT_SYSTEM_CALL == type)
		{
			char *fuction_name = NULL;
			fuction_name = mjson_locate_string(q, "fuction_name");
			LOGI("fuction_name = %s", fuction_name);
			LOGI("strlen(fuction_name) = %d", strlen(fuction_name));
			if(strstr(fuction_name, "settimeofday") != NULL) 
			{
				struct timeval tms;
				tms.tv_sec = mjson_locate_number(q, "tms.tv_sec");
				tms.tv_usec = mjson_locate_number(q, "tms.tv_usec");

				LOGI("tms.tv_sec = %d", tms.tv_sec);
				LOGI("tms.tv_usec = %d", tms.tv_usec);
				ret = settimeofday(&tms, NULL);
				LOGI("ret = %d", ret);
				
			}
		}
		else if(ROOT_SYSTEM_EXE == type)
		{
			int pid    = 0;
			int param_num = 0;
			int wait_flag = 0, status = 0;
			char *exe_name = NULL;
			char *param_array[MAX_PARAM_NUM];
			char param_name[64];
			exe_name = mjson_locate_string(q, "exe_name");
			param_num = mjson_locate_number(q, "param_num");
			wait_flag = mjson_locate_number(q, "wait_flag");
			LOGI( "exe_name= %s, param_num = %d, wait_flag = %d", exe_name, param_num, wait_flag);
			/*vfork 创建进程*/
			pid = vfork();
			if (pid < 0)
			{
				LOGI( "(out)vfork error");
				goto BAIL;
			}
			if (0 == pid)
			{
				for(i = 0; i < param_num; i++)
				{
					sprintf(param_name, "param%d", i);
					param_array[i] = mjson_locate_string(q, param_name);
					LOGI( "param_name= %s, param_array[%d] = %s", param_name, i, param_array[i]);
				}
				switch(param_num)
				{
					case 0:
						ret = execl(exe_name, exe_name, (char*)0);
						break;

					case 1:
						ret = execl(exe_name, exe_name, param_array[0], (char*)0);
						break;

					case 2:
						ret = execl(exe_name, exe_name, param_array[0], param_array[1], (char*)0);
						break;

					case 3:
						ret = execl(exe_name, exe_name, param_array[0], param_array[1], param_array[2], (char*)0);
						break;

					case 4:
						ret = execl(exe_name, exe_name, param_array[0], param_array[1], param_array[2], param_array[3], (char*)0);
						break;

					case 5:
						ret = execl(exe_name, exe_name, param_array[0], param_array[1], param_array[2], param_array[3], param_array[4], (char*)0);
						break;

					case 6:
						ret = execl(exe_name, exe_name, param_array[0], param_array[1], param_array[2], param_array[3], param_array[4], param_array[5], (char*)0);
						break;

					case 7:
						ret = execl(exe_name, exe_name, param_array[0], param_array[1], param_array[2], param_array[3], param_array[4], param_array[5], 
							 param_array[6], (char*)0);
						break;

					case 8:
						ret = execl(exe_name, exe_name, param_array[0], param_array[1], param_array[2], param_array[3], param_array[4], param_array[5], 
							 param_array[6], param_array[7], (char*)0);

					case 9:
						ret = execl(exe_name, exe_name, param_array[0], param_array[1], param_array[2], param_array[3], param_array[4], param_array[5], 
							 param_array[6], param_array[7],param_array[8],(char*)0);
						break;

					case 10:
						ret = execl(exe_name, exe_name, param_array[0], param_array[1], param_array[2], param_array[3], param_array[4], param_array[5], 
							 param_array[6], param_array[7], param_array[8], param_array[9], (char*)0);
						break;
				}

				if(ret < 0)
				{
					LOGI( "(out)Err on execl");
					_exit(0);
				}
			}
			else
			{
				if(wait_flag)
				{
					/*等待进程结束*/
					LOGI(  "waitpid pid:%d", pid);
					while(waitpid(pid, &status, 0) < 0)
					{
						LOGI(  "waitpid error pid:%d", pid);
						goto BAIL;
					}
					LOGI( "waitpid out pid:%d", pid);

				}
			}		
	}
	ret = write(client_sockfd, &ret, 4);
	LOGI("ret = %d", ret);	
	
	BAIL:
		close(client_sockfd);
		mjson_try_end();
		
	}
	return 0;


}

以json方式传递数据,server解析

client 一个例子:

define SERVER_NAME "@server_root_permission_socket"

static inline long long current_time_millis(){
	struct timeval tv[1];
	gettimeofday(tv, NULL);
	return((long long)tv->tv_sec) * 1000 + tv->tv_usec/1000;
}

int do_root_call(char *json)
{
	int sockfd;
	int len = -1;
	int ret = -1;
	int result;
	sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
	if( -1 == sockfd ){
		porting_error(PORT_MODULE_BASE,"[%s] [%d] sockfd creat error",__FUNCTION__, __LINE__);
		return -1;
	}

	struct sockaddr_un address;  
	address.sun_family = AF_UNIX;  
	strcpy(address.sun_path, SERVER_NAME); 
	ret = connect(sockfd, (struct sockaddr *)&address, sizeof(address)); 
	if (ret == -1) {
		porting_error(PORT_MODULE_BASE,"[%s] [%d] client connect error",__FUNCTION__, __LINE__);
		return -1;
	}
	porting_info(PORT_MODULE_BASE,"sockfd = %d", sockfd);
	porting_info(PORT_MODULE_BASE,"result = %d", ret);
	len = strlen(json);
	ret = write(sockfd, &len, 4);
	porting_info(PORT_MODULE_BASE,"ret2 = %d", ret);
	porting_info(PORT_MODULE_BASE,"json = %s", json);
	ret = write(sockfd, json, strlen(json));
	porting_info(PORT_MODULE_BASE,"ret3 = %d", ret);
	read( sockfd, &ret, 4);
	porting_info(PORT_MODULE_BASE,"ret4 = %d", ret);
	close(sockfd);
	sockfd = -1;
	porting_info(PORT_MODULE_BASE," client ok");
	return 0;
}


http://download.csdn.net/detail/new_abc/5087048


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值