#define _GNU_SOURCE #include #include #include #include #include #define NIZ_DODATEK(a) #a #define NIZ(a) NIZ_DODATEK(a) #define RTV_CLIENT_ID "82013fb3a531d5414f478747c1aca622" /* enak za vse */ #define RTV_CLIENT_ID_SIZEOF 32+1 #define RTV_VIDEO_TIP 1 #define RTV_AUDIO_TIP 2 #define RTV_NEPOZNAN_TIP 0 #define RTV_NACIN argv[1] #define RTV_URL argv[2] #define RTV_P_SIZEOF 128 /* privzeti sizeof */ #define RTV_TEST_NASLOV "Vreme ob 22h" #define RTV_TEST_ZANRI "\"INFORMATIVNE VSEBINE\"," \ "\"DNEVNO INFORMATIVNE ODDAJE\",\"Vremenska poročila\"" #define RTV_TEST_OPIS "Vreme je na sporedu vsak dan po Poročilih, pred in po" \ " Dnevniku ter po Odmevih. Napoved vremena pa vas čaka tudi vsak delavnik" \ " zjutraj v rubriki oddaje Dobro jutro. \\r\\n" #define RTV_TEST_ID 89614963 #define RTV_TEST_DOLZINA 155 #define RTV_TEST_TIP_ODDAJE_IME "Vreme" #define RTV_TEST_TIP_ODDAJE_ID 608 #define RTV_TEST_PROGRAM "SLO1" #define RTV_TEST_OBJAVLJENO "2010-12-03 23:20:10" #define RTV_TEST_PREDVAJANO "2010-12-03 23:20:10" #define RTV_TEST_TIP_POSNETKA 4D_VIDEO_TIP #define RTV_TEST_SLICICA "http://img.rtvslo.si/_up/ava/ava_misc/show_logos" \ "/VREME_VECERNO-980.jpg" #define RTV_TEST_KONTROLNA_VREDNOST 1186735842 #define RTV_TEST_VELIKOST 9396765 #define RTV_NAPISI_NAPAKA 1 #define RTV_NAPISI_INFO 1 #define RTV_NAPISI_OPOZORILO 1 #define RTV_NAPISI_HROSC 1 #define RTV_NAPISI(kaj, frmt, ...) /* pazi na format string RCE! */ \ do { if ( RTV_NAPISI_ ##kaj ) fprintf(stderr, \ "[" #kaj "] %s@%s:" NIZ(__LINE__) " " frmt "\n", \ __func__, __FILE__, ##__VA_ARGS__ ); } while(0); #define RTV_USER_AGENT "Mozilla/5.0 equivalent (rtv4d-dl " RTV_VER "; C " \ NIZ(__STDC_VERSION__) " GCC " __VERSION__ "; " __DATE__ " " __TIME__ "; " \ __FILE__ ":" NIZ(__LINE__) ")" #define RTV_HTTP_GET \ "GET /%s HTTP/1.0\r\nHost: %s\r\nUser-Agent: " RTV_USER_AGENT \ "\r\nAccept: */*\r\nX-Requested-With: tcp.c (" __FILE__ ":" NIZ(__LINE__) \ ")\r\nConnection: close\r\n\r\n" #define RTV_HTTP_TIMEOUT 69 /* sekund */ #define RTV_NE_BO_POSLAL NULL /* "ToJeMogočeBackdoor!" */ /* bere več znakov */ #define RTV_API_META_URL "http://api.rtvslo.si/ava/getRecordingDrm/" \ "%u?client_id=" RTV_CLIENT_ID #define RTV_API_META_URL_SIZEOF 128 /* vključno z nul znakom */ #define RTV_API_MEDIA_URL "http://api.rtvslo.si/ava/getMedia/%u/?client_id=" \ RTV_CLIENT_ID "&jwt=%s" #define RTV_API_MEDIA_URL_SIZEOF 64 + RTV_CLIENT_ID_SIZEOF + RTV_JWT_SIZEOF #define RTV_JWT_SIZEOF 43+1 #define RTV_PREDVAJALNIK_URL "http://4d.rtvslo.si/arhiv/v/%u" #define RTV_PREDVAJALNIK_URL_SIZEOF 32+1 + 12 #define RTV_VER "0.0.2" struct meta_oddaja { size_t naslov_sizeof; char * naslov; /* Vreme ob 22h */ unsigned int tip_oddaje_id; /* 608 */ size_t zanri_sizeof; char * zanri; /* INFORMATIVNE VSEBINE, DNEVNO INFORMATIVNE ODDAJE, Vrem... */ size_t opis_sizeof; char * opis; /* Vreme je na sporedu vsak dan po Poročilih, pred in po Dn... */ unsigned int id; /* 89614963 */ unsigned int dolzina; /* 155 */ size_t jwt_sizeof; /* 44 */ char * jwt; /* 1lKYcP7j8iNwqVQeQC8htsrBN47LpiHq3sm5bFlxRys */ size_t tip_oddaje_ime_sizeof; char * tip_oddaje_ime; /* Vreme */ size_t program_sizeof; char * program; /* SLO1 */ size_t objavljeno_sizeof; char * objavljeno; /* 2010-12-03 23:20:10 */ unsigned short int tip_posnetka; /* RTV_VIDEO_TIP */ size_t slicica_sizeof; char * slicica; /* http://img.rtvslo.si/_up/ava/ava_misc/show_logos/VREM... */ size_t predvajano_sizeof; char * predvajano; /* 2010-12-03 23:20:10 */ /* unsigned long long int kontrolna_vrednost; */ /* unsigned long long int velikost; */ /* število bajtov posnetka */ char get_meta_url[RTV_API_META_URL_SIZEOF]; /* http://api.rtvslo.si/ava/... */ char get_media_url[RTV_API_MEDIA_URL_SIZEOF]; /* http://api.rtvslo.si/av... */ char predvajalnik_url[RTV_PREDVAJALNIK_URL_SIZEOF]; /* http://4d.rtvslo.... */ size_t posnetek_url_sizeof; char * posnetek_url; /* http://progressive.rtvslo.si/encrypted00/2010/12... */ }; struct meta_oddaja * meta_oddaja_alloc () { struct meta_oddaja * m = malloc(sizeof(struct meta_oddaja)); m->naslov = malloc(sizeof(char)*RTV_P_SIZEOF);m->naslov_sizeof = RTV_P_SIZEOF; m->zanri = malloc(sizeof(char)*RTV_P_SIZEOF); m->zanri_sizeof = RTV_P_SIZEOF; m->opis = malloc(sizeof(char)*RTV_P_SIZEOF); m->opis_sizeof = RTV_P_SIZEOF; m->tip_oddaje_ime=malloc(sizeof(char)*RTV_P_SIZEOF); m->tip_oddaje_ime_sizeof = RTV_P_SIZEOF; m->program = malloc(sizeof(char)*RTV_P_SIZEOF);m->program_sizeof=RTV_P_SIZEOF; m->slicica = malloc(sizeof(char)*RTV_P_SIZEOF);m->slicica_sizeof=RTV_P_SIZEOF; m->jwt = malloc(sizeof(char)*RTV_P_SIZEOF); m->jwt_sizeof=RTV_P_SIZEOF; m->objavljeno = malloc(sizeof(char)*RTV_P_SIZEOF); m->objavljeno_sizeof = RTV_P_SIZEOF; m->predvajano = malloc(sizeof(char)*RTV_P_SIZEOF); m->predvajano_sizeof = RTV_P_SIZEOF; m->posnetek_url = malloc(sizeof(char)*RTV_P_SIZEOF); m->posnetek_url_sizeof = RTV_P_SIZEOF; return m; } int meta_oddaja_free (struct meta_oddaja * m) { free(m->naslov); m->naslov = NULL; free(m->zanri); m->zanri = NULL; free(m->opis); m->opis = NULL; free(m->tip_oddaje_ime); m->tip_oddaje_ime = NULL; free(m->program); m->program = NULL; free(m->slicica); m->slicica = NULL; free(m->jwt); m->jwt = NULL; free(m->objavljeno); m->objavljeno = NULL; free(m->predvajano); m->predvajano = NULL; free(m->posnetek_url); m->posnetek_url = NULL; free(m); m = NULL; return 0; } int niz_realloc (char * s, size_t * v) { *v = (*v)*2; s = realloc(s, sizeof(char)*(*v)); return 0; } int http_get (/* const */ char * u, FILE * r) { /* url ostane enak */ unsigned int p = 80; /* HTTP port ^~~~~~~~ glej man open_memstream, fmemopen*/ char * k; /* označuje konec imena gostitelja */ char t; /* začasna shramba za končni znak, ko je le-ta null */ int c = -42069; /* connection descriptor */ int ret; /* izhodni status write funkcij */ char * path; /* kaže na path requesta */ int returnstatus = 0; char * header; /* za headerje */ FILE * headerstream; size_t header_sizeof = 0; long long int contentlength = -69420; char * request_buf; /* za request buffer */ #define RTV_URL_HOST (u+7) if (u == NULL) { RTV_NAPISI(NAPAKA, "URL je null!"); return 1; } if (strncmp(u, "http://", 7) != 0) { RTV_NAPISI(NAPAKA, "URL ni podprt: %s", u); return 2; } k = strchr(RTV_URL_HOST, '/'); if (k - strchrnul(RTV_URL_HOST, ':') > 0) { /* pred pathom je PORT */ k = strchrnul(RTV_URL_HOST, ':'); p = atoi(k+1); } if (p > 65535) { /* port je nepodpisan, če gre v minus bo itak ZELO > 65535 */ RTV_NAPISI(NAPAKA, "port je neveljaven"); return 3; } if (k == NULL) k = strchrnul(RTV_URL_HOST, '/'); path = strchr(RTV_URL_HOST, '/'); if (path == NULL) { u[6] = '\0'; /* na koncu popravimo nazaj, izkoristimo ta memory xD */ path = u+5; } else { path++; } t = *k; *k = '\0'; RTV_NAPISI(INFO, "Vzpostavljam TCP povezavo na http://%s:%d ...", RTV_URL_HOST, p); c = spawn_conn(RTV_URL_HOST, p); if (c < 0) { RTV_NAPISI(NAPAKA, "TCP povezava ni uspela!"); returnstatus = 4; goto http_get_returncleanly; } else { RTV_NAPISI(INFO, "Povezan na strežnik."); } request_buf = malloc (sizeof(char) * ( sizeof(RTV_HTTP_GET) + strlen(RTV_URL_HOST)+ strlen(path) + 1 )); sprintf(request_buf, RTV_HTTP_GET, path, RTV_URL_HOST); /* =dovolj prostora */ RTV_NAPISI(INFO, "Pošiljam %lu bajtov ...", strlen(request_buf)); ret = sync_write(c, request_buf, strlen(request_buf), RTV_HTTP_TIMEOUT); if (ret != 0) { returnstatus = 5; RTV_NAPISI(NAPAKA, "TCP časovna omejitev pri pošiljanju je potekla"); goto http_get_returncleanly; } else { RTV_NAPISI(INFO, "Uspešno poslano."); } headerstream = open_memstream(&header, &header_sizeof); while (1) { rewind(headerstream); ret = read_until(c, headerstream, RTV_HTTP_TIMEOUT, "\n", -1); /* unsig!*/ fflush(headerstream); if (ret != 0) { returnstatus = 6; RTV_NAPISI(NAPAKA, "Branje headerja ni uspelo!"); goto http_get_returncleanly; } if (strncasecmp("Content-Length: ", header, strlen("Content-Length: ")) == 0) { contentlength = strtoll(header+16, NULL, 10); RTV_NAPISI(INFO, "Pridobil %lld bajtni odgovor.", contentlength); } if (strncmp("\r\n", header, 2) == 0 || header[0] == '\n') break; } if (contentlength == -69420) { RTV_NAPISI(OPOZORILO, "Manjka Content-Length, berem do konca."); } else { RTV_NAPISI(INFO, "Začetek telesa odgovora. Berem in pišem."); } fclose(headerstream); ret = read_until(c, r, RTV_HTTP_TIMEOUT, RTV_NE_BO_POSLAL, contentlength); if (ret != 0) { returnstatus = 7; RTV_NAPISI(NAPAKA, "Branje in pisanje telesa odgovora ni uspelo!"); goto http_get_returncleanly; } RTV_NAPISI(INFO, "Prejel in uspešno shranil/prebral HTTP odgovor."); http_get_returncleanly: free(request_buf); request_buf = NULL; free(header); header = NULL; if(c != -69420 && kill_conn(c) < 0) /* kill_conn se ne izvede, če prvi ni 1.*/ RTV_NAPISI(OPOZORILO, "TCP povezave ni uspelo prekiniti"); *k = t; u[6] = '/'; return returnstatus; } int rtv_meta_izpolni(struct meta_oddaja * m) { int returnstatus = 0; FILE * odgstream; char * odg; size_t sizeloc; size_t i, j; unsigned short int nasel_addaptivemedia = 0; /* glej iskanje stream URLja */ char * metakeys[] = {"\"title\"", "\"showId\"", "\"genre\"", \ "\"description\"", "\"showDescription\"", "\"duration\"", "\"jwt\"", \ "\"showName\"", "\"source\"", "\"publishDate\"", "\"mediaType\"", \ "\"orig\"", "\"broadcastDate\"", /* getMedia query: */ "\"http\"", \ "\"https\"", "\"addaptiveMedia\"" }; char * cp; #define RTV_META_IZPOLNI_METAKEYS_SIZEOF 13 /* hkrati offset za getMedia */ #define RTV_META_IZPOLNI_METAKEYS_GETMEDIA_FINAL \ (RTV_META_IZPOLNI_METAKEYS_SIZEOF+3) /* zadnji+1 za getMedia */ #define RTV_META_IZPOLNI_VALUE (odg+i+strlen(metakeys[j])+2) #define RTV_META_IZPOLNI_VALUE_INTERNAL RTV_META_IZPOLNI_VALUE snprintf(m->get_meta_url, RTV_API_META_URL_SIZEOF, RTV_API_META_URL, m->id); snprintf(m->predvajalnik_url, RTV_PREDVAJALNIK_URL_SIZEOF, RTV_PREDVAJALNIK_URL, m->id); odgstream = open_memstream(&odg, &sizeloc); returnstatus = http_get(m->get_meta_url, odgstream); /* shranimo metapodat. */ if (returnstatus != 0) { RTV_NAPISI(NAPAKA, "Zahteva za metapodatke iz API strežnika je spodletela"); goto rtv_meta_izpolni_returncleanly; } fflush(odgstream); for (i = 0; i < sizeloc; i++) { for (j = 0; j < RTV_META_IZPOLNI_METAKEYS_SIZEOF; j++) { if (strncmp(odg+i, metakeys[j], strlen(metakeys[j])) == 0) { switch (j) { case 0: /* title */ #define strtollu strtoull #define strtolu strtoul #define strtolld strtoll #define strtold strtol #define strtod strtol #define strtou strtoul #define RTV_META_IZPOLNI_V(imem, format, tip) /* za variabilne nize */ \ cp[0] = '\0'; /* omejimo json string, ne potrebujemo strncpy */ \ m->imem = realloc(m->imem, sizeof(tip) * \ strlen(RTV_META_IZPOLNI_VALUE_INTERNAL)+1); \ m->imem##_sizeof = strlen(RTV_META_IZPOLNI_VALUE_INTERNAL)+1; \ strcpy(m->imem, RTV_META_IZPOLNI_VALUE_INTERNAL); #define RTV_META_IZPOLNI_I(imem, format, tip) /* za številke */ \ m->imem = strto##format(RTV_META_IZPOLNI_VALUE_INTERNAL, NULL, 10); #define RTV_META_IZPOLNI(imem, oblika, format, splitter, tip) \ do { cp = strchr(RTV_META_IZPOLNI_VALUE_INTERNAL, splitter); \ if (cp == NULL) { \ RTV_NAPISI(OPOZORILO, "Napaka pri iskanju podatka " #imem); \ /* strcpy(m->imem, "Napaka pri pridobivanju."); */ /* ni vse s*/ \ } else { \ oblika(imem, format, tip) \ RTV_NAPISI(HROSC, "Shranil metapodatek " #imem ": %" #format, \ m->imem); \ } } while (0) /* #pragma GCC diagnostic ignored "-Wint-conversion" */ /* surpressaš opozor. */ RTV_META_IZPOLNI(naslov, RTV_META_IZPOLNI_V, s, '"', char); break; case 1: /* showId */ RTV_META_IZPOLNI(tip_oddaje_id, RTV_META_IZPOLNI_I, u, '"', unsigned int); break; case 2: /* genre je "asdasd","asdasd","sdfsfd" */ RTV_META_IZPOLNI(zanri, RTV_META_IZPOLNI_V, s, ']', char); memmove(m->zanri, (m->zanri)+1, strlen(m->zanri)+1); break; case 3: /* description */ RTV_META_IZPOLNI(opis, RTV_META_IZPOLNI_V, s, '"', char); break; case 4: /* showDescription */ if (m->opis[0] == '\0') { /* če je prejšnji spodletel */ RTV_META_IZPOLNI(opis, RTV_META_IZPOLNI_V, s, '"', char); } break; case 5: /* duration */ #undef RTV_META_IZPOLNI_VALUE_INTERNAL #define RTV_META_IZPOLNI_VALUE_INTERNAL RTV_META_IZPOLNI_VALUE-1 RTV_META_IZPOLNI(dolzina, RTV_META_IZPOLNI_I, u, '"', unsigned int); #undef RTV_META_IZPOLNI_VALUE_INTERNAL #define RTV_META_IZPOLNI_VALUE_INTERNAL RTV_META_IZPOLNI_VALUE break; case 6: /* jwt */ RTV_META_IZPOLNI(jwt, RTV_META_IZPOLNI_V, s, '"', char); if (RTV_JWT_SIZEOF != m->jwt_sizeof) { RTV_NAPISI(OPOZORILO, "Shranil nepričakovano dolg JWT! Je vdor?"); } break; case 7: /* showName */ RTV_META_IZPOLNI(tip_oddaje_ime, RTV_META_IZPOLNI_V, s, '"', char); break; case 8: /* source */ RTV_META_IZPOLNI(program, RTV_META_IZPOLNI_V, s, '"', char); break; case 9: /* publishDate */ RTV_META_IZPOLNI(objavljeno, RTV_META_IZPOLNI_V, s, '"', char); break; case 10: /* mediaType */ switch (RTV_META_IZPOLNI_VALUE[0]) { case 'v': m->tip_posnetka = RTV_VIDEO_TIP; break; case 'a': m->tip_posnetka = RTV_AUDIO_TIP; break; default: m->tip_posnetka = RTV_NEPOZNAN_TIP; break; } break; case 11: /* orig */ /* sličica */ RTV_META_IZPOLNI(slicica, RTV_META_IZPOLNI_V, s, '"', char); break; case 12: /* broadcastDate */ RTV_META_IZPOLNI(predvajano, RTV_META_IZPOLNI_V, s, '"', char); break; /* #pragma GCC diagnostic warning "-Wint-conversion" */ /* undo */ default: RTV_NAPISI(OPOZORILO, "Doseg nedefinirane kode!"); } } } } snprintf(m->get_media_url, RTV_API_MEDIA_URL_SIZEOF, RTV_API_MEDIA_URL, m->id, m->jwt); rewind(odgstream); fflush(odgstream); returnstatus = http_get(m->get_media_url, odgstream); /* shranimo video url */ if (returnstatus != 0) { RTV_NAPISI(NAPAKA, "Zahteva za ključ videa iz API strežnika je spodletela"); goto rtv_meta_izpolni_returncleanly; } fflush(odgstream); /* * sedaj pridobimo direktni URL do mp4 datoteke, ki ima keylockhash v GET * parametru. OPOMBA: treba je najti NAJKVALITETNEJŠO datoteko, ker RTVSLO * strežnik pošilja zmešan vrstni red JSON parametrov, bo treba najti drug * način. ugotovil sem, da, če je stream v addaptiveMedia JSON podobjektu, * bo ta vedno največji, če pa obstaja samo en stream, pa addaptiveMedia * podobjekta sploh ne bo. torej, če se je string addaptiveMedia pojavil * tik pred tem URLjem, bo ta najboljši in lahko nehamo. */ for (i = 0; i < ftell(odgstream); i++) { for (j = RTV_META_IZPOLNI_METAKEYS_SIZEOF; j < RTV_META_IZPOLNI_METAKEYS_GETMEDIA_FINAL; j++) { if (strncmp(odg+i, metakeys[j], strlen(metakeys[j])) == 0) { switch (j-RTV_META_IZPOLNI_METAKEYS_SIZEOF) { case 0: /* http */ /* videofile */ RTV_META_IZPOLNI(posnetek_url, RTV_META_IZPOLNI_V, s, '"', char); if (nasel_addaptivemedia == 1) { RTV_NAPISI(HROSC, "Izmed več streamov izbral najboljšega."); goto rtv_meta_izpolni_naselnajboljsistream; } nasel_addaptivemedia = 0; break; case 1: /* https */ if (m->posnetek_url[0] == '\0') { RTV_META_IZPOLNI(posnetek_url, RTV_META_IZPOLNI_V, s, '"', char); fprintf(stderr, "test: %s\n", m->posnetek_url); memmove((m->posnetek_url)+4, (m->posnetek_url)+5, strlen((m->posnetek_url)+5)+1); RTV_NAPISI(HROSC, "Popravil HTTPS URL na HTTP"); if (nasel_addaptivemedia == 1) { RTV_NAPISI(HROSC, "Izmed več streamov izbral najboljšega."); goto rtv_meta_izpolni_naselnajboljsistream; } } nasel_addaptivemedia = 0; break; case 2: /* addaptiveMedia */ nasel_addaptivemedia = 1; RTV_NAPISI(HROSC, "Naslednji najden pretok bo najboljši."); break; default: RTV_NAPISI(OPOZORILO, "Doseg nedefinirane kode; case=%lu", j-RTV_META_IZPOLNI_METAKEYS_SIZEOF); } } } } /* endfor: for (i = 0; i < ftell(odgstream); i++) */ rtv_meta_izpolni_naselnajboljsistream: rtv_meta_izpolni_returncleanly: fclose(odgstream); free(odg); odg = NULL; return returnstatus; } int main (int argc, char ** argv) { if (argc < 1+1) { fprintf(stderr, "preberi README.md pred uporabo programa, saj vsebuje navodila in ostalo.\n"); return 1; } struct meta_oddaja * m = meta_oddaja_alloc(); char fn[69]; /* .txt / .mp4 - NE USER INPUT */ char * e; /* char pointer for the memes */ FILE * fd; unsigned short int returnstatus = 0; if (RTV_URL != NULL) { m->id = atoi(RTV_URL); if (strrchr(RTV_URL, '/') != NULL) m->id = atoi(strrchr(RTV_URL, '/')+1); if (m->id <= 0) { fprintf(stderr, "IDja oddaje ni uspelo dobiti. preverite vnos.\n"); returnstatus = 3; goto returncleanly; } } else { m->id = RTV_TEST_ID; } switch (RTV_NACIN[0]) { case 't': /* test - program se preizkusi brez prenosa datotek */ RTV_NAPISI(NAPAKA, "samotestiranje še ni izdelano!"); break; case 'o': /* oddaja - prenese oddajo v datoteko */ if (rtv_meta_izpolni(m) != 0) { RTV_NAPISI(NAPAKA, "Ni uspelo pridobiti metapodatkov oddaje."); returnstatus = 4; goto returncleanly; } if (argc < 4) { e = strrchr(m->posnetek_url, '.'); snprintf(fn, 68, "%u%.4s", m->id, e); fd = fopen(fn, "w"); } else { fd = fopen(argv[3], "w"); } if (fd == NULL) { RTV_NAPISI(NAPAKA, "Ni uspelo odpreti datoteke za pisanje vanjo."); returnstatus = 5; goto returncleanly; } if (http_get(m->posnetek_url, fd) == 0) { RTV_NAPISI(INFO, "uspešno shranjeno."); } else { RTV_NAPISI(NAPAKA, "Nekaj je spodletelo pri http_get()"); returnstatus = 6; } break; case 'm': /* meta-oddaja - prenese metapodatke o oddaji */ if (rtv_meta_izpolni(m) != 0) { RTV_NAPISI(NAPAKA, "Ni uspelo pridobiti metapodatkov oddaje."); returnstatus = 4; goto returncleanly; } if (argc < 4) { /* e = strrchr(m->posnetek_url, '.'); */ snprintf(fn, 68, "%u%s", m->id, ".txt"); fd = fopen(fn, "w"); } else { fd = fopen(argv[3], "w"); } if (fd == NULL) { RTV_NAPISI(NAPAKA, "Ni uspelo odpreti datoteke za pisanje vanjo."); returnstatus = 5; goto returncleanly; } fprintf(fd, "id: %u\nnaslov: %s\ntip_oddaje_id: %u\nzanri: %s\nopis: %s\n" "dolzina: %u\njwt: %s\ntip_oddaje_ime: %s\nprogram: %s\n" "objavljeno: %s\ntip_posnetka: %s\nslicica: %s\npredvajano: %s\n" /* "velikost: %llu\n" */ "get_meta_url: %s\nget_media_url: %s\n" "predvajalnik_url: %s\nposnetek_url: %s\n", m->id, m->naslov, m->tip_oddaje_id, m->zanri, m->opis, m->dolzina, m->jwt, m->tip_oddaje_ime, m->program, m->objavljeno, m->tip_posnetka == RTV_VIDEO_TIP ? "RTV_VIDEO_TIP" : \ m->tip_posnetka == RTV_AUDIO_TIP ? "RTV_AUDIO_TIP":"RTV_NEPOZNAN_TIP", m->slicica, m->predvajano, /* m->velikost, */ m->get_meta_url, m->get_media_url, m->predvajalnik_url, m->posnetek_url); fclose(fd); break; case 's': /* sličica - prenese sličico oddaje */ if (rtv_meta_izpolni(m) != 0) { RTV_NAPISI(NAPAKA, "Ni uspelo pridobiti metapodatkov oddaje."); returnstatus = 4; goto returncleanly; } if (argc < 4) { e = strrchr(m->slicica, '.'); snprintf(fn, 68, "%u%.4s", m->id, e); fd = fopen(fn, "w"); } else { fd = fopen(argv[3], "w"); } if (fd == NULL) { RTV_NAPISI(NAPAKA, "Ni uspelo odpreti datoteke za pisanje vanjo."); returnstatus = 5; goto returncleanly; } if (http_get(m->slicica, fd) == 0) { RTV_NAPISI(INFO, "uspešno shranjeno."); } else { RTV_NAPISI(NAPAKA, "Nekaj je spodletelo pri http_get()"); returnstatus = 6; } break; default: fprintf(stderr, "opcija ne obstaja! poskusi test.\n"); returnstatus = 2; goto returncleanly; break; } returncleanly: meta_oddaja_free(m); m = NULL; return returnstatus; }