int find_monitor_file_type(monitor_dirs *md, const char *path)
{
    int type = 0, found = NFOUND;
    string save_path(path, strlen(path));
    monitor_dir dirobj;
    vector<string> vAllParents;

    memset(&dirobj, 0, sizeof(dirobj));
    vAllParents.clear();

    if ((NULL == md) || (NULL == path) || (0 == strlen(path)))
    {
        debug_sys(LOG_ERR, "illegal parameter!\n");
        return 0;
    }

    get_all_parent_dir((char *)save_path.c_str(), vAllParents);
    for (vector<string>::iterator it = vAllParents.begin();
         it != vAllParents.end(); it++)
    {
        if (find_monitor_dir(md, (char *)it->c_str(), &dirobj) == FOUND)
        {
            debug_sys(LOG_DEBUG, "path:%s, parent path with type:%s\n", save_path.c_str(), (char *)it->c_str());
            type = dirobj.is_counter_size;
            found = FOUND;
            break;
        }
    }

    if (found == NFOUND)
    {
        debug_sys(LOG_ERR, "Failed to find the parent for %s!, use the default value 0\n", path);
    }
    return type;
}
int add_monitor_dir(monitor_dirs *md, char *path, int &level, int is_counter_size)
{
    monitor_dir *tmp = NULL;
    monitor_dir *newone = NULL;

    debug_sys(LOG_NOTICE, "begin to add_monitor_dir for %s\n", path);

    pthread_rwlock_wrlock(&md->md_lock);
    if (__find_monitor_dir(md, path, &tmp) == FOUND)
    {
        debug_sys(LOG_NOTICE, "path exist, skip add monitor %s\n", path);
        pthread_rwlock_unlock(&md->md_lock);
        return FOUND;
    }

    newone = (monitor_dir *)calloc(1, sizeof(monitor_dir));
    if (newone == NULL)
    {
        debug_sys(LOG_ERR, "Allocate memory failed for %s\n", path);
        pthread_rwlock_unlock(&md->md_lock);
        return ERROR;
    }

    snprintf(newone->dir_name, MAX_PATH, "%s", path);
    newone->directory_level = __find_monitor_file_level(md, path, level);
    newone->file_status = 1;
    newone->is_counter_size = is_counter_size;
    md->md.insert(make_pair(string(path, strlen(path)), newone));
    md->md_mum++;
    pthread_rwlock_unlock(&md->md_lock);

    level = newone->directory_level;

    return SUCC;
}
int main(const int argc, const char *argv[])
{
	int server_fd, client_fd;
	int read_size;
	short cmd_len;
	struct sockaddr addr;
	socklen_t alen;

	info_sys("backuprestore service start!");

	if ((server_fd = srv_create_sk()) < 0)
		err_sys("create socket server error");
	alen = sizeof(addr);

	info_sys("Server socket create successfully!");

	while(1){
		client_fd = accept(server_fd, (struct sockaddr*) &addr, &alen);
		if (client_fd < 0) {
			debug_sys("socket accept failed, please try again!");
			continue;
		}
		info_sys("before excute");
		while (1) {
			cmd_len = 0;
			if (readx(client_fd, &cmd_len, sizeof(cmd_len)) <= 0){
				debug_sys("cmd length read fail");
				break;
			}

			if (cmd_len < 1 || cmd_len > 2048){
				debug_sys("cmd length is not right");
				break;
			}

			if (readx(client_fd, &cmd, cmd_len) <= 0){
				debug_sys("read cmd fail");
				break;
			}
			cmd[cmd_len] = 0;
			if (excute(client_fd, cmd) < 0)
				break;
		}
		close(client_fd);
	}
	close(server_fd);
	info_sys("backuprestore service end!");
	return EXIT_SUCCESS;
}
int add_monitor_dir_inotify(monitor_dirs *md, char *path, int level, int is_counter_size, int f)
{
    debug_sys(LOG_NOTICE, "Add dir inotify for %s\n", path);

    if (!file_exist(path))
    {
        debug_sys(LOG_ERR, "file %s not exist\n", path);
        return ERROR;
    }

    if (add_monitor_dir(md, path, level, is_counter_size) == SUCC || f == 1)
    {
        return add_dir_inotify(md, path, level);
    }
    return SUCC;
}
int add_exclude_pattern(char *dirpattern , exclude_dir_array *ed)
{
    const char *error = NULL;
    int erroffset = 0;
    pcre *re = NULL;
    edir dir_tmp;

    pthread_mutex_lock(&ed->ex_lock);
    if (__find_exclude_pattern(dirpattern, ed) == FOUND)
    {
        pthread_mutex_unlock(&ed->ex_lock);
        return FOUND;
    }

    re = pcre_compile(dirpattern, 0, &error, &erroffset, NULL);
    if (re == NULL)
    {
        pthread_mutex_unlock(&ed->ex_lock);
        debug_sys(LOG_ERR, "PCRE compilation telephone failed at offset %d: %s\n", erroffset,  error);
        return ERROR;
    }

    dir_tmp.dirpattern = string(dirpattern, strlen(dirpattern));
    dir_tmp.re = re;
    ed->vdirs.push_back(dir_tmp);
    pthread_mutex_unlock(&ed->ex_lock);

    return NFOUND;
}
static int srv_create_sk()
{
	int lsocket;
	info_sys("Get socket from Android env!");
	lsocket = android_get_control_socket(SOCKET_PATH);
	if (lsocket < 0){ 
		debug_sys("Failed to get socket from environment");
        return -1;
    }
	
	if (listen(lsocket, QBACKLOG)) {
		debug_sys("Listen on socket failed");
        return -1;
	}
	fcntl(lsocket, F_SETFD, FD_CLOEXEC);
	return lsocket;
}
static int readx(int socket, void* buf, int count)
{
    int num = 0, rx = 0;
    char* _buf = buf;
    if (count <= 0) return -1;
    
    while (num < count){
        rx = read(socket, _buf + num, count - num);
        if (rx < 0){
            if (errno == EINTR) continue;
            debug_sys("read error");
            return -1;
        }
        else if (!rx){
            debug_sys("read the end of file");
            return -1;
        }
        num += rx;
    }
    return 1;
}
int add_dir_inotify(monitor_dirs *md, char *path, int level)
{
    char **exclude_dirs = NULL;
    int ret, size = 0;
    vector<string> vSubdirs;
    vSubdirs.clear();
    string debug_string = "";

    get_sub_exclude_dir(path, &md->ex_dirs, vSubdirs);

    debug_sys(LOG_DEBUG, "add intotify for dir %s\n", path);
    size = vSubdirs.size();
    if (size > 0)
    {
        exclude_dirs = (char **)calloc(size + 1, sizeof(char *));
        if (exclude_dirs == NULL)
        {
            debug_sys(LOG_ERR, "malloc failed for %s\n", path);
            return -1;
        }
        for (int i = 0; i < size; i++)
        {
            exclude_dirs[i] = strdup((char *)vSubdirs[i].c_str());
        }
    }
    ret = add_notify_dir(path, g_events, level + 1, exclude_dirs);

    if (exclude_dirs != NULL)
    {
        for (int i = 0; i < size; i++)
        {
            char *p = exclude_dirs[i];
            my_free(p);
        }
        my_free(exclude_dirs);
    }
    return SUCC;
}
int del_monitor_dir_inotify(monitor_dirs *md, char *path)
{
    debug_sys(LOG_NOTICE, "Delete dir inotify for %s\n", path);
    /*
        if (file_exist(path))
        {
            debug_sys(LOG_ERR, "Path %s should not exist\n", path);
            return ERROR;
        }
    */
    del_monitor_dir(md, path);
    inotifytools_remove_watch_by_filename(path);
    return SUCC;
}
void print_directory_sort(monitor_dirs *md)
{
    string debug_string;
    vector<monitor_dir> vDirs;
    vDirs.clear();
    sort_monitor_dirs(md, vDirs);
    for (vector<monitor_dir>::iterator it = vDirs.begin();
         it != vDirs.end(); it++)
    {
        char tmpstr[1024] = {0};
        monitor_dir dirinfo = *it;
        snprintf(tmpstr, 1024, "dir name %s, status %d, dirsize %lld, dircount %lld\n",
                 dirinfo.dir_name, dirinfo.file_status, dirinfo.fi.filesz, dirinfo.fi.filenm);
        debug_string += string(tmpstr);
    }
    debug_sys(LOG_NOTICE, "%s\n", debug_string.c_str());
}
static int writex(int socket, const void* buf, int count)
{
    int num = 0, tx = 0;
    char* _buf = buf;
    if (count <= 0)
        return -1;
    while (num < count){
        tx = write(socket, buf + tx, count - tx);
        if (tx < 0){            
            if (errno == EINTR) continue;
            debug_sys("write error");
            return -1;
        }
        num += tx;            
    }
    return 1;
}
static int parseCmd(char* cmd)
{
    int i = 0;
    cmdArgs[i++] = cmd;
    while(*cmd){
        if(*cmd == ' '){
            *cmd++ = '\0';
            if (i < MAX_TOKEN)
                cmdArgs[i++] = cmd;
            else {
                debug_sys("argr count error!");
                return -1;
            }
        }
        ++cmd;
    }
    return i;
}
static int excute(int socket, char* cmd){
    int argsCnt = 0, i = 0;
    short ret = -1;
    char reply[REPLY_LEN];
    if ((argsCnt = parseCmd(cmd)) < 0)
        goto done;

    for (i = 0; i < sizeof(cmds)/sizeof(cmds[0]); ++i){
        if (!strcmp(cmds[i].cmd_name, cmdArgs[0])){
            if (cmds[i].cmd_args_cnt != argsCnt)
            {
                debug_sys("cmds args is not map");
                goto done;               
            }
            else
            {
                ret = cmds[i].excute(cmdArgs + 1, reply);
                break;
            }            
        }
    }           
done:   
    return writex(socket, (char*)&ret, 2);
}