Exemple #1
0
Fichier : xml.c Projet : poume/spot
static void parse_browse_album(ezxml_t top, struct album_browse* a)
{
    xmlstrncpy(a->name, sizeof a->name, top, "name", -1);
    xmlstrncpy(a->id, sizeof a->id, top, "id", -1);
    xmlstrncpy(a->cover_id, sizeof a->cover_id, top, "cover", -1);
    xmlatoi(&a->year, top, "year", -1);
    xmlatof(&a->popularity, top, "popularity", -1);
    xmlstrncpy(a->artist, sizeof a->artist, top, "artist", -1);
    xmlstrncpy(a->artist_id, sizeof a->artist_id, top, "artist-id", -1);
    
    ezxml_t x = ezxml_get(top, "review",-1);
    if (x) {
      int len = strlen(x->txt);
      a->review = malloc(len + 1);
      memcpy(a->review, x->txt, len+1);
    }

    /* TODO: support multiple discs per album  */
    a->tracks = calloc(1, sizeof(struct track));
    ezxml_t disc = ezxml_get(top, "discs",0,"disc", -1);
    a->num_tracks = parse_tracks(disc, a->tracks, false);

    /* Copy missing metadata from album to tracks */
    int count = 0;
    for (struct track *t = a->tracks; t; t = t->next) {
        DSFYstrncpy(t->album, a->name, sizeof t->album);
        DSFYstrncpy(t->album_id, a->id, sizeof t->album_id);
        DSFYstrncpy(t->cover_id, a->cover_id, sizeof t->cover_id);
        t->year = a->year;
        count++;
    }
}
Exemple #2
0
int session_connect (SESSION * session)
{
	struct sockaddr_in sin;
	char host[1025 + 1], *service_list, *service;
	int port;

	/* Lookup service hosts in DNS */
        service_list = dns_srv_list ("_spotify-client._tcp.spotify.com");
	if (!service_list) {
            DSFYDEBUG("service lookup failed. falling back to ap.spotify.com\n");
            service_list = malloc(200);
            strcpy(service_list, "ap.spotify.com:4070\n");
        }

	for (service = service_list; *service;) {
		if (sscanf (service, "%[^:]:%d\n", host, &port) != 2)
			return -1;

		service += strlen (host) + 7;
		DSFYDEBUG ("session_connect(): Connecting to %s:%d\n", host,
			   port);

		memset (&sin, 0, sizeof (sin));
		sin.sin_family = PF_INET;
		sin.sin_port = htons (port);
		sin.sin_addr.s_addr = dns_resolve_name (host);
		if (sin.sin_addr.s_addr == INADDR_NONE)
			continue;

		session->ap_sock = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
		if (connect (session->ap_sock, (struct sockaddr *) &sin,
			     sizeof (sin)) != -1)
			break;

		sock_close (session->ap_sock);
		session->ap_sock = -1;
	}

	free (service_list);
	if (sin.sin_addr.s_addr == INADDR_NONE)
		return -1;

	/*
	 * Save for later use in ConnectionInfo message
	 * (too lazy to do getpeername() later ;)
	 */
	DSFYstrncpy (session->server_host, host, sizeof session->server_host);
	session->server_port = port;

	DSFYstrncpy (session->user_info.server_host, host,
		     sizeof session->user_info.server_host);
	session->user_info.server_port = port;

	return 0;
}
Exemple #3
0
void session_auth_set (SESSION * session, const char *username, const char *password)
{
	DSFYstrncpy (session->user_info.username, username,
		     sizeof session->user_info.username);
	DSFYstrncpy (session->username, username, sizeof session->username);
	session->username[sizeof (session->username) - 1] = 0;
	session->username_len = strlen (session->username);

	DSFYstrncpy (session->password, password, sizeof session->password);
	session->password[sizeof (session->password) - 1] = 0;
}
Exemple #4
0
static void parse_browse_album(ezxml_t top, struct album_browse* a, bool high_bitrate)
{
    xmlstrncpy(a->name, sizeof a->name, top, "name", -1);
    xmlstrncpy(a->id, sizeof a->id, top, "id", -1);
    xmlstrncpy(a->artist, sizeof a->artist, top, "artist", -1);
    xmlstrncpy(a->artist_id, sizeof a->artist_id, top, "artist-id", -1);
    xmlstrncpy(a->cover_id, sizeof a->cover_id, top, "cover", -1);
    xmlatoi(&a->year, top, "year", -1);
    xmlatof(&a->popularity, top, "popularity", -1);

    a->tracks = calloc(1, sizeof(struct track));
    ezxml_t disc = ezxml_get(top, "discs",0,"disc", -1);
    a->num_tracks = parse_tracks(disc, a->tracks, false, high_bitrate);

    /* Append extra discs to album  */
    struct track *last = a->tracks;
    while (last->next)
      last = last->next;
    while ((disc = disc->next)) {
      int offset = last->tracknumber;
      last->next = calloc(1, sizeof(struct track));
      a->num_tracks += parse_tracks(disc, last->next, false, high_bitrate);
      do {
        last = last->next;
        last->tracknumber += offset;
      } while (last->next);
    }

    /* Copy missing metadata from album to tracks */
    int count = 0;
    for (struct track *t = a->tracks; t; t = t->next) {
        DSFYstrncpy(t->album, a->name, sizeof t->album);
        DSFYstrncpy(t->album_id, a->id, sizeof t->album_id);
        DSFYstrncpy(t->cover_id, a->cover_id, sizeof t->cover_id);
        t->year = a->year;
        count++;
    }
}
Exemple #5
0
static void parse_browse_album(ezxml_t top, struct album_browse* a, bool high_bitrate)
{
    xmlstrncpy(a->name, sizeof a->name, top, "name", -1);
    xmlstrncpy(a->id, sizeof a->id, top, "id", -1);
    xmlstrncpy(a->cover_id, sizeof a->cover_id, top, "cover", -1);
    xmlatoi(&a->year, top, "year", -1);
    xmlatof(&a->popularity, top, "popularity", -1);

    /* TODO: support multiple discs per album  */
    a->tracks = calloc(1, sizeof(struct track));
    ezxml_t disc = ezxml_get(top, "discs",0,"disc", -1);
    a->num_tracks = parse_tracks(disc, a->tracks, false, high_bitrate);

    /* Copy missing metadata from album to tracks */
    int count = 0;
    for (struct track *t = a->tracks; t; t = t->next) {
        DSFYstrncpy(t->album, a->name, sizeof t->album);
        DSFYstrncpy(t->album_id, a->id, sizeof t->album_id);
        DSFYstrncpy(t->cover_id, a->cover_id, sizeof t->cover_id);
        t->year = a->year;
        count++;
    }
}
Exemple #6
0
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;
}
Exemple #7
0
static int parse_tracks(ezxml_t xml, struct track* t, bool ordered, bool high_bitrate)
{
    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;
        }

        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;
}
Exemple #8
0
Fichier : xml.c Projet : poume/spot
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;
}
Exemple #9
0
int session_connect (SESSION * session)
{
	struct addrinfo h, *airoot, *ai;
	char host[1025 + 1], port[6], *service_list, *service;

	/* Lookup service hosts in DNS */
        service_list = dns_srv_list ("_spotify-client._tcp.spotify.com");
	if (!service_list) {
            DSFYDEBUG ("Service lookup failed. falling back to ap.spotify.com\n");
            service_list = malloc(200);
            strcpy (service_list, "ap.spotify.com:4070\n");
        }



	for (service = service_list; *service;) {
		if (sscanf (service, "%[^:]:%5s\n", host, port) != 2)
			return -1;

		service += strlen (host) + 7;
		DSFYDEBUG ("Connecting to %s:%s\n", host,
			   port);

		memset(&h, 0, sizeof(h));
		h.ai_family = PF_UNSPEC;
		h.ai_socktype = SOCK_STREAM;
		h.ai_protocol = IPPROTO_TCP;
		if (getaddrinfo (host, port, &h, &airoot)) {
			DSFYDEBUG ("getaddrinfo(%s,%s) failed with error %d\n",
					host, port, errno);
			continue;
		}

		for(ai = airoot; ai; ai = ai->ai_next) {
			if (ai->ai_family != AF_INET
				&& ai->ai_family != AF_INET6)
				continue;

			session->ap_sock = socket (ai->ai_family,
					ai->ai_socktype, ai->ai_protocol);
			if (session->ap_sock < 0)
				continue;

			if (connect (session->ap_sock,
				(struct sockaddr *) ai->ai_addr,
				ai->ai_addrlen) != -1)
				break;

			sock_close (session->ap_sock);
			session->ap_sock = -1;
		}

		freeaddrinfo (airoot);
		if (session->ap_sock != -1)
			break;
	}

	free (service_list);
	if (session->ap_sock == -1)
		return -1;

	/*
	 * Save for later use in ConnectionInfo message
	 * (too lazy to do getpeername() later ;)
	 */
	DSFYstrncpy (session->server_host, host, sizeof session->server_host);
	session->server_port = atoi(port);

	DSFYstrncpy (session->user_info.server_host, host,
		     sizeof session->user_info.server_host);
	session->user_info.server_port = atoi(port);

	return 0;
}