From: Antoine Jacquet Date: Tue, 7 Feb 2006 23:00:00 +0000 (+0100) Subject: version 0.35 (by Andreas Neuper) X-Git-Tag: v0.35 X-Git-Url: http://royale.zerezo.com/git/?a=commitdiff_plain;h=e2f3f82e0ae06d888512028fa1e9572082612807;p=FAPG version 0.35 (by Andreas Neuper) * BUG fix: no more ampersand in RSS feeds are passed * BUG fix: no more spaces or non-printables in links of RSS feeds * BUG fix: potential access violations removed * speed up printing by using table assignment (since predictiv) * added hook to get additional info for RSS feeds (default is to use internal only) * remove multiple slashes like ./// and //// as well * clean with gnu compiler V3.3 (you might add but never remove 'unsigned'!) * RSS feed successfully tested with iPod/iTunes and German language --- diff --git a/CHANGELOG b/CHANGELOG index cfc88f1..32497e0 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,15 @@ Change log file for FAPG +version 0.35 (2006-02-08) (by Andreas Neuper) + * BUG fix: no more ampersand in RSS feeds are passed + * BUG fix: no more spaces or non-printables in links of RSS feeds + * BUG fix: potential access violations removed + * speed up printing by using table assignment (since predictiv) + * added hook to get additional info for RSS feeds (default is to use internal only) + * remove multiple slashes like ./// and //// as well + * clean with gnu compiler V3.3 (you might add but never remove 'unsigned'!) + * RSS feed successfully tested with iPod/iTunes and German language + version 0.34 (2006-01-21) (by Andreas Neuper) * BUG fix: "unsigned char" (like in 0.31) to get complete output and avoid core dumps * BUG fix: disabled "skip" variable to use multiple args diff --git a/Makefile b/Makefile index 990ae9c..6e8000f 100644 --- a/Makefile +++ b/Makefile @@ -2,14 +2,22 @@ PRE = /usr/local BIN = $(PRE)/bin DOC = $(PRE)/share/doc/fapg MAN = $(PRE)/share/man/man1 +CFLAGS=-Wall -g2 -funsigned-char -fapg:fapg.c genres.h - gcc -Wall -o fapg fapg.c +fapg: fapg.c + +fapg.c: genres.h + touch $@ clean: rm -f fapg -install:fapg +beautify: + indent -nut -kr -ncs -nsaf -npcs -nsai -nsaw -o fapg.good.c fapg.c &&\ + mv fapg.good.c fapg.c + splint -checks fapg.c + +install: fapg mkdir -p $(BIN) $(DOC) $(MAN) cp -f fapg $(BIN) cp -f COPYING README $(DOC) diff --git a/README b/README index 332dae5..d48459a 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -FAPG 0.34 (Fast Audio Playlist Generator) +FAPG 0.35 (Fast Audio Playlist Generator) site: http://royale.zerezo.com/fapg/ mail: royale@zerezo.com @@ -7,7 +7,7 @@ make make install usage: -fapg [-b|--backslash] [-d|--debug] [-f|--format=m3u|pls|html|rss] [-g|--genre=#:#:...] [-o|--output=/path/to/file.m3u] [-p|--prefix=/the/prefix] [-r|--recursive] [-w|--windows] [-x|--exclude=#:#:...] /path/to/mp3/dir1 [/path/to/mp3/dir2 ...] +fapg [-b|--backslash] [-d|--debug] [-f|--format=m3u|pls|html|rss] [-g|--genre=#:#:...] [-o|--output=/path/to/file.m3u] [-p|--prefix=/the/prefix] [-r|--recursive] [-w|--windows] [-x|--exclude=#:#:...] [-c|--command=] /path/to/mp3/dir1 [/path/to/mp3/dir2 ...] - backslash : replace the '/' with '\' in Unix path. - debug : display useful messages if the program fails ;) - format : choose which format of playlist you want to generate (default is m3u). @@ -17,6 +17,7 @@ fapg [-b|--backslash] [-d|--debug] [-f|--format=m3u|pls|html|rss] [-g|--genre=#: - recursive : recursively read the subdirectories. - windows : replace all Unix characters with Windows characters... - exclude : choose which genres will be excluded in the generated playlist (default is none). +- command : external binary or script that produces additional fields for RSS feeds (slow) links : http://geek.scorpiorising.ca/scripts.html diff --git a/fapg.1 b/fapg.1 index 8b3588f..c7ca1ff 100644 --- a/fapg.1 +++ b/fapg.1 @@ -62,7 +62,7 @@ on the server containing the files is and is visible on the Windows network as .I \\\\\\\\server\\\\mp3 : -.B fapg --backslash --output=/samba/mp3/list.m3u --prefix='\\\\\\\\server\\\\mp3\\\\' --recursive --windows /samba/mp3 +.B cd /samba/mp3 && fapg --backslash --output=/samba/mp3/list.m3u --prefix='\\\\\\\\server\\\\mp3\\\\' --recursive --windows ./ An HTML playlist for an album: .B fapg --output=fapg.html ~/path/to/album @@ -70,9 +70,12 @@ An HTML playlist for an album: A playlist that contains all your classical tracks may receive the genres to include (or exclude) in one or multiple portions .B fapg --genre=32:105 --genre=106:104:103 /path/to/all/music -Generate a podcasting XML file: -.B fapg --output=dir.xml -f rss -r --prefix=http://thisserver/basedir path/to/mp3 -Please note that in all given directories ( and in /rss ) files called podcast.jpg are referenced. +Generate a podcasting XML file using an external program rss.sh to generate a detailed description: +.B fapg --output=dir.xml -f rss -c /usr/local/bin/rss.sh -r --prefix=http://thisserver/basedir path/to/mp3 +if command starts with +.I intern +the build-in description (Author,Title,Link) is generated. +Please note that in all given directories ( and in ...basedir/xml ) files called podcast.jpg are referenced. Many header fields are set to defaults using environment variables like LOGNAME or LANG. diff --git a/fapg.c b/fapg.c index e627ea5..19eb30a 100644 --- a/fapg.c +++ b/fapg.c @@ -1,7 +1,7 @@ /* * FAPG */ -#define VERSION "0.34" +#define VERSION "0.35" /* * FAPG means Fast Audio Playlist Generator. * It is a tool to generate list of audio files (Wav, MP3, Ogg, etc) @@ -44,472 +44,767 @@ #define MP3_BASE 1024 #define OGG_BASE 1024*10 -#define MAX 1024*200 /* 200ko for ID3 with JPEG images in it */ - -int debug=0; -int format=0; /* 0 = m3u ; 1 = pls ; 2 = html ; 3 = rss */ -char *genrelist=NULL; -unsigned char *prefix=""; -unsigned char *base=""; -unsigned char *dir=""; -unsigned char *hostname="fritzserver.de"; -unsigned char *referal="http://www.explaining.text.org/select.php?title="; -int recursive=0; -int avoidhlinked=0; -int separator='/'; -int skip=0; -int windows=0; -unsigned char *eol="\n"; +#define MAX 1024*200 /* 200ko for ID3 with JPEG images in it */ + +int debug = 0; +int format = 0; /* 0 = m3u ; 1 = pls ; 2 = html ; 3 = rss */ +char *genrelist = NULL; +unsigned char *prefix = ""; +unsigned char *base = ""; +unsigned char *dir = ""; +unsigned char *hostname = "fritzserver.de"; +// unsigned char *referal="/usr/local/bin/fapg-rss.sh"; +unsigned char *referal = NULL; +//int windows=0; +int recursive = 0; +int avoidhlinked = 0; +int separator = '/'; +unsigned char *eol = "\n"; unsigned char buffer[MAX]; -int counter=0; +int counter = 0; unsigned char artist[1024]; unsigned char title[1024]; unsigned char genrebuf[1024]; -unsigned char genre=0; +unsigned char genre = 0; int duration; +#define MP2ENC 1 +#define MP3ENC 2 +#define MPCENC 3 +#define MPPENC 4 +#define OGGENC 5 +#define WAVENC 6 + +char *magic[] = { NULL, + "audio/mpeg", "audio/mpeg", + "audio/mpeg", "audio/mpeg", + "audio/ogg-vorbis", "audio/x-wav", + NULL +}; + +unsigned char unix2dos[] = + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 70, 35, 36, 37, 38, 39, 40, 41, 82, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 84, 59, 36, 61, 65, 71, + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 36, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 36, 125, 126, 127, + 199, 252, 233, 226, 228, 224, 229, 231, + 234, 235, 232, 239, 238, 236, 196, 197, + 201, 230, 198, 244, 246, 242, 251, 249, + 255, 214, 220, 248, 163, 216, 215, 131, + 225, 237, 243, 250, 241, 209, 170, 186, + 191, 174, 172, 189, 188, 161, 171, 187, + 166, 166, 166, 166, 166, 193, 194, 192, + 169, 166, 166, 43, 43, 162, 165, 43, + 43, 45, 45, 43, 45, 43, 227, 195, + 43, 43, 45, 45, 166, 45, 43, 164, + 240, 208, 202, 203, 200, 105, 205, 206, + 207, 43, 43, 166, 220, 166, 204, 175, + 211, 223, 212, 210, 245, 213, 181, 254, + 222, 218, 219, 217, 253, 221, 175, 180, + 173, 177, 61, 190, 182, 167, 247, 184, + 176, 168, 183, 185, 179, 178, 166, 160 +}; -unsigned char unix2dos[256]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,70,35,36,37,38,39,40,41,82,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,84,59,36,61,65,71,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,36,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,36,125,126,127,199,252,233,226,228,224,229,231,234,235,232,239,238,236,196,197,201,230,198,244,246,242,251,249,255,214,220,248,163,216,215,131,225,237,243,250,241,209,170,186,191,174,172,189,188,161,171,187,166,166,166,166,166,193,194,192,169,166,166,43,43,162,165,43,43,45,45,43,45,43,227,195,43,43,45,45,166,45,43,164,240,208,202,203,200,105,205,206,207,43,43,166,220,166,204,175,211,223,212,210,245,213,181,254,222,218,219,217,253,221,175,180,173,177,61,190,182,167,247,184,176,168,183,185,179,178,166,160}; +unsigned char *basemap; +unsigned char *winorunix; +unsigned char one2one[] = + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 71, + 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, + 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, + 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, + 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 231, + 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, 253, 254, 255 +}; /* identical mapping */ + +unsigned char noand[256] = + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 43, 39, + 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 71, + 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, + 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, + 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, + 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 231, + 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, 253, 254, 255 +}; /* only '&' is mapped to '+' */ + +unsigned char *iso2web[256] = { + "%00", "%01", "%02", "%03", "%04", "%05", "%06", "%07", + "%08", "%09", "%0a", "%0b", "%0c", "%0d", "%0e", "%0f", + "%10", "%11", "%12", "%13", "%14", "%15", "%16", "%17", + "%18", "%19", "%1a", "%1b", "%1c", "%1d", "%1e", "%1f", + "%20", "%21", "%22", "%23", "%24", "%25", "%26", "%27", + "%28", "%29", "%2a", "+", ",", "-", ".", "/", + "0", "1", "2", "3", "4", "5", "6", "7", + "8", "9", ":", ";", "%3c", "=", "%3e", "%3f", + "@", "A", "B", "C", "D", "E", "F", "G", + "H", "I", "J", "K", "L", "M", "N", "O", + "P", "Q", "R", "S", "T", "U", "V", "W", + "X", "Y", "Z", "%5B", "\\", "%5D", "^", "_", + "`", "a", "b", "c", "d", "e", "f", "g", + "h", "i", "j", "k", "l", "m", "n", "o", + "p", "q", "r", "s", "t", "u", "v", "w", + "x", "y", "z", "%7b", "|", "%7d", "~", "%7f", + "%80", "%81", "%82", "%83", "%84", "%85", "%86", "%87", + "%88", "%89", "%8a", "%8b", "%8c", "%8d", "%8e", "%8f", + "%90", "%91", "%92", "%93", "%94", "%95", "%96", "%97", + "%98", "%99", "%9a", "%9b", "%9c", "%9d", "%9e", "%9f", + "%a0", "%a1", "%a2", "%a3", "%a4", "%a5", "%a6", "%a7", + "%a8", "%a9", "%aa", "%ab", "%ac", "%ad", "%ae", "%af", + "%b0", "%b1", "%b2", "%b3", "%b4", "%b5", "%b6", "%b7", + "%b8", "%b9", "%ba", "%bb", "%bc", "%bd", "%be", "%bf", + "%c0", "%c1", "%c2", "%c3", "%c4", "%c5", "%c6", "%c7", + "%c8", "%c9", "%ca", "%cb", "%cc", "%cd", "%ce", "%cf", + "%d0", "%d1", "%d2", "%d3", "%d4", "%d5", "%d6", "%d7", + "%d8", "%d9", "%da", "%db", "%dc", "%dd", "%de", "%df", + "%e0", "%e1", "%e2", "%e3", "%e4", "%e5", "%e6", "%e7", + "%e8", "%e9", "%ea", "%eb", "%ec", "%ed", "%ee", "%ef", + "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7", + "%f8", "%f9", "%fa", "%fb", "%fc", "%fd", "%fe", "%ff" +}; void usage() { - fprintf(stderr,"Usage >> fapg [-b|--backslash] [-d|--debug] [-f|--format=m3u|pls|html|rss] [-g|--genre=#:#:...] [-n|--nohardlink] [-o|--output=/path/to/file.m3u] [-p|--prefix=/the/prefix] [-r|--recursive] [-w|--windows] [-x|--exclude=#:#:...] /path/to/mp3/dir1 [/path/to/mp3/dir2 ...]\n"); - exit(1); + fprintf(stderr, + "Usage >> fapg [-b|--backslash] [-d|--debug] [-f|--format=m3u|pls|html|rss] [-g|--genre=#:#:...] [-n|--nohardlink] [-o|--output=/path/to/file.m3u] [-p|--prefix=/the/prefix] [-r|--recursive] [-w|--windows] [-c|--command=] [-x|--exclude=#:#:...] /path/to/mp3/dir1 [/path/to/mp3/dir2 ...]\n"); + exit(1); } -const char*reflink(const char*title) +#define mywebputchar(x) { fputs(iso2web[(unsigned char)winorunix[(unsigned char)x]], stdout); } +#define myputchar(x) { putchar(basemap[(unsigned char)winorunix[(unsigned char)x]]); } + +void mywebputstr(const char *c) { - int i=0; - static char *buffer; - buffer=malloc(strlen(title)+strlen(referal)+2); - strcpy(buffer,referal); - strcat(buffer,title); - for(i=strlen(referal);i> unable to allocate cleared memory\n"); exit(2); } - else - { - int n=0; - while (n> genrelist entry activting : %d\n",atoi(&optarg[n])); - genrelist[atoi(&optarg[n])]=1; - while (isdigit(optarg[n++])); - } - } - break; - case 'n': - avoidhlinked=1; - break; - case 'o': - close(1); - if (fopen(optarg,"w")==NULL) { fprintf(stderr,"Error >> unable to open output file : %s\n",optarg); exit(2); } - break; - case 'p': - prefix=malloc(strlen(optarg)+1); - strcpy(prefix,optarg); - base=malloc(strlen(prefix)+1); - strcpy(base,prefix); - dir=strchr(base,'/'); - if( (dir!=NULL) && (dir[1]=='/') ) dir=strchr(dir+2,'/'); - if (dir!=NULL) *dir++=0; else dir=""; - /* if prefix is a weblink, base is the baselink, dir is the path */ - break; - case 'r': - recursive=1; - break; - case 'w': - windows=1; - eol="\r\n"; - break; - case 'x': - if (genrelist==NULL) /* allow multiple includes/excludes - not recommended (confusing) but possible */ - { - int n=0; - genrelist=calloc(257,sizeof(char)); - while (n<256) genrelist[n++]=1; - } - if (genrelist==NULL) { fprintf(stderr,"Error >> unable to allocate cleared memory\n"); exit(2); } - else - { - int n=0; - while (n> genrelist entry activting : %d\n",atoi(&optarg[n])); - genrelist[atoi(&optarg[n])]=0; - while (isdigit(optarg[n++])); - } - } - break; - default: - usage(); + while(*c != 0) { + myputchar(*c); + c++; + /* remove multiple slashes "//" when parsing a directory ending with a "/" */ + while(*c == '/' && c[1] == '/') + c++; } - } - /* hostname = getenv("HOSTNAME"); */ - if (genrelist==NULL) - { - genrelist=calloc(257,sizeof(char)); - if (genrelist==NULL) { fprintf(stderr,"Error >> unable to allocate cleared memory\n"); exit(2); } - else - { - int n=0; - while (n<256) genrelist[n++]=1; +} + +void print_webpath(const char *path) +{ + const char *c = path; + + printf(prefix); /* we must not modify this part */ + if(*c == '.' && c[1] == '/') { /* remove leading "./" when parsing current directory */ + c += 2; + /* maybe there follow many slashes */ + while(*c == '/') + c++; + } + for(; *c != '\0'; c++) { + mywebputchar(*c); + /* remove multiple "//" when parsing a directory ending with a "/" */ + while(*c == '/' && c[1] == '/') + c++; } - } } -void parse_mp3(unsigned char *file) +void print_path(const char *path) { - int bitrates[2][3][15]= - {{{0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448}, - {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384}, - {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320}}, - {{0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256}, - {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160}, - {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160}}}; - FILE *fic; - unsigned char *c; - int lus; - - genre=0; - genrebuf[0]=0; - if (debug) fprintf(stderr,"Debug >> parsing mp3 : %s\n",file); - - /* read header */ - if ((fic=fopen(file,"r"))==NULL) { fprintf(stderr,"Warning >> can't open file : %s\n",file); return; } - lus=fread(buffer,1,MP3_BASE,fic); - c=buffer; - - /* try ID3v2 */ - if (buffer[0]=='I' && buffer[1]=='D' && buffer[2]=='3') - { - int size; - int version; - version=*(buffer+3); - if (version<2 || version>4) - fprintf(stderr,"Warning >> ID3 v2.%d not implemented ! trying anyway : %s\n",version,file); - if (*(buffer+5)!=0) - fprintf(stderr,"Warning >> specials headers not implemented (%d) ! trying anyway : %s\n",*(buffer+5),file); - c=buffer+6; - size=(*c<<21)+(*(c+1)<<14)+(*(c+2)<<7)+(*(c+3)); - /* read more header */ - if (size+lus>MAX) - { - lus+=fread(buffer+lus,1,MAX-lus,fic); - fprintf(stderr,"Warning >> ID3 header is huge (%d bytes) ! trying anyway : %s\n",size,file); + const char *c = path; + printf(prefix); + /* skip leading "./" when parsing current directory */ + if(*c == '.' && *(c + 1) == '/') { + c += 2; + /* maybe there follow more slashes */ + while(*c == '/') + c++; } + myputstr(c); +} + +void print_pathtail(const char *path) +{ + const char *c; + c = strrchr(path, separator); + if(c != NULL) + c++; else - lus+=fread(buffer+lus,1,size,fic); - if (size>lus) size=lus; - c+=4; - if (version==2) while (c>3&1); - lay=4-(*(c+1)>>1&3); - bitrate_index=*(c+2)>>4&0xF; - if (version>=1 && version<=2 && lay-1>=0 && lay-1<=2 && bitrate_index>=0 && bitrate_index<=14) - bitrate=bitrates[version-1][lay-1][bitrate_index]; - else - bitrate=0; - if (bitrate!=0) - { - fseek(fic,0,SEEK_END); - duration=(ftell(fic)+buffer-c)/125/bitrate; - } - else - duration=0; - break; - } - c++; - } - - /* try ID3v1 */ - if (strlen(artist)==0 && strlen(title)==0) - { - fseek(fic,-128,SEEK_END); - lus=fread(buffer,1,128,fic); - if (lus==128 && buffer[0]=='T' && buffer[1]=='A' && buffer[2]=='G') - { - strncpy(title,buffer+3,30); - title[30]='\0'; - c=title+29; - while (c>title && *c==' ') *(c--)='\0'; - strncpy(artist,buffer+33,30); - artist[30]='\0'; - c=artist+29; - while (c>artist && *c==' ') *(c--)='\0'; - /* strncpy(album,buffer+65,30); */ - /* strncpy(year,buffer+97,4); */ - /* strncpy(comment,buffer+101,30); */ - /* strncpy(genrebuf,buffer+127,1); genre[1]=0; */ - genre=buffer[127]; - } - } - - fclose(fic); -} + c = path; + myputstr(c); +} -void parse_ogg(unsigned char *file) +void noreferal(const char *path, const char *artist, const char *title) { - FILE *fic; - unsigned char *c; - int lus; - int sample_rate; - int samples; - - if (debug) fprintf(stderr,"Debug >> parsing ogg : %s\n",file); - - /* read header */ - if ((fic=fopen(file,"r"))==NULL) { fprintf(stderr,"Warning >> can't open file : %s\n",file); return; } - lus=fread(buffer,1,OGG_BASE,fic); - - /* try Ogg */ - if (buffer[0]!='O' && buffer[1]!='g' && buffer[2]!='g') - { - fprintf(stderr,"Warning >> not a Ogg header : %s\n",file); + printf("\t\t"); + myputstr(artist); + printf("
"); + myputstr(title); + printf("


Direct Link to Audiofile

]]>
%s", + eol); +} + +void reference(const char *title) +{ + FILE *pipe = NULL; + static char command[2048], buffer[1024]; + int buflen = 8192; + + buflen = strlen(title) + strlen(referal) + 3; + assert((buflen < 2046)); + strcpy(command, referal); + buflen = strlen(command); + command[buflen] = ' '; + command[buflen + 1] = '"'; + command[buflen + 2] = 0; + strcat(command, title); + buflen = strlen(command); + command[buflen] = '"'; + command[buflen + 1] = 0; + if(debug) + fprintf(stderr, "Debug >> processing command: %s\n", command); + pipe = popen(command, "r"); + if(pipe == NULL) { + fprintf(stderr, "Warning >> can't open pipe >%s< !\n", command); + free(command); + return; + } + fgets(buffer, 1020, pipe); + while(!feof(pipe)) { + fputs(buffer, stdout); + fgets(buffer, 1020, pipe); + } + pclose(pipe); return; - } - - c=buffer+0x28; - sample_rate=(*c)+(*(c+1)<<8)+(*(c+2)<<16)+(*(c+3)<<24); - - while (c> unable to allocate cleared memory\n"); + exit(2); + } else { + unsigned int n = 0; + while(n < strlen(optarg)) { + if(debug) + fprintf(stderr, + "Debug >> genrelist entry activting : %d\n", + atoi(&optarg[n])); + genrelist[atoi(&optarg[n])] = 1; + while(isdigit(optarg[n++])); + } + } + break; + case 'n': + avoidhlinked = 1; + break; + case 'o': + close(1); + if(fopen(optarg, "w") == NULL) { + fprintf(stderr, + "Error >> unable to open output file : %s\n", + optarg); + exit(2); + } + break; + case 'p': + prefix = malloc(strlen(optarg) + 1); + strcpy(prefix, optarg); + base = malloc(strlen(prefix) + 1); + strcpy(base, prefix); + dir = strchr(base, '/'); + if((dir != NULL) && (dir[1] == '/')) + dir = strchr(dir + 2, '/'); + if(dir != NULL) + *dir++ = 0; + else + dir = ""; + /* if prefix is a weblink, base is the baselink, dir is the path */ + break; + case 'r': + recursive = 1; + break; + case 'u': + winorunix = one2one; + eol = "\n"; + break; + case 'w': + winorunix = unix2dos; + eol = "\r\n"; + break; + case 'x': + if(genrelist == NULL) { /* allow multiple includes/excludes - not recommended (confusing) but possible */ + int n = 0; + genrelist = calloc(257, sizeof(char)); + while(n < 256) + genrelist[n++] = 1; + } + if(genrelist == NULL) { + fprintf(stderr, + "Error >> unable to allocate cleared memory\n"); + exit(2); + } else { + unsigned int n = 0; + while(n < strlen(optarg)) { + if(debug) + fprintf(stderr, + "Debug >> genrelist entry activting : %d\n", + atoi(&optarg[n])); + genrelist[atoi(&optarg[n])] = 0; + while(isdigit(optarg[n++])); + } + } + break; + default: + usage(); + } + } + /* hostname = getenv("HOSTNAME"); */ + if(genrelist == NULL) { + genrelist = calloc(257, sizeof(char)); + if(genrelist == NULL) { + fprintf(stderr, + "Error >> unable to allocate cleared memory\n"); + exit(2); + } else { + int n = 0; + while(n < 256) + genrelist[n++] = 1; } - if (i==ID3_NR_OF_V1_GENRES) genre=0; - } - } - c++; - } - - fseek(fic,-OGG_BASE,SEEK_END); - lus=fread(buffer,1,OGG_BASE,fic); - c=buffer+lus-1; - while (strncmp(c,"OggS",4)!=0 && c>buffer) c--; - if (c!=buffer) - { - c+=6; - samples=(*c)+(*(c+1)<<8)+(*(c+2)<<16)+(*(c+3)<<24); - duration=samples/sample_rate; - } - - fclose(fic); + } } -void parse_mpc(unsigned char *file) +void parse_mp3(unsigned char *file) { - FILE *fic; - unsigned char *c; - int lus; - int sample_rates[4]={44100,48000,37800,32000}; - int frame_count; - int size,items; - int i; - - if (debug) fprintf(stderr,"Debug >> parsing mpc : %s\n",file); - - /* read header */ - if ((fic=fopen(file,"r"))==NULL) { fprintf(stderr,"Warning >> can't open file : %s\n",file); return; } - lus=fread(buffer,1,12,fic); - - /* try Musepack */ - if (buffer[0]!='M' && buffer[1]!='P' && buffer[2]!='+') - { - fprintf(stderr,"Warning >> not a Musepack header : %s\n",file); - return; - } - - /* only version 7 */ - if (buffer[3]!=7) - { - fprintf(stderr,"Warning >> only Musepack SV7 supported : %s\n",file); - return; - } - - /* duration */ - c=buffer+4; - frame_count=(*c)+(*(c+1)<<8)+(*(c+2)<<16)+(*(c+3)<<24); - c+=5; - duration=frame_count*1152/sample_rates[*c&3]; - - /* try APETAGEX footer */ - fseek(fic,-32,SEEK_END); - lus=fread(buffer,1,32,fic); - if (lus==32 && strncmp(buffer,"APETAGEX",8)==0) - { - c=buffer+12; - size=(*c)+(*(c+1)<<8)+(*(c+2)<<16)+(*(c+3)<<24); - size+=32; - c+=4; - items=(*c)+(*(c+1)<<8)+(*(c+2)<<16)+(*(c+3)<<24); - fseek(fic,-size,SEEK_END); - lus=fread(buffer,1,size,fic); - if (lus==size && strncmp(buffer,"APETAGEX",8)==0) - { - c=buffer+32; - while (items--) - { - size=(*c)+(*(c+1)<<8)+(*(c+2)<<16)+(*(c+3)<<24); - c+=8; - if (strcasecmp(c,"TITLE")==0) - { - strncpy(title,c+6,size); - title[size]='\0'; + int bitrates[2][3][15] = + { {{0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, + 416, 448}, + {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, + 384}, + {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, + 320}}, + {{0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256}, + {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160}, + {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160}} + }; + FILE *fic; + unsigned char *c; + int lus; + + genre = 0; + genrebuf[0] = 0; + if(debug) + fprintf(stderr, "Debug >> parsing mp3 : %s\n", file); + + /* read header */ + if((fic = fopen(file, "r")) == NULL) { + fprintf(stderr, "Warning >> can't open file : %s\n", file); + return; + } + lus = fread(buffer, 1, MP3_BASE, fic); + c = buffer; + + /* try ID3v2 */ + if(buffer[0] == 'I' && buffer[1] == 'D' && buffer[2] == '3') { + int size; + int version; + version = *(buffer + 3); + if(version < 2 || version > 4) + fprintf(stderr, + "Warning >> ID3 v2.%d not implemented ! trying anyway : %s\n", + version, file); + if(*(buffer + 5) != 0) + fprintf(stderr, + "Warning >> specials headers not implemented (%d) ! trying anyway : %s\n", + *(buffer + 5), file); + c = buffer + 6; + size = + (*c << 21) + (*(c + 1) << 14) + (*(c + 2) << 7) + (*(c + 3)); + /* read more header */ + if(size + lus > MAX) { + lus += fread(buffer + lus, 1, MAX - lus, fic); + fprintf(stderr, + "Warning >> ID3 header is huge (%d bytes) ! trying anyway : %s\n", + size, file); + } else + lus += fread(buffer + lus, 1, size, fic); + if(size > lus) + size = lus; + c += 4; + if(version == 2) + while(c < buffer + size) { + int size = (*(c + 3) << 16) + (*(c + 4) << 8) + (*(c + 5)); + if(*c == 0) + break; + if(strncmp(c, "TT2", 3) == 0) { + strncpy(title, c + 7, size - 1); + title[size - 1] = '\0'; + } + if(strncmp(c, "TP1", 3) == 0) { + strncpy(artist, c + 7, size - 1); + artist[size - 1] = '\0'; + } + if(strncmp(c, "TCO", 3) == 0) { + /* strncpy(genrebuf,c+7,size-1); */ + /* genrebuf[size-1]='\0'; */ + /* genre=atoi(&genrebuf[1]); */ + genre = atoi(c + 8); + } + c += size + 6; + } + if(version == 3 || version == 4) + while(c < buffer + size) { + int size = + (*(c + 4) << 24) + (*(c + 5) << 16) + (*(c + 6) << 8) + + (*(c + 7)); + if(*c == 0) + break; + if(strncmp(c, "TIT2", 4) == 0) { + strncpy(title, c + 11, size - 1); + title[size - 1] = '\0'; + } + if(strncmp(c, "TPE1", 4) == 0) { + strncpy(artist, c + 11, size - 1); + artist[size - 1] = '\0'; + } + if(strncmp(c, "TCON", 4) == 0) { + /* strncpy(genrebuf,c+11,size-1); */ + /* genrebuf[size-1]='\0'; */ + /* genre=atoi(&genrebuf[1]); */ + genre = atoi(c + 12); + } + c += size + 10; + } + } + + while(c < buffer + lus - 10) { + if(*c == 0xFF && (*(c + 1) & 0xF0) == 0xF0) { + int version; + int lay; + int bitrate_index; + int bitrate; + version = 2 - (*(c + 1) >> 3 & 1); + lay = 4 - (*(c + 1) >> 1 & 3); + bitrate_index = *(c + 2) >> 4 & 0xF; + if(version >= 1 && version <= 2 && lay - 1 >= 0 && lay - 1 <= 2 + && bitrate_index >= 0 && bitrate_index <= 14) + bitrate = bitrates[version - 1][lay - 1][bitrate_index]; + else + bitrate = 0; + if(bitrate != 0) { + fseek(fic, 0, SEEK_END); + duration = (ftell(fic) + buffer - c) / 125 / bitrate; + } else + duration = 0; + break; } - if (strcasecmp(c,"ARTIST")==0) - { - strncpy(artist,c+7,size); - artist[size]='\0'; + c++; + } + + /* try ID3v1 */ + if(strlen(artist) == 0 && strlen(title) == 0) { + fseek(fic, -128, SEEK_END); + lus = fread(buffer, 1, 128, fic); + if(lus == 128 && buffer[0] == 'T' && buffer[1] == 'A' + && buffer[2] == 'G') { + strncpy(title, buffer + 3, 30); + title[30] = '\0'; + c = title + 29; + while(c > title && *c == ' ') + *(c--) = '\0'; + strncpy(artist, buffer + 33, 30); + artist[30] = '\0'; + c = artist + 29; + while(c > artist && *c == ' ') + *(c--) = '\0'; + /* strncpy(album,buffer+65,30); */ + /* strncpy(year,buffer+97,4); */ + /* strncpy(comment,buffer+101,30); */ + /* strncpy(genrebuf,buffer+127,1); genre[1]=0; */ + genre = buffer[127]; } - if (strcasecmp(c,"GENRE")==0) - { - for(i=0;i> parsing ogg : %s\n", file); + + /* read header */ + if((fic = fopen(file, "r")) == NULL) { + fprintf(stderr, "Warning >> can't open file : %s\n", file); + return; + } + lus = fread(buffer, 1, OGG_BASE, fic); + + /* try Ogg */ + if(buffer[0] != 'O' && buffer[1] != 'g' && buffer[2] != 'g') { + fprintf(stderr, "Warning >> not a Ogg header : %s\n", file); + return; + } + + c = buffer + 0x28; + sample_rate = + (*c) + (*(c + 1) << 8) + (*(c + 2) << 16) + (*(c + 3) << 24); + + while(c < buffer + lus - 10) { + int size; + if(strncasecmp(c, "TITLE=", 6) == 0) { + size = + *(c - 4) + (*(c - 3) << 8) + (*(c - 2) << 16) + + (*(c - 1) << 24); + strncpy(title, c + 6, size - 6); + title[size - 6] = '\0'; + c += size; + } + if(strncasecmp(c, "ARTIST=", 7) == 0) { + size = + *(c - 4) + (*(c - 3) << 8) + (*(c - 2) << 16) + + (*(c - 1) << 24); + strncpy(artist, c + 7, size - 7); + artist[size - 7] = '\0'; + c += size; + } + if(strncasecmp(c, "GENRE=", 6) == 0) { + static int i = 0; + size = + *(c - 4) + (*(c - 3) << 8) + (*(c - 2) << 16) + + (*(c - 1) << 24); + strncpy(genrebuf, c + 6, size - 6); + genrebuf[size - 6] = '\0'; + c += size; + for(i = 0; i < ID3_NR_OF_V1_GENRES; i++) { + if(strcasecmp(ID3_v1_genre_description[i], genrebuf) == 0) { + genre = i; + break; + } + if(i == ID3_NR_OF_V1_GENRES) + genre = 0; + } + } + c++; + } + + fseek(fic, -OGG_BASE, SEEK_END); + lus = fread(buffer, 1, OGG_BASE, fic); + c = buffer + lus - 1; + while(strncmp(c, "OggS", 4) != 0 && c > buffer) + c--; + if(c != buffer) { + c += 6; + samples = + (*c) + (*(c + 1) << 8) + (*(c + 2) << 16) + (*(c + 3) << 24); + duration = samples / sample_rate; + } + + fclose(fic); +} + + +void parse_mpc(unsigned char *file) +{ + FILE *fic; + unsigned char *c; + int lus; + int sample_rates[4] = { 44100, 48000, 37800, 32000 }; + int frame_count; + int size, items; + int i; + + if(debug) + fprintf(stderr, "Debug >> parsing mpc : %s\n", file); + + /* read header */ + if((fic = fopen(file, "r")) == NULL) { + fprintf(stderr, "Warning >> can't open file : %s\n", file); + return; + } + lus = fread(buffer, 1, 12, fic); + + /* try Musepack */ + if(buffer[0] != 'M' && buffer[1] != 'P' && buffer[2] != '+') { + fprintf(stderr, "Warning >> not a Musepack header : %s\n", file); + return; + } + + /* only version 7 */ + if(buffer[3] != 7) { + fprintf(stderr, "Warning >> only Musepack SV7 supported : %s\n", + file); + return; + } + + /* duration */ + c = buffer + 4; + frame_count = + (*c) + (*(c + 1) << 8) + (*(c + 2) << 16) + (*(c + 3) << 24); + c += 5; + duration = frame_count * 1152 / sample_rates[*c & 3]; + + /* try APETAGEX footer */ + fseek(fic, -32, SEEK_END); + lus = fread(buffer, 1, 32, fic); + if(lus == 32 && strncmp(buffer, "APETAGEX", 8) == 0) { + c = buffer + 12; + size = + (*c) + (*(c + 1) << 8) + (*(c + 2) << 16) + (*(c + 3) << 24); + size += 32; + c += 4; + items = + (*c) + (*(c + 1) << 8) + (*(c + 2) << 16) + (*(c + 3) << 24); + fseek(fic, -size, SEEK_END); + lus = fread(buffer, 1, size, fic); + if(lus == size && strncmp(buffer, "APETAGEX", 8) == 0) { + c = buffer + 32; + while(items--) { + size = + (*c) + (*(c + 1) << 8) + (*(c + 2) << 16) + + (*(c + 3) << 24); + c += 8; + if(strcasecmp(c, "TITLE") == 0) { + strncpy(title, c + 6, size); + title[size] = '\0'; + } + if(strcasecmp(c, "ARTIST") == 0) { + strncpy(artist, c + 7, size); + artist[size] = '\0'; + } + if(strcasecmp(c, "GENRE") == 0) { + for(i = 0; i < ID3_NR_OF_V1_GENRES; i++) { + strncpy(genrebuf, c + 6, size); + genrebuf[size] = '\0'; + if(strcasecmp + (ID3_v1_genre_description[i], genrebuf) == 0) { + genre = i; + break; + } + if(i == ID3_NR_OF_V1_GENRES) + genre = 0; + } + } + c += strlen(c) + 1 + size; } - if (i==ID3_NR_OF_V1_GENRES) genre=0; - } } - c+=strlen(c)+1+size; - } } - } - fclose(fic); + fclose(fic); } #define FSN 32 @@ -518,268 +813,325 @@ void parse_mpc(unsigned char *file) #define regbit_qry(x,y) ( x[( (y) / sizeof(INOTYP) )] & 1<<( (y) % sizeof(INOTYP) ) ) #define regbit_set(x,y) ( x[( (y) / sizeof(INOTYP) )] |= 1<<( (y) % sizeof(INOTYP) ) ) -int hlink_check(struct stat*info) +int hlink_check(struct stat *info) { - /* - * for speed this subroutine should only be called - * - if the file has more than one hardlink - * - if the file is a resolved softlink - */ - /* the persistent variables */ - static INOTYP *list[FSN]; - static dev_t name[FSN]; - /* some temporary variables */ - int fsn, is_registered=0; - - /* assertions - in case parameters are lowered for less memory usage */ - assert(fsnst_ino)/sizeof(INOTYP)st_dev)) && (name[fsn]!=0) ; fsn++); - - /* if file system is not registered yet, do it and leave */ - if( name[fsn] == 0 ) - { - name[fsn] = (info->st_dev); - /* provide space for the bitmap that maps the inodes of this file system */ - list[fsn] = (INOTYP*)calloc(MAXINO,sizeof(INOTYP)); - /* no comparison is needed in empty lists ... return */ - if(debug) fprintf(stderr, "Debug >> Linked >> Init List %04x @mem %04lx\n", (int)name[fsn], (long)&list[fsn] ); - } else - { - /* this looks more complicated than it really is */ - /* the idea is very simple: - * provide a bitmap that maps all inodes of a file system - * to mark all files that have already been visited. - * If it is already visited, do not add it to the playlist - */ /* - * The difficulty is as follows: - * struct inode_bitmap { char registered:1; } bitmap[1<st_ino) ) ) is_registered=1; - else regbit_set( list[fsn], (info->st_ino) ); - /* - * the debug expression is more complicated then the working stuff - */ - if(debug) - fprintf(stderr, "Debug >> Linked >> DEV %04x INO %06x => " - "list[%02x][%04x] = %04x & %04x --> %s registered\n", - (int)info->st_dev, (int)info->st_ino, fsn, (int)((info->st_ino)/sizeof(INOTYP)), - (int)list[fsn][(info->st_ino)/sizeof(INOTYP)], - 1<<((info->st_ino)%sizeof(INOTYP)), is_registered?"Already":"Not" ); - } - return is_registered; + /* the persistent variables */ + static INOTYP *list[FSN]; + static dev_t name[FSN]; + /* some temporary variables */ + int fsn, is_registered = 0; + + /* assertions - in case parameters are lowered for less memory usage */ + assert(fsn < FSN); + assert((info->st_ino) / sizeof(INOTYP) < MAXINO); + + /* search which internal registration number is used for this filesystem */ + for(fsn = 0; (name[fsn] != (info->st_dev)) && (name[fsn] != 0); fsn++); + + /* if file system is not registered yet, do it and leave */ + if(name[fsn] == 0) { + name[fsn] = (info->st_dev); + /* provide space for the bitmap that maps the inodes of this file system */ + list[fsn] = (INOTYP *) calloc(MAXINO, sizeof(INOTYP)); + /* no comparison is needed in empty lists ... return */ + if(debug) + fprintf(stderr, + "Debug >> Linked >> Init List %04x @mem %04lx\n", + (int)name[fsn], (long)&list[fsn]); + } else { + /* this looks more complicated than it really is */ + /* the idea is very simple: + * provide a bitmap that maps all inodes of a file system + * to mark all files that have already been visited. + * If it is already visited, do not add it to the playlist + */ + /* + * The difficulty is as follows: + * struct inode_bitmap { char registered:1; } bitmap[1<st_ino))) + is_registered = 1; + else + regbit_set(list[fsn], (info->st_ino)); + /* + * the debug expression is more complicated then the working stuff + */ + if(debug) + fprintf(stderr, "Debug >> Linked >> DEV %04x INO %06x => " + "list[%02x][%04x] = %04x & %04x --> %s registered\n", + (int)info->st_dev, (int)info->st_ino, fsn, + (int)((info->st_ino) / sizeof(INOTYP)), + (int)list[fsn][(info->st_ino) / sizeof(INOTYP)], + 1 << ((info->st_ino) % sizeof(INOTYP)), + is_registered ? "Already" : "Not"); + } + return is_registered; } void parse_file(unsigned char *newpath) { - unsigned char *c; - unsigned char ext[5]; - int j; - - void print_faketitle() - { - c=newpath+strlen(newpath); - while (c>newpath && *c!='/') c--; - while (c%d%s%s",counter,artist,title); - if (duration==-1) printf("?"); else printf("%d:%s%d",duration/60,duration%60<10?"0":"",duration%60); - printf("%s",eol); + case 2: + printf("%d%s%s", counter, + artist, title); + if(duration == -1) + printf("?%s", eol); + else + printf("%d:%s%d%s", duration / 60, + duration % 60 < 10 ? "0" : "", duration % 60, eol); break; - case 3: - if (duration!=-1) - { time_t zeit; - time(&zeit); - char timebuffer[256]; - strftime(timebuffer,255, "%a %d %b %Y %T %Z", localtime(&zeit) ); /* ctime() had a trailing CR */ - printf("\t%s",eol); - if (strlen(artist)==0 && strlen(title)==0) - { - /* find a better solution for this */ - printf("\t\t%s%s\t\t%s%s",newpath,eol, newpath,eol ); - } - else printf("\t\t%s%s\t\t%s%s",artist,eol, title,eol ); - /* you might want to add more into description --> look for a smart, not a fast program */ - printf("\t\t%s
%s
Direct Link to Audiofile
]]>
%s",eol); -#if 1 - printf("\t\t%s%s",reflink(title),eol); -#endif - printf("\t\t%s%s",timebuffer,eol); - printf("\t\t%s\t\t",duration, eol); - print_path(); - printf("%s",eol ); - printf("\t\t%d:%d:%d%s",duration/3600,(duration/60)%60,duration%60,eol); - printf("\t\t%s%s", artist, eol); - printf("\t
%s",eol ); + case 3: + if(duration != -1) { + struct stat infos; + char timebuffer[256]; + + if(stat(newpath, &infos) != 0) { + fprintf(stderr, "Warning >> can't stat entry : %s\n", + newpath); + return; + } + strftime(timebuffer, 255, "%a %d %b %Y %T %z", localtime(&(infos.st_mtime))); /* ctime() had a trailing CR */ + printf("\t%s", eol); + printf("\t\t"); + myputstr(artist); + printf("%s\t\t", eol); + myputstr(title); + printf("%s", eol); + + if(referal == NULL) { + noreferal(newpath, artist, title); + } else + reference(newpath); + printf("\t\t%s%s\t\t%s\t\t", + (int)infos.st_size, magic[encoding], eol); + print_pathtail(newpath); + printf("%s", eol); + if(duration > 3599) + printf + ("\t\t%d:%02d:%02d%s", + duration / 3600, (duration / 60) % 60, + duration % 60, eol); + else + printf + ("\t\t%d:%02d%s", + duration / 60, duration % 60, eol); + if(strlen(artist) != 0) { + printf("\t\t"); + myputstr(artist); + printf("%s", eol); + } + printf("\t%s", eol); } break; } - } + } } void parse_directory(unsigned char *path) { - int i,n; - struct dirent **namelist; - unsigned char newpath[PATH_MAX]; - struct stat infos; - - if (debug) - fprintf(stderr,"Debug >> parsing directory : %s\n",path); - if (stat(path,&infos)!=0) - { - fprintf(stderr,"Warning >> can't stat entry : %s\n",path); - return; - } - /* check if it is a filename */ - if (S_ISREG(infos.st_mode) || S_ISLNK(infos.st_mode)) - { - parse_file(path); - return; - } - /* must be a directory - or something unusable like pipe, socket, etc */ - if ((n=scandir(path,&namelist,0,alphasort))<0) - { - fprintf(stderr,"Warning >> can't open directory : %s\n",path); - return; - } - for (i=0;id_name); - - if (stat(newpath,&infos)!=0) - { - fprintf(stderr,"Warning >> can't stat entry : %s\n",newpath); - continue; - } - if (recursive && S_ISDIR(infos.st_mode) - && strcmp(namelist[i]->d_name,".")!=0 - && strcmp(namelist[i]->d_name,"..")!=0) parse_directory(newpath); - /* hlink_check() might be applied more selective ... avoidhlink is only a simple prereq */ - if (S_ISREG(infos.st_mode) && ! ( avoidhlinked && hlink_check(&infos) ) ) - { - parse_file(newpath); - } - free(namelist[i]); - } - free(namelist); + int i, n; + struct dirent **namelist; + unsigned char newpath[PATH_MAX]; + struct stat infos; + + if(debug) + fprintf(stderr, "Debug >> parsing directory : %s\n", path); + if(stat(path, &infos) != 0) { + fprintf(stderr, "Warning >> can't stat entry : %s\n", path); + return; + } + /* check if it is a filename */ + if(S_ISREG(infos.st_mode) || S_ISLNK(infos.st_mode)) { + parse_file(path); + return; + } + /* must be a directory - or something unusable like pipe, socket, etc */ + if((n = scandir(path, &namelist, 0, alphasort)) < 0) { + fprintf(stderr, "Warning >> can't open directory : %s\n", path); + return; + } + for(i = 0; i < n; i++) { + sprintf(newpath, "%s/%s", path, namelist[i]->d_name); + + if(stat(newpath, &infos) != 0) { + fprintf(stderr, "Warning >> can't stat entry : %s\n", newpath); + continue; + } + if(recursive && S_ISDIR(infos.st_mode) + && strcmp(namelist[i]->d_name, ".") != 0 + && strcmp(namelist[i]->d_name, "..") != 0) + parse_directory(newpath); + /* hlink_check() might be applied more selective ... avoidhlink is only a simple prereq */ + if(S_ISREG(infos.st_mode) + && !(avoidhlinked && hlink_check(&infos))) { + parse_file(newpath); + } + free(namelist[i]); + } + free(namelist); } -int main(int argc,char **argv) +int main(int argc, char **argv) { - parse_options(argc,argv); - if (optind==argc) usage(); - switch (format) - { + winorunix = one2one; + basemap = one2one; + parse_options(argc, argv); + if(optind == argc) + usage(); + switch (format) { case 0: - printf("#EXTM3U%s",eol); - break; + printf("#EXTM3U%s", eol); + break; case 1: - printf("[playlist]%s",eol); - break; + printf("[playlist]%s", eol); + break; case 2: - printf("%s%s%s%s%sPlaylist generated by FAPG " VERSION "%s%s%s%s%s%s%s

Playlist

%s%s%s%s",eol,eol,eol,eol,eol,eol,eol,eol,eol,eol,eol,eol,eol,eol,eol,eol,eol,eol,eol,eol,eol,eol,eol,eol,eol,eol,eol,eol,eol,eol,eol,eol,eol,eol,eol,eol,eol,eol,eol,eol,eol,eol,eol,eol,eol,eol,eol,eol,eol,eol,eol,eol,eol,eol,eol,eol,eol,eol,eol,eol,eol,eol,eol); - break; + printf + ("%s%s%s%s%sPlaylist generated by FAPG " + VERSION + "%s%s%s%s%s%s%s

Playlist

%s%s
EntryArtistTitleLength
%s%s", + eol, eol, eol, eol, eol, eol, eol, eol, eol, eol, eol, eol, + eol, eol, eol, eol, eol, eol, eol, eol, eol, eol, eol, eol, + eol, eol, eol, eol, eol, eol, eol, eol, eol, eol, eol, eol, + eol, eol, eol, eol, eol, eol, eol, eol, eol, eol, eol, eol, + eol, eol, eol, eol, eol, eol, eol, eol, eol, eol, eol, eol, + eol, eol, eol); + break; case 3: - { time_t zeit; - time(&zeit); - char timebuffer[256]; - strftime(timebuffer,255, "%a %d %b %Y %T %Z", localtime(&zeit) ); - printf("%s%s%s %s\t%s - %s%s\tDirectory Tree %s%s\t%s%s\t%s\t%s%s\tFAPG " VERSION "%s\t%s\t\t%s/podcast.jpg%s\t\tServer Logo%s\t\t%s%s\t\tFeed provided by FAPG. Click to visit.%s\t%s\t%s\t\tAdmin %s%s\t\tpodcast@%s%s\t%s\tVarious%s\tDirectory Tree %s%s\t%s%s\tunknown%s\t%s%s\tNo%s\t1800%s",eol,eol,eol,eol,hostname,dir,eol,prefix,eol,base,eol,prefix,eol,timebuffer,eol,eol,eol,base,eol,eol,base,eol,eol,eol,eol,base,eol,hostname,eol,eol,eol,dir,eol,getenv("LOGNAME"),eol,eol,getenv("LANG"),eol,eol,eol); - } - break; - } - for (;optind%s%s%s %s\t%s - %s - %s%s\tDirectory Tree %s%s\t%s%s\t%s\t%s%s\tFAPG " + VERSION + "%s\t%s\t\t%s/podcast.jpg%s\t\tServer Logo%s\t\t%s%s\t\tFeed provided by FAPG. Click to visit.%s\t%s\t%s\t\tAdmin %s%s\t\tpodcast@%s%s\t%s\tVarious%s\tDirectory Tree %s%s\t%s%s\tunknown%s\t%s%s\tNo%s\t1800%s", + eol, eol, eol, eol, hostname, dir, argv[optind], eol, + prefix, eol, base, eol, prefix, eol, timebuffer, eol, eol, + eol, base, eol, eol, base, eol, eol, eol, eol, base, eol, + hostname, eol, eol, eol, dir, eol, getenv("LOGNAME"), eol, + eol, getenv("LANG"), eol, eol, eol); + unix2dos[38] = 43; // I never made an rss feed work with '&' in it + basemap = noand; + } + break; + } + for(; optind < argc; optind++) { + parse_directory(argv[optind]); + } + switch (format) { case 1: - printf("NumberOfEntries=%d%sVersion=2%s",counter,eol,eol); - break; + printf("NumberOfEntries=%d%sVersion=2%s", counter, eol, eol); + break; case 2: - printf("
EntryArtistTitleLength
%s%s

Playlist generated by FAPG " VERSION "

%s%s%s%s",eol,eol,eol,eol,eol,eol); - break; + printf + ("%s%s

Playlist generated by FAPG " + VERSION "

%s%s%s%s", eol, eol, eol, eol, + eol, eol); + break; case 3: - printf(" %s%s",eol,eol); - break; - } - if (genrelist) free(genrelist); - exit(0); + printf(" %s%s", eol, eol); + break; + } + if(genrelist) + free(genrelist); + exit(0); }