예제 #1
0
/*
 * Returns a PayloadType from the local list that matches a PayloadType offered or answered in the remote list
*/
static PayloadType * find_payload_type_best_match(const MSList *l, const PayloadType *refpt){
	PayloadTypeMatcher *m;
	for(m=matchers;m->mime_type!=NULL;++m){
		if (refpt->mime_type && strcasecmp(m->mime_type,refpt->mime_type)==0){
			return m->match_func(l,refpt);
		}
	}
	return generic_match(l,refpt);
}
예제 #2
0
/*
 * Returns a PayloadType from the local list that matches a PayloadType offered or answered in the remote list
*/
static PayloadType * find_payload_type_best_match(MSFactory *factory, const MSList *local_payloads, const PayloadType *refpt,
						  const MSList *remote_payloads, bool_t reading_response){
	PayloadType *ret = NULL;
	MSOfferAnswerContext *ctx = ms_factory_create_offer_answer_context(factory, refpt->mime_type);
	if (ctx){
		ms_message("Doing offer/answer processing with specific provider for codec [%s]", refpt->mime_type); 
		ret = ms_offer_answer_context_match_payload(ctx, local_payloads, refpt, remote_payloads, reading_response);
		ms_offer_answer_context_destroy(ctx);
		return ret;
	}
	return generic_match(local_payloads, refpt, remote_payloads);
}
예제 #3
0
/**
 * @brief Handle inotify events
 *
 * Calls the callcbacks
 *
 * @param files nb max of logs destination directories (crashlog,
 * aplogs, bz... )
 *
 * @return 0 on success, -1 on error.
 */
int receive_inotify_events(int inotify_fd) {
    int len = 0, orig_len, idx, wd, missing_bytes;
    char orig_buffer[sizeof(struct inotify_event)+PATHMAX], *buffer, lastevent[sizeof(struct inotify_event)+PATHMAX];
    struct inotify_event *event;
    struct watch_entry *entry = NULL;

    len = read(inotify_fd, orig_buffer, sizeof(orig_buffer));
    if (len < 0) {
        LOGE("%s: Cannot read file_monitor_fd, error is %s\n", __FUNCTION__, strerror(errno));
        return -errno;
    }

    buffer = &orig_buffer[0];
    orig_len = len;
    event = (struct inotify_event *)buffer;

    /* Preinitialize lastevent (in case it was not used so it is not dumped) */
    ((struct inotify_event *)lastevent)->wd = 0;
    ((struct inotify_event *)lastevent)->mask = 0;
    ((struct inotify_event *)lastevent)->cookie = 0;
    ((struct inotify_event *)lastevent)->len = 0;

    while (1) {
        if (len == 0) {
            /* End of the events to read */
            return 0;
        }
        if ((unsigned int)len < sizeof(struct inotify_event)) {
            /* Not enough room for an empty event */
            LOGI("%s: incomplete inotify_event received (%d bytes), complete it\n", __FUNCTION__, len);
            /* copy the last bytes received */
            if( (unsigned int)len <= sizeof(lastevent) )
                memcpy(lastevent, buffer, len);
            else {
                LOGE("%s: Cannot copy buffer\n", __FUNCTION__);
                return -1;
            }
            /* read the missing bytes to get the full length */
            missing_bytes = (int)sizeof(struct inotify_event)-len;
            if(((int) len + missing_bytes) < ((int)sizeof(lastevent))) {
                if (read(inotify_fd, &lastevent[len], missing_bytes) != missing_bytes ){
                    LOGE("%s: Cannot complete the last inotify_event received (structure part) - %s\n", __FUNCTION__, strerror(errno));
                    return -1;
                }
            }
            else {
                LOGE("%s: Cannot read missing bytes, not enought space in lastevent\n", __FUNCTION__);
                return -1;
            }
            event = (struct inotify_event*)lastevent;
            /* now, reads the full last event, including its name field */
            if ( read(inotify_fd, &lastevent[sizeof(struct inotify_event)],
                event->len) != (int)event->len) {
                LOGE("%s: Cannot complete the last inotify_event received (name part) - %s\n",
                    __FUNCTION__, strerror(errno));
                return -1;
            }
            len = 0;
            /* now, the last event is complete, we can continue the parsing */
        } else if ( (unsigned int)len < sizeof(struct inotify_event) + event->len ) {
            int res, missing_bytes = (int)sizeof(struct inotify_event) + event->len - len;
            event = (struct inotify_event*)lastevent;
            /* The event was truncated */
            LOGI("%s: truncated inotify_event received (%d bytes missing), complete it\n", __FUNCTION__, missing_bytes);

            /* Robustness : check 'lastevent' array size before reading inotify fd*/
            if( (unsigned int)len > sizeof(lastevent) ) {
                LOGE("%s: not enough space on array lastevent.\n", __FUNCTION__);
                return -1;
            }
            /* copy the last bytes received */
            memcpy(lastevent, buffer, len);
            /* now, reads the full last event, including its name field */
            res = read(inotify_fd, &lastevent[len], missing_bytes);
            if ( res != missing_bytes ) {
                LOGE("%s: Cannot complete the last inotify_event received (name part2); received %d bytes, expected %d bytes - %s\n",
                    __FUNCTION__, res, missing_bytes, strerror(errno));
                return -1;
            }
            len = 0;
            /* now, the last event is complete, we can continue the parsing */
        } else {
            event = (struct inotify_event *)buffer;
            buffer += sizeof(struct inotify_event) + event->len;
            len -= sizeof(struct inotify_event) + event->len;
        }
        /* Handle the event read from the buffer*/
        /* First check the kind of the subject of this event (file or directory?) */
        if (!(event->mask & IN_ISDIR)) {
            /* event concerns a file into a watched directory */
            entry = get_event_entry(event->wd, (event->len ? event->name : NULL));
            if ( !entry ) {
                /* Didn't find any entry for this event, check for
                 * a dropbox final event... */
                if (event->len > 8 && !strncmp(event->name, "dropbox-", 8)) {
                    /* dumpstate is done so remove the watcher */
                    LOGD("%s: Received a dropbox event(%s)...",
                        __FUNCTION__, event->name);
                    inotify_rm_watch(inotify_fd, event->wd);
                    finalize_dropbox_pending_event(event);
                    continue;
                }
                /* Stray event... */
                LOGD("%s: Can't handle the event \"%s\", no valid entry found, drop it...\n",
                    __FUNCTION__, (event->len ? event->name : "empty event"));
                continue;
            }
        }
        /*event concerns a watched directory itself */
        else {
            entry = NULL;
            /* Manage case where a watched directory is deleted*/
            if ( event->mask & (IN_DELETE_SELF | IN_MOVE_SELF) ) {
                /* Recreate the dir and reinstall the watch */
                for (idx = 0 ; idx < (int)DIM(wd_array) ; idx++) {
                    if ( wd_array[idx].wd == event->wd )
                        entry = &wd_array[idx];
                }
                if ( entry && entry->eventpath ) {
                    mkdir(entry->eventpath, 0777); /* TO DO : restoring previous rights/owner/group ?*/
                    inotify_rm_watch(inotify_fd, event->wd);
                    wd = inotify_add_watch(inotify_fd, entry->eventpath, entry->eventmask);
                    if ( wd < 0 ) {
                        LOGE("Can't add watch for %s.\n", entry->eventpath);
                        return -1;
                    }
                    LOGW("%s: watched directory %s : \'%s\' has been created and snooped",__FUNCTION__,
                            (event->mask & (IN_DELETE_SELF) ? "deleted" : "moved"), entry->eventpath);
                    /* if the watch was duplicated, set it for all the entries */
                    for (idx = 0 ; idx < (int)DIM(wd_array) ; idx++) {
                        if (wd_array[idx].wd == event->wd)
                            wd_array[idx].wd = wd;
                    }
                    /* Do nothing more on directory events */
                    continue;
                }
            }
            else {
                for (idx = 0 ; idx < (int)DIM(wd_array) ; idx++) {
                    if ( wd_array[idx].wd != event->wd )
                        continue;
                    entry = &wd_array[idx];
                    /* for modem generic */
                    /* TO IMPROVE : change flag management and put this in main loop */
                    if(strstr(LOGS_MODEM_DIR, entry->eventpath) && (generic_match(event->name, g_first_modem_config))){
                        process_modem_generic(entry, event, inotify_fd);
                        break;
                    }
                }
                pconfig check_config = generic_match_by_wd(event->name, g_first_modem_config, event->wd);
                if(check_config){
                        process_modem_generic( &check_config->wd_config, event, inotify_fd);
                }else{
                    LOGE("%s: Directory not catched %s.\n", __FUNCTION__, event->name);
                }
                /* Do nothing more on directory events */
                continue;
            }
        }
        if ( entry && entry->pcallback && entry->pcallback(entry, event) < 0 ) {
            LOGE("%s: Can't handle the event %s...\n", __FUNCTION__,
                event->name);
            dump_inotify_events(orig_buffer, orig_len, lastevent);
            return -1;
        }
    }

    return 0;
}