X-Git-Url: http://royale.zerezo.com/git/?p=FAPG;a=blobdiff_plain;f=fapg.c;h=e627ea5294aa648c02264871c77043ce0ee1b07e;hp=eaa8ac3c0c32bc74eff7a6f864d419b4e52be73f;hb=421f874ec03fa08a659b5b4314411f24f1d6460b;hpb=5fcf230b83f0541f31b9ccc18ac34391504246b6 diff --git a/fapg.c b/fapg.c old mode 100755 new mode 100644 index eaa8ac3..e627ea5 --- a/fapg.c +++ b/fapg.c @@ -1,367 +1,785 @@ -/* - * FAPG 0.0 released under GPL - * http://royale.zerezo.com/fapg/ - */ - -#include -#include -#include -#include -#include -#include -#include - -#define MAX 10240 - -int debug=0; -int format=0; /* 0 = m3u ; 1 = pls ; 2 = html */ -unsigned char *prefix=""; -int recursive=0; -int separator='/'; -int skip=0; -int windows=0; -unsigned char buffer[MAX]; - -int counter=0; - -unsigned char artist[1024]; -unsigned char title[1024]; -int time; - -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}; - -void usage() -{ - fprintf(stderr,"Usage >> fapg [-backslash] [-debug] [-format=m3u|pls|html] [-output=/path/to/file.m3u] [-prefix=/the/prefix] [-recursive] [-windows] /path/to/mp3/dir1 [/path/to/mp3/dir2 ...]\n"); - exit(1); -} - -void parse_options(int argc,char **argv) -{ - static struct option long_options[]= - { - {"backslash",no_argument,&separator,'\\'}, - {"debug",no_argument,&debug,1}, - {"format",required_argument,0,'f'}, - {"output",required_argument,0,'o'}, - {"prefix",required_argument,0,'p'}, - {"recursive",no_argument,&recursive,1}, - {"windows",no_argument,&windows,1} - }; - int c; - int option_index=0; - while ((c=getopt_long_only(argc,argv,"",long_options,&option_index))!=-1) - { - switch(c) - { - case 0: - break; - case 'f': - if (strcmp(optarg,"m3u")==0) format=0; else - if (strcmp(optarg,"pls")==0) format=1; else - if (strcmp(optarg,"html")==0) format=2; else - usage(); - 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); - break; - default: - usage(); - } - } -} - -void parse_mp3(unsigned char *file) -{ - 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; - - 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,MAX,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<<24)+(*(c+1)<<16)+(*(c+2)<<8)+(*(c+3)); - 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); - time=(ftell(fic)+buffer-c)/125/bitrate; - } - else - time=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'; - } - } - - fclose(fic); -} - -void parse_ogg(unsigned char *file) -{ - 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,MAX,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 (cbuffer) c--; - if (c!=buffer) - { - c+=6; - samples=(*c)+(*(c+1)<<8)+(*(c+2)<<16)+(*(c+3)<<24); - time=samples/sample_rate; - } - - fclose(fic); -} - -void parse_directory(unsigned char *path) -{ - DIR *dirp; - struct dirent *dp; - unsigned char newpath[PATH_MAX]; - unsigned char *c; - - void print_faketitle() - { - c=newpath+strlen(newpath); - while (c>newpath && *c!='/') c--; - while (c> parsing directory : %s\n",path); - if ((dirp=opendir(path))==NULL) { fprintf(stderr,"Warning >> can't open directory : %s\n",path); return; } - while ((dp=readdir(dirp))!=NULL) - { - sprintf(newpath,"%s/%s",path,dp->d_name); - if (recursive && dp->d_type & DT_DIR && strcmp(dp->d_name,".")!=0 && strcmp(dp->d_name,"..")!=0) - { - parse_directory(newpath); - } - if (dp->d_type & DT_REG) - { - unsigned char ext[5]; - int i; - for (i=0;i<5;i++) ext[i]=tolower(dp->d_name[strlen(dp->d_name)-4+i]); - artist[0]='\0'; - title[0]='\0'; - time=-2; - if (strcmp(".mp3",ext)==0) { time=-1; parse_mp3(newpath); } - if (strcmp(".ogg",ext)==0) { time=-1; parse_ogg(newpath); } - if (strcmp(".wav",ext)==0) { time=-1; /* parse_wav(newpath); */ } - - if (time!=-2) /* is it an audio file ? */ - { - counter++; - switch (format) - { - case 0: - if (time!=-1) - { - printf("#EXTINF:%d,",time); - if (strlen(artist)==0 && strlen(title)==0) print_faketitle(); - else printf("%s - %s",artist,title); - putchar('\n'); - } - print_path(); - putchar('\n'); - break; - case 1: - printf("File%d=",counter); - print_path(); - putchar('\n'); - printf("Title%d=",counter); - if (strlen(artist)==0 && strlen(title)==0) print_faketitle(); - else printf("%s - %s",artist,title); - putchar('\n'); - if (time!=-1) printf("Length%d=%d\n",counter,time); - break; - case 2: - printf("%d%s%s",counter,artist,title); - if (time==-1) printf("?"); else printf("%d",time); - printf("\n"); - break; - } - } - } - } - closedir(dirp); -} - -int main(int argc,char **argv) -{ - parse_options(argc,argv); - if (optind==argc) usage(); - switch (format) - { - case 0: - printf("#EXTM3U\n"); - break; - case 1: - printf("[playlist]\n"); - break; - case 2: - printf("\n\n\n\n\nPlaylist generated by FAPG 0.0\n\n\n\n\n\n\n

Playlist

\n\n\n\n"); - break; - } - for (;optind\n\n

Playlist generated by FAPG 0.0

\n\n\n\n"); - break; - } - exit(0); -} +/* + * FAPG + */ +#define VERSION "0.34" +/* + * FAPG means Fast Audio Playlist Generator. + * It is a tool to generate list of audio files (Wav, MP3, Ogg, etc) + * in various formats (M3U, PLS, HTML, etc). + * It is very usefull if you have a large amount of audio files + * and you want to quickly and frequently build a playlist. + * + * Copyright (C) 2003-2004 Antoine Jacquet + * http://royale.zerezo.com/fapg/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "genres.h" + +#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"; +unsigned char buffer[MAX]; + +int counter=0; + +unsigned char artist[1024]; +unsigned char title[1024]; +unsigned char genrebuf[1024]; +unsigned char genre=0; +int duration; + +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}; + +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); +} + +const char*reflink(const char*title) +{ + 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(); + } + } + /* 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 parse_mp3(unsigned char *file) +{ + 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>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); +} + +void parse_ogg(unsigned char *file) +{ + 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); + return; + } + + c=buffer+0x28; + sample_rate=(*c)+(*(c+1)<<8)+(*(c+2)<<16)+(*(c+3)<<24); + + while (cbuffer) 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;ist_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; +} + + +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
%s",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 ); + } + 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 main(int argc,char **argv) +{ + parse_options(argc,argv); + if (optind==argc) usage(); + switch (format) + { + case 0: + printf("#EXTM3U%s",eol); + break; + case 1: + 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
EntryArtistTitleLength
%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%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

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); +}
EntryArtistTitleLength