static int parse_tracks(ezxml_t xml, struct track* t, bool ordered) { int track_count = 0; struct track* prev = NULL; struct track* root = t; for (ezxml_t track = ezxml_get(xml, "track",-1); track; track = track->next) { /* is this an ordered list? in that case we have to find the right track struct for every track id */ if (ordered) { char tid[33]; xmlstrncpy(tid, sizeof tid, track, "id", -1); struct track* tt; for (tt = root; tt; tt = tt->next) if (!tt->has_meta_data && !strncmp(tt->track_id, tid, sizeof tt->track_id)) break; /* if we didn't find the id, check if an old, redirected id is used */ if (!tt) { char rid[33]; for (ezxml_t re = ezxml_child(track, "redirect"); re; re = re->next) { strncpy(rid, re->txt, sizeof rid); for (tt = root; tt; tt = tt->next) { /* update to new id */ /* FIXME: This invalidates the playlist checksum */ if (!tt->has_meta_data && !strncmp(tt->track_id, rid, sizeof tt->track_id)) { memcpy (tt->track_id, tid, sizeof tt->track_id); break; } } if (tt) break; } /* we've wasted enough cpu cycles on this track now */ if (!tt) { DSFYDEBUG("!!! error: track id not found: %s\n", tid); continue; } } t = tt; } else if (!t) { t = calloc(1, sizeof(struct track)); prev->next = t; } xmlstrncpy(t->title, sizeof t->title, track, "title", -1); xmlstrncpy(t->album, sizeof t->album, track, "album", -1); xmlstrncpy(t->track_id, sizeof t->track_id, track, "id", -1); xmlstrncpy(t->cover_id, sizeof t->cover_id, track, "cover", -1); xmlstrncpy(t->album_id, sizeof t->album_id, track, "album-id", -1); /* create list of artists */ struct artist* preva = NULL; struct artist* artist = calloc(1, sizeof(struct artist)); t->artist = artist; ezxml_t xid = ezxml_get(track, "artist-id", -1); for (ezxml_t xa = ezxml_get(track, "artist", -1); xa; xa = xa->next) { if (preva) { artist = calloc(1, sizeof(struct artist)); preva->next = artist; } DSFYstrncpy(artist->name, xa->txt, sizeof artist->name); if (xid) { DSFYstrncpy(artist->id, xid->txt, sizeof artist->id); xid = xid->next; } preva = artist; } ezxml_t file = ezxml_get(track, "files",0, "file",-1); if (file) { char* id = (char*)ezxml_attr(file, "id"); if (id) { DSFYstrncpy(t->file_id, id, sizeof t->file_id); t->playable = true; } } xmlatoi(&t->year, track, "year", -1); xmlatoi(&t->length, track, "length", -1); xmlatoi(&t->tracknumber, track, "track-number", -1); xmlatof(&t->popularity, track, "popularity", -1); t->has_meta_data = true; prev = t; t = t->next; track_count++; } return track_count; }
struct playlist* xml_parse_playlist(struct playlist* pl, unsigned char* xml, int len, bool list_of_lists) { ezxml_t top = ezxml_parse_str(xml, len); ezxml_t tmpx = ezxml_get(top, "next-change",0, "change", 0, "ops", 0, "add", 0, "items", -1); char* items = NULL; if (tmpx) items = tmpx->txt; while (items && *items && isspace(*items)) items++; if (list_of_lists) { /* create list of playlists */ struct playlist* prev = NULL; struct playlist* p = pl; for (char* id = strtok(items, ",\n"); id; id = strtok(NULL, ",\n")) { if (prev) { p = calloc(1, sizeof(struct playlist)); prev->next = p; } DSFYstrncpy(p->playlist_id, id, sizeof p->playlist_id); prev = p; } } else { /* create list of tracks */ struct track* prev = NULL; struct track* root = NULL; struct track* t = NULL; int track_count = 0; for (char* id = strtok(items, ",\n"); id; id = strtok(NULL, ",\n")) { t = calloc(1, sizeof(struct track)); if (prev) prev->next = t; else root = t; DSFYstrncpy(t->track_id, id, sizeof t->track_id); prev = t; track_count++; } pl->tracks = root; pl->num_tracks = track_count; // FIXME: <version> parsing overwrites track_count } xmlstrncpy(pl->author, sizeof pl->author, top, "next-change",0, "change", 0, "user", -1); xmlstrncpy(pl->name, sizeof pl->name, top, "next-change",0, "change", 0, "ops",0, "name", -1); xml_parse_version(pl, top, "next-change", 0, "version", -1); ezxml_free(top); return pl; }
static int parse_tracks(ezxml_t xml, struct ds_track* t, bool ordered, bool high_bitrate) { int track_count = 0; struct ds_track* prev = NULL; struct ds_track* root = t; for (ezxml_t track = ezxml_get(xml, "track",-1); track; track = track->next) { /* is this an ordered list? in that case we have to find the right track struct for every track id */ if (ordered) { char tid[33]; xmlstrncpy(tid, sizeof tid, track, "id", -1); struct ds_track* tt; for (tt = root; tt; tt = tt->next) if (!tt->has_meta_data && !strncmp(tt->track_id, tid, sizeof tt->track_id)) break; /* if we didn't find the id, check if an old, redirected id is used */ if (!tt) { char rid[33]; for (ezxml_t re = ezxml_child(track, "redirect"); re; re = re->next) { strncpy(rid, re->txt, sizeof rid); for (tt = root; tt; tt = tt->next) { /* update to new id */ /* FIXME: This invalidates the playlist checksum */ if (!tt->has_meta_data && !strncmp(tt->track_id, rid, sizeof tt->track_id)) { memcpy (tt->track_id, tid, sizeof tt->track_id); break; } } if (tt) break; } /* we've wasted enough cpu cycles on this track now */ if (!tt) { DSFYDEBUG("!!! error: track id not found: %s\n", tid); continue; } } t = tt; } else if (!t) { t = calloc(1, sizeof(struct ds_track)); prev->next = t; } xmlstrncpy(t->title, sizeof t->title, track, "title", -1); xmlstrncpy(t->album, sizeof t->album, track, "album", -1); xmlstrncpy(t->track_id, sizeof t->track_id, track, "id", -1); xmlstrncpy(t->cover_id, sizeof t->cover_id, track, "cover", -1); xmlstrncpy(t->album_id, sizeof t->album_id, track, "album-id", -1); /* create list of artists */ struct ds_artist* preva = NULL; struct ds_artist* artist = calloc(1, sizeof(struct ds_artist)); t->artist = artist; ezxml_t xid = ezxml_get(track, "artist-id", -1); for (ezxml_t xa = ezxml_get(track, "artist", -1); xa; xa = xa->next) { if (preva) { artist = calloc(1, sizeof(struct ds_artist)); preva->next = artist; } DSFYstrncpy(artist->name, xa->txt, sizeof artist->name); if (xid) { DSFYstrncpy(artist->id, xid->txt, sizeof artist->id); xid = xid->next; } preva = artist; } for ( ezxml_t file = ezxml_get(track, "files",0, "file",-1); file; file = file->next) { char* fmt = (char*)ezxml_attr(file, "format"); if (fmt) { unsigned int bitrate; if (sscanf(fmt,"Ogg Vorbis,%u,", &bitrate)) { if (bitrate > t->file_bitrate) { if (high_bitrate || t->file_bitrate == 0) t->file_bitrate = bitrate; else continue; } } char* id = (char*)ezxml_attr(file, "id"); if (id) { DSFYstrncpy(t->file_id, id, sizeof t->file_id); t->playable = true; } } } for ( ezxml_t restriction = ezxml_get(track, "restrictions", 0, "restriction", -1); restriction; restriction = restriction->next) { char *catalogues = (char*)ezxml_attr(restriction, "catalogues"); if(catalogues && strstr(catalogues, "premium") != NULL) { char* allowed = (char*)ezxml_attr(restriction, "allowed"); if(allowed) { t->allowed = calloc(strlen(allowed)+1, sizeof(char)); DSFYstrncpy(t->allowed, allowed, strlen(allowed)+1); } else { t->allowed = NULL; } char* forbidden = (char*)ezxml_attr(restriction, "forbidden"); if(forbidden) { t->forbidden = calloc(strlen(forbidden)+1, sizeof(char)); DSFYstrncpy(t->forbidden, forbidden, strlen(forbidden)+1); } else { t->forbidden = NULL; } } } xmlatoi(&t->year, track, "year", -1); xmlatoi(&t->length, track, "length", -1); xmlatoi(&t->tracknumber, track, "track-number", -1); xmlatof(&t->popularity, track, "popularity", -1); t->has_meta_data = true; prev = t; t = t->next; track_count++; } return track_count; }
/* parse getStation xml struct */ static void PianoXmlParseGetStationInfoCb (const char *key, const ezxml_t value, void *data) { PianoStationInfo_t *info = data; if (strcmp ("seeds", key) == 0) { const ezxml_t dataNode = ezxml_get (value, "array", 0, "data", -1); for (ezxml_t seedNode = ezxml_child (dataNode, "value"); seedNode; seedNode = seedNode->next) { struct PianoXmlParseSeedBag bag; memset (&bag, 0, sizeof (bag)); PianoXmlStructParser (ezxml_child (seedNode, "struct"), PianoXmlParseSeedCb, &bag); assert (bag.song != NULL || bag.artist != NULL || bag.station != NULL); if (bag.seedId == NULL) { /* seeds without id are useless */ continue; } /* FIXME: copy&waste */ if (bag.song != NULL) { bag.song->seedId = bag.seedId; if (info->songSeeds == NULL) { info->songSeeds = bag.song; } else { PianoSong_t *curSong = info->songSeeds; while (curSong->next != NULL) { curSong = curSong->next; } curSong->next = bag.song; } } else if (bag.artist != NULL) { bag.artist->seedId = bag.seedId; if (info->artistSeeds == NULL) { info->artistSeeds = bag.artist; } else { PianoArtist_t *curSong = info->artistSeeds; while (curSong->next != NULL) { curSong = curSong->next; } curSong->next = bag.artist; } } else if (bag.station != NULL) { bag.station->seedId = bag.seedId; if (info->stationSeeds == NULL) { info->stationSeeds = bag.station; } else { PianoStation_t *curStation = info->stationSeeds; while (curStation->next != NULL) { curStation = curStation->next; } curStation->next = bag.station; } } else { free (bag.seedId); } } } else if (strcmp ("feedback", key) == 0) { const ezxml_t dataNode = ezxml_get (value, "array", 0, "data", -1); for (ezxml_t feedbackNode = ezxml_child (dataNode, "value"); feedbackNode; feedbackNode = feedbackNode->next) { if (PianoXmlParsePlaylistStruct (feedbackNode, &info->feedback) != PIANO_RET_OK) { break; } } } }
void CMsnProto::UpdateStoreCacheKey(ezxml_t bdy) { ezxml_t key = ezxml_get(bdy, "soap:Header", 0, "AffinityCacheHeader", 0, "CacheKey", -1); if (key) replaceStr(storageCacheKey, ezxml_txt(key)); }
static int osfy_artistbrowse_load_from_xml(sp_session *session, sp_artistbrowse *arb, ezxml_t root) { unsigned char id[20]; int disc_number, i; sp_track *track; sp_album *album; ezxml_t node, album_node, loop_node, track_node; /* Load artist from XML if not yet loaded */ if(sp_artist_is_loaded(arb->artist) == 0) osfy_artist_load_artist_from_xml(session, arb->artist, root); assert(sp_artist_is_loaded(arb->artist)); /* Load portraits */ for(loop_node = ezxml_get(root, "bios", 0, "bio", 0, "portraits", 0, "portrait", -1); loop_node; loop_node = loop_node->next) { if((node = ezxml_get(loop_node, "id", -1)) == NULL) continue; arb->portraits = realloc(arb->portraits, sizeof(unsigned char *) * (1 + arb->num_portraits)); arb->portraits[arb->num_portraits] = malloc(20); hex_ascii_to_bytes(node->txt, arb->portraits[arb->num_portraits], 20); arb->num_portraits++; } /* Load biography */ if((node = ezxml_get(root, "bios", 0, "bio", 0, "text", -1)) != NULL) arb->biography = strdup(node->txt); else arb->biography = strdup(""); /* Load similar artists */ for(loop_node = ezxml_get(root, "similar-artists", 0, "artist", -1); loop_node; loop_node = loop_node->next) { if((node = ezxml_get(loop_node, "id", -1)) == NULL) continue; arb->similar_artists = realloc(arb->similar_artists, sizeof(sp_artist *) * (1 + arb->num_similar_artists)); hex_ascii_to_bytes(node->txt, id, 16); arb->similar_artists[arb->num_similar_artists] = osfy_artist_add(session, id); sp_artist_add_ref(arb->similar_artists[arb->num_similar_artists]); if(sp_artist_is_loaded(arb->similar_artists[arb->num_similar_artists]) == 0) { DSFYDEBUG("Loading similar artist from artistbrowse XML\n"); osfy_artist_load_artist_from_xml(session, arb->similar_artists[arb->num_similar_artists], loop_node); } assert(sp_artist_is_loaded(arb->similar_artists[arb->num_similar_artists])); arb->num_similar_artists++; } /* Loop over each album listed */ for(album_node = ezxml_get(root, "albums", 0, "album", -1); album_node; album_node = album_node->next) { /* Extract album ID and add it */ if((node = ezxml_get(album_node, "id", -1)) == NULL) continue; hex_ascii_to_bytes(node->txt, id, 16); album = sp_album_add(session, id); /* Load album if necessary */ if(sp_album_is_loaded(album) == 0) osfy_album_load_from_album_xml(session, album, album_node); assert(sp_album_is_loaded(album)); /* Add album to artistbrowse's list of albums */ arb->albums = realloc(arb->albums, sizeof(sp_album *) * (1 + arb->num_albums)); arb->albums[arb->num_albums] = album; sp_album_add_ref(arb->albums[arb->num_albums]); arb->num_albums++; /* Loop over each disc in the album and add tracks */ for(loop_node = ezxml_get(album_node, "discs", 0, "disc", -1); loop_node; loop_node = loop_node->next) { /* Cache disc number */ if((node = ezxml_get(loop_node, "disc-number", -1)) == NULL) { DSFYDEBUG("BUG: Found no 'disc-numner' under discs -> disc\n"); continue; } disc_number = atoi(node->txt); /* Loop over each track and add it to the artistbrowse tracks list */ for(track_node = ezxml_get(loop_node, "track", -1), i = 1; track_node; track_node = track_node->next, i++) { /* Extract track ID and add it */ if((node = ezxml_get(track_node, "id", -1)) == NULL) continue; hex_ascii_to_bytes(node->txt, id, 16); track = osfy_track_add(session, id); /* Add album to track */ if(track->album) sp_album_release(track->album); track->album = album; sp_album_add_ref(track->album); /* Set disc number */ track->disc = disc_number; /* Set track index on disc */ if(track->index == 0) track->index = i; /* Load track details from XML if not already loaded */ if(sp_track_is_loaded(track) == 0) osfy_track_load_from_xml(session, track, track_node); assert(sp_track_is_loaded(track)); /* Mark track as available if the album is available and the album has a non-zero duration (i.e, associated files) */ if(!track->is_available && track->duration) { DSFYDEBUG("Track '%s' marked as not available but has files, force-marking track as %savailable\n", node->txt, !album->is_available? "not ": ""); track->is_available = album->is_available; } /* Add track to artistbrowse and increase the track's ref count */ arb->tracks = realloc(arb->tracks, sizeof(sp_track *) * (1 + arb->num_tracks)); arb->tracks[arb->num_tracks] = track; sp_track_add_ref(arb->tracks[arb->num_tracks]); arb->num_tracks++; } } /* for each disc in album */ } /* for each album */ return 0; }
bool CMsnProto::MSN_StoreGetProfile(bool allowRecurse) { char* reqHdr; ezxml_t tbdy; ezxml_t xmlp = storeSoapHdr("GetProfile", "Initial", tbdy, reqHdr); ezxml_t prohndl = ezxml_add_child(tbdy, "profileHandle", 0); ezxml_t alias = ezxml_add_child(prohndl, "Alias", 0); ezxml_t node = ezxml_add_child(alias, "Name", 0); ezxml_set_txt(node, mycid); node = ezxml_add_child(alias, "NameSpace", 0); ezxml_set_txt(node, "MyCidStuff"); node = ezxml_add_child(prohndl, "RelationshipName", 0); ezxml_set_txt(node, "MyProfile"); ezxml_t proattr = ezxml_add_child(tbdy, "profileAttributes", 0); node = ezxml_add_child(proattr, "ResourceID", 0); ezxml_set_txt(node, "true"); node = ezxml_add_child(proattr, "DateModified", 0); ezxml_set_txt(node, "true"); ezxml_t exproattr = ezxml_add_child(proattr, "ExpressionProfileAttributes", 0); node = ezxml_add_child(exproattr, "ResourceID", 0); ezxml_set_txt(node, "true"); node = ezxml_add_child(exproattr, "DateModified", 0); ezxml_set_txt(node, "true"); node = ezxml_add_child(exproattr, "DisplayName", 0); ezxml_set_txt(node, "true"); node = ezxml_add_child(exproattr, "DisplayNameLastModified", 0); ezxml_set_txt(node, "true"); node = ezxml_add_child(exproattr, "PersonalStatus", 0); ezxml_set_txt(node, "true"); node = ezxml_add_child(exproattr, "PersonalStatusLastModified", 0); ezxml_set_txt(node, "true"); node = ezxml_add_child(exproattr, "StaticUserTilePublicURL", 0); ezxml_set_txt(node, "true"); node = ezxml_add_child(exproattr, "Photo", 0); ezxml_set_txt(node, "true"); node = ezxml_add_child(exproattr, "Flags", 0); ezxml_set_txt(node, "true"); char* szData = ezxml_toxml(xmlp, true); ezxml_free(xmlp); unsigned status = 0; char *storeUrl = NULL, *tResult = NULL; for (int k = 4; --k;) { mir_free(storeUrl); storeUrl = GetStoreHost("GetProfile"); tResult = getSslResult(&storeUrl, szData, reqHdr, status); if (tResult == NULL) UpdateStoreHost("GetProfile", NULL); else break; } mir_free(reqHdr); free(szData); if (tResult != NULL) { if (status == 200) { ezxml_t xmlm = ezxml_parse_str(tResult, strlen(tResult)); ezxml_t body = getSoapResponse(xmlm, "GetProfile"); UpdateStoreHost("GetProfile", body ? storeUrl : NULL); mir_snprintf(proresid, sizeof(proresid), "%s", ezxml_txt(ezxml_child(body, "ResourceID"))); ezxml_t expr = ezxml_child(body, "ExpressionProfile"); if (expr == NULL) { MSN_StoreShareItem(proresid); MSN_SharingMyProfile(); if (allowRecurse) MSN_StoreGetProfile(false); } else { const char* szNick = ezxml_txt(ezxml_child(expr, "DisplayName")); setStringUtf(NULL, "Nick", (char*)szNick); const char* szStatus = ezxml_txt(ezxml_child(expr, "PersonalStatus")); replaceStr(msnLastStatusMsg, szStatus); mir_snprintf(expresid, sizeof(expresid), "%s", ezxml_txt(ezxml_child(expr, "ResourceID"))); ezxml_t photo = ezxml_child(expr, "Photo"); mir_snprintf(photoid, sizeof(photoid), "%s", ezxml_txt(ezxml_child(photo, "ResourceID"))); ezxml_t docstr = ezxml_get(photo, "DocumentStreams", 0, "DocumentStream", -1); while (docstr) { const char *docname = ezxml_txt(ezxml_child(docstr, "DocumentStreamName")); if (!strcmp(docname, "UserTileStatic")) { getMyAvatarFile(ezxml_txt(ezxml_child(docstr, "PreAuthURL")), _T("miranda_avatar.tmp")); break; } docstr = ezxml_next(docstr); } } ezxml_free(xmlm); } else if (status == 500 && allowRecurse) { ezxml_t xmlm = ezxml_parse_str(tResult, strlen(tResult)); const char* szErr = ezxml_txt(getSoapFault(xmlm, true)); if (strcmp(szErr, "PassportAuthFail") == 0) { MSN_GetPassportAuth(); MSN_StoreGetProfile(false); } else { MSN_StoreCreateProfile(); if (MSN_StoreGetProfile(false)) status = 200; } ezxml_free(xmlm); } else UpdateStoreHost("GetProfile", NULL); } mir_free(tResult); mir_free(storeUrl); return status == 200; }
/** * \return <si/> response to <si/> request */ static int xmlns_si_file_accept(struct x_bus *sess, ezxml_t __stnz) { char *str; int err; ezxml_t stream_job; ezxml_t _stnz1; ezxml_t _stnz2; char *fname, *siz; ENTER; _stnz1 = ezxml_child(__stnz, "file"); if (!_stnz1) goto ftexception; fname = (char *) ezxml_attr(_stnz1, "name"); siz = (char *) ezxml_attr(_stnz1, "size"); // get features for (_stnz2 = ezxml_get(__stnz, "feature", -1); _stnz2; _stnz2 = ezxml_next(_stnz2)) { str = (char *) ezxml_attr(_stnz2, "xmlns"); if (str && strstr(str, "feature-neg")) break; }; if (!_stnz2) goto ftexception; // find stream-method for (_stnz2 = ezxml_get(_stnz2, "x", 0, "field", -1); _stnz2; _stnz2 = ezxml_next(_stnz2)) { str = (char *) ezxml_attr(_stnz2, "var"); if (str && strstr(str, "stream-method")) break; }; if (!_stnz2) goto ftexception; // get all stream methods for (_stnz2 = ezxml_child(_stnz2, "option"); _stnz2; _stnz2 = ezxml_next(_stnz2)) { _stnz1 = ezxml_child(_stnz2, "value"); if (_stnz1) printf("STREAM: %s\n", _stnz1->txt); if (!strcmp(_stnz1->txt, XMLNS_BYTESTREAMS)) break; }; if (!_stnz2) goto ftexception; /* enter critical section */ pthread_mutex_lock(&sess->lock); // create new file transfer job _stnz2 = ezxml_get(sess->dbcore, "bytestreams", 0, "pending", -1); if (!_stnz2) { _stnz2 = ezxml_child(sess->dbcore, "bytestreams"); _stnz2 = ezxml_add_child(_stnz2, "pending", 0); } err = !_stnz2->child; /* if some pending job already exists */ if (err) { stream_job = ezxml_new("job"); ezxml_set_attr(stream_job, "type", "file-transfer"); ezxml_set_attr_d(stream_job, "id", ezxml_attr(__stnz,"id")); if (ezxml_attr(__stnz, "mime-type")) ezxml_set_attr_d(stream_job, "mime-type", ezxml_attr(__stnz,"mime-type")); ezxml_set_attr_d(stream_job, "profile", ezxml_attr(__stnz,"profile")); ezxml_set_attr_d(stream_job, "name", fname); ezxml_set_attr(stream_job, "source", "remote"); ezxml_set_attr(stream_job, "src_fd", "0"); ezxml_set_attr(stream_job, "dst_fd", "0"); ezxml_set_attr(stream_job, "status", "0"); _stnz2 = ezxml_get(sess->dbcore, "bytestreams", 0, "pending", -1); ezxml_insert(stream_job, _stnz2, 0); /* leave critical section */ pthread_mutex_unlock(&sess->lock); } else { /* leave critical section */ pthread_mutex_unlock(&sess->lock); goto ftexception; } // create si response _stnz1 = ezxml_new("si"); ezxml_set_attr(_stnz1, "xmlns", XMLNS_SI); _stnz2 = ezxml_add_child(_stnz1, "feature", 0); ezxml_set_attr(_stnz2, "xmlns", XMLNS_FEATURE_NEG); _stnz2 = ezxml_add_child(_stnz2, "x", 0); ezxml_set_attr(_stnz2, "xmlns", XMLNS_X_DATA); ezxml_set_attr(_stnz2, "type", "submit"); _stnz2 = ezxml_add_child(_stnz2, "field", 0); ezxml_set_attr(_stnz2, "var", "stream-method"); _stnz2 = ezxml_add_child(_stnz2, "value", 0); ezxml_set_txt(_stnz2, XMLNS_BYTESTREAMS); EXIT; xmpp_session_reply_iq_stanza(sess,__stnz,_stnz1); return 0; ftexception: // create si response _stnz1 = ezxml_new("error"); ezxml_set_attr(_stnz1, "code", "400"); ezxml_set_attr_d(_stnz1,"type","cancel"); _stnz2 = ezxml_add_child(_stnz1, "bad-request", 0); ezxml_set_attr(_stnz2, "xmlns", XMLNS_XMPP_STANZAS); _stnz2 = ezxml_add_child(_stnz1, "no-valid-streams", 0); ezxml_set_attr(_stnz2, "xmlns", XMLNS_SI); EXIT; xmpp_session_reply_iq_stanza(sess,__stnz,_stnz1); return -1; }
static int xmpp_send_file(struct x_bus *sess, const char *jid, const char *name) { struct stat f_stat; char ts[25]; pthread_t t; ezxml_t stream_job; ezxml_t __stnz; ezxml_t _s1; ezxml_t _s2; char *myjid = NULL; if (stat(name, &f_stat)) return -1; pthread_mutex_lock(&sess->lock); myjid = x_strdup(ezxml_attr(sess->dbcore, "jid")); pthread_mutex_unlock(&sess->lock); __stnz = ezxml_new("iq"); ezxml_set_attr(__stnz, "type", "set"); ezxml_set_attr_d(__stnz,"to",jid); ezxml_set_attr(__stnz, "from", myjid); // TODO Randomize ID ezxml_set_attr(__stnz, "id", "some-id"); _s1 = ezxml_add_child(__stnz, "si", 0); ezxml_set_attr(_s1, "xmlns", XMLNS_SI); sprintf(ts, "s5b_%x", (int) (random() + time(NULL))); ezxml_set_attr_d(_s1,"id",ts); ezxml_set_attr(_s1, "profile", XMLNS_FILE_TRANSFER); _s2 = ezxml_add_child(_s1, "file", 0); ezxml_set_attr(_s2, "xmlns", XMLNS_FILE_TRANSFER); ezxml_set_attr_d(_s2,"name",name); sprintf(ts, "%d", (int) f_stat.st_size); ezxml_set_attr_d(_s2,"size",ts); _s2 = ezxml_add_child(_s1, "feature", 0); ezxml_set_attr(_s2, "xmlns", XMLNS_FEATURE_NEG); _s2 = ezxml_add_child(_s2, "x", 0); ezxml_set_attr(_s2, "xmlns", XMLNS_X_DATA); ezxml_set_attr(_s2, "type", "form"); _s2 = ezxml_add_child(_s2, "field", 0); ezxml_set_attr(_s2, "var", "stream-method"); ezxml_set_attr(_s2, "type", "list-single"); _s2 = ezxml_add_child(_s2, "option", 0); _s2 = ezxml_add_child(_s2, "value", 0); ezxml_set_txt(_s2, XMLNS_BYTESTREAMS); /* enter critical section */ pthread_mutex_lock(&sess->lock); // create new file transfer job // this job should be created and added to // new main event loop _s2 = ezxml_get(sess->dbcore, "bytestreams", 0, "pending", -1); if (!_s2) { _s2 = ezxml_get(sess->dbcore, "bytestreams", -1); _s2 = ezxml_add_child(_s2, "pending", 0); } _s2 = ezxml_child(_s2, "job"); /* if some pending job already exists */ if (!_s2) { // create new stream job stream_job = ezxml_new("job"); ezxml_set_attr_d(stream_job, "jid", jid); ezxml_set_attr_d(stream_job, "id",ezxml_attr(_s1,"id")); ezxml_set_attr(stream_job, "type", "file-transfer"); ezxml_set_attr(stream_job, "source", "local"); ezxml_set_attr_d(stream_job, "name", name); ezxml_set_attr(stream_job, "src_fd", "0"); ezxml_set_attr(stream_job, "dst_fd", "0"); ezxml_set_attr(stream_job, "status", "0"); _s2 = ezxml_get(sess->dbcore, "bytestreams", 0, "pending", -1); ezxml_insert(stream_job, _s2, 0); xmpp_stanza2stdout(sess->dbcore); } pthread_mutex_unlock(&sess->lock); // FIXME pthread_create(&t, NULL, sock5srv, (void *) sess); sprintf(ts, "%d", (int) t); pthread_mutex_lock(&sess->lock); _s2 = ezxml_get(sess->dbcore, "threads", -1); if (_s2) { _s2 = ezxml_add_child(_s2, "thread", 0); ezxml_set_attr(_s2, "name", "socks5"); ezxml_set_attr_d(_s2,"id",ts); } pthread_mutex_unlock(&sess->lock); EXIT; xmpp_session_send_stanza(sess, __stnz); ezxml_free(__stnz); if (myjid) free(myjid); return 0; }
static void xmlns_si_file_send(struct x_bus *sess, ezxml_t __stnz) { ezxml_t _stnz; ezxml_t _s, _s1; int status; int has_proxy = 0; char *proxy = NULL; char *myjid = NULL; char *myip = NULL; ENTER; pthread_mutex_lock(&sess->lock); myjid = x_strdup(ezxml_attr(sess->dbcore, "jid")); _s = ezxml_get(sess->dbcore, "interfaces", 0, "iface", -1); myip = x_strdup(ezxml_attr(_s, "addr")); pthread_mutex_unlock(&sess->lock); _s = ezxml_get(sess->dbcore, "bytestreams", 0, "pending", -1); if (_s) _s = ezxml_child(_s, "job"); _stnz = ezxml_get(sess->dbcore, "ftproxy", -1); proxy = (char *) ezxml_attr(_stnz, "jid"); if (proxy) has_proxy++; sscanf(ezxml_attr(_s, "status"), "%d", &status); if (status < 2 && has_proxy) { // _s = xmpp_stanza_get_root(_from); // first send request to proxy _stnz = ezxml_new("iq"); ezxml_set_attr(_stnz, "id", "6756756"); ezxml_set_attr(_stnz, "type", "get"); ezxml_set_attr(_stnz, "from", myjid); ezxml_set_attr_d(_stnz,"to",proxy); _s1 = ezxml_add_child(_stnz, "query", 0); ezxml_set_attr(_s1, "xmlns", XMLNS_BYTESTREAMS); } else if (myip) { _stnz = ezxml_new("iq"); ezxml_set_attr(_stnz, "id", "6756756"); ezxml_set_attr(_stnz, "type", "set"); ezxml_set_attr(_stnz, "from", myjid); ezxml_set_attr_d(_stnz,"to",ezxml_attr(_s,"jid")); // FIXME Correct random values _s1 = ezxml_add_child(_stnz, "query", 0); ezxml_set_attr(_s1, "xmlns", XMLNS_BYTESTREAMS); ezxml_set_attr(_s1, "mode", "tcp"); ezxml_set_attr_d(_s1,"sid",ezxml_attr(_s,"id")); // FIXME Correct ip _s1 = ezxml_add_child(_s1, "streamhost", 0); ezxml_set_attr(_s1, "jid", myjid); ezxml_set_attr_d(_s1,"host",myip); ezxml_set_attr(_s1, "port", "5277"); } else { /* TODO Clean file atrsnfer job */ // ERROR } EXIT; xmpp_session_send_stanza(sess, _stnz); ezxml_free(_stnz); if (myjid) free(myjid); if (myip) free(myip); return; }
static void * sock5srv(void *arg) { struct x_bus *sess; char buf[128]; int sock; int sockcli; int err; int dst_fd; int port = 5277; ezxml_t _s; struct sockaddr_in srv; struct sockaddr_in cli; sess = (struct x_bus *) arg; _s = ezxml_get(sess->dbcore, "bytestreams", 0, "pending", -1); if (_s) _s = ezxml_child(_s, "job"); ENTER; printf("Serving on %d\n", port); sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); memset(&srv, 0, sizeof(struct sockaddr_in)); srv.sin_family = AF_INET; srv.sin_addr.s_addr = htonl(INADDR_ANY); srv.sin_port = htons(port); if (bind(sock, (struct sockaddr *) &srv, sizeof(struct sockaddr_in)) < 0) { perror("bind()"); close(sock); return NULL; } if (listen(sock, 1) < 0) { perror("listen()"); close(sock); return NULL; } printf("Accepting on %d\n", port); if ((sockcli = accept(sock, (struct sockaddr *) &cli, (socklen_t *) &err)) < 0) { perror("accept()"); close(sock); } err = recv(sockcli, buf, 128, 0); #ifdef TRACE_DEBUG printf("Received %d bytes (0x%x 0x%x) from server\n", err, buf[0], buf[1]); #endif buf[0] = 0x05; buf[1] = 0x00; err = send(sockcli, buf, 2, 0); #ifdef TRACE_DEBUG printf("Sent %d bytes to server\n", err); #endif err = recv(sockcli, buf, 128, 0); #ifdef TRACE_DEBUG printf("Received %d bytes (0x%x 0x%x) from server\n", err, buf[0], buf[1]); #endif buf[0] = 0x05; buf[1] = 0x00; err = send(sockcli, buf, err, 0); #ifdef TRACE_DEBUG printf("Sent %d bytes to server\n", err); #endif /* * Change jobs status and schedule */ pthread_mutex_lock(&sess->lock); dst_fd = sockcli; sprintf(buf, "%d", dst_fd); ezxml_set_attr_d(_s,"dst_fd",buf); pthread_mutex_unlock(&sess->lock); close(sock); EXIT; return NULL; }