Exemple #1
0
static void mad_close(input_object *obj)
{
	struct mad_local_data *data;
	if (!obj)
		return;
	data = (struct mad_local_data *)obj->local_data;

	if (data) {
		if (data->mad_fd)
			reader_close(data->mad_fd);
		if (data->mad_init) {
			mad_synth_finish (&data->synth);
			mad_frame_finish (&data->frame);
			mad_stream_finish(&data->stream);
			data->mad_init = 0;
		}
		if (data->frames) {
			free(data->frames);
		}				
		free(obj->local_data);
		obj->local_data = NULL;
	}				
}
Exemple #2
0
/*-------------------------------------------------------------------------*/
static int
output_tree (void)

/* Output the collected dependencies in tree form into the Depfile.
 * Return 0 on success, RETURN_WARN on a mild error, RETURN_ERROR on a
 * severe error.
 */

{
  int         rc;
  char      * pFile;    /* Name of file to create */
  Node      * pNode;

  pFile = sDepfile;
  assert(pFile);

  rc = RETURN_OK;
  do
  {
    if (!pStack)
    {
      /* Initialise stack */
      pStack = malloc(sizeof(*pStack));
      if (!pStack)
      {
        printf("%s: Out of memory\n", aPgmName);
        rc = RETURN_ERROR;
        break;
      }
      memset(pStack, 0, sizeof(*pStack));
    }

    /* Open files */
    if (reader_openrw(NULL, pFile))
    {
      perror(aPgmName);
      printf("%s: Can't write '%s'\n", aPgmName, pFile);
      rc = RETURN_ERROR;
      break;
    }

    if (bVerbose)
    {
      printf(" creating '%s'\r", pFile);
      fflush(stdout);
    }

    /* Walk and output the dependencies and users of the
     * skeleton sources.
     */
    nodes_initwalk();
    while (rc != RETURN_ERROR && NULL != (pNode = nodes_inorder()) )
    {
      if (!(pNode->flags & (NODE_IGNORE)) 
       && (pNode->flags & (NODE_SOURCE|NODE_AVOID)) == NODE_SOURCE
       && (!IS_SELECT_MODE || (pNode->flags & (NODE_SELECT|NODE_ISELECT)))
       && !((pNode->flags & NODE_NOTFND) && bIgnoreMiss)
         )
      {
        rc = output_node_tree(pNode, FALSE, IS_SELECT_MODE);
        if (!rc)
          rc = output_node_tree(pNode, TRUE, IS_SELECT_MODE);
        if (!rc && reader_writen("\n", 1))
          rc = RETURN_ERROR;
      }
    }

    /* Walk and output the dependencies and users of the
     * non-skeleton sources
     */
    nodes_initwalk();
    while (rc != RETURN_ERROR && NULL != (pNode = nodes_inorder()) )
    {
      if (!(pNode->flags & (NODE_IGNORE|NODE_SOURCE))
       && (!IS_SELECT_MODE || (pNode->flags & (NODE_SELECT|NODE_ISELECT)))
       && !((pNode->flags & NODE_NOTFND) && bIgnoreMiss)
         )
      {
        rc = output_node_tree(pNode, FALSE, IS_SELECT_MODE);
        if (!rc)
          rc = output_node_tree(pNode, TRUE, IS_SELECT_MODE);
        if (!rc && reader_writen("\n", 1))
          rc = RETURN_ERROR;
      }
    }

    if (rc == RETURN_ERROR)
    {
      int i = errno;
      if (bVerbose)
        printf("%-78s\r", "");
      errno = i;
      perror(aPgmName);
      printf("%s: Error writing '%s'.\n", aPgmName, pFile);
      rc = RETURN_ERROR;
      break;
    }

    if (reader_writeflush())
    {
      int i = errno;
      if (bVerbose)
        printf("%-78s\r", "");
      errno = i;
      perror(aPgmName);
      printf("%s: Error writing '%s'.\n", aPgmName, sDepfile);
      rc = RETURN_ERROR;
      break;
    }
    /* Finish up */
    if (bVerbose)
      printf("%-78s\r", "");

    if (reader_close())
    {
      perror(aPgmName);
      printf("%s: Error writing '%s'.\n", aPgmName, pFile);
      rc = RETURN_ERROR;
      break;
    }

  } while(0);

  while (pStack)
  {
    StackNode * pTop;

    pTop = pStack;
    pStack = pStack->pNext;
    free(pTop);
  }

  /* Error cleanup */
  if (rc == RETURN_ERROR)
  {
    reader_close();
    remove(pFile);
  }

  if (bVerbose && rc != RETURN_ERROR)
    printf("%-78s\r", "");

  return rc;
}
Exemple #3
0
/*-------------------------------------------------------------------------*/
static int
readfiles (void)

/* Read and analyse all files.
 * If a file can't be read, print a message.
 * Return 0 if all went well, RETURN_WARN if one of the files could not be
 * found, RETURN_ERROR if one of the files could not be read properly.
 */

{
    int           rc;       /* Return value */
    Node        * pNode;    /* Node of the file under examination */
    int           srcRead;  /* Number of source files read */
    const char  * pName;    /* Includefile name returned by reader */

    rc = 0;
    srcRead = 0;

    while (NULL != (pNode = nodes_todo()) )
    {
        int bSystem; /* TRUE if it's a <> include */

        if (pNode->flags & NODE_NOTFND)
            continue;

        if (!reader_open(pNode->pName))
        {
            rc = readerror(pNode, rc, FALSE);
            continue;
        } /* If (can't open pNode->pName) */

        if (bVerbose)
        {
            printf(" reading %-65s\r", pNode->pName); fflush(stdout);
        }

        while (NULL != (pName = reader_get(&bSystem)) )
        {
            int    index;    /* index into aIncl[] */
            Node * pChild;   /* Node of included file, NULL if not found */
            Node * pChFirst; /* First 'direct' child node */

            for (index = -1, pChild = NULL, pChFirst = NULL
                ; !pChild && index < iInclSize
                ; index++)
            {
                char aName[FILENAME_MAX+1];
                char * pCName;  /* aName[] cleaned up */
                char * pCBase;  /* Namepart in *pCName */

                /* Don't look for system includes in non-system directories. */
                if (index >= 0 && bSplitPath && bSystem && !aIncl[index].bSysPath)
                    continue;

                aName[FILENAME_MAX] = '\0';

                if (index < 0)
                {
                    /* Special case: look directly for the filename.
                     * If bSplitPath is given, or if the filename is absolute,
                     * use it unchanged. Else, use the path of the including
                     * file as anchor.
                     */

                    if (bSplitPath || '/' == *pName)
                        strcpy(aName, pName);
                    else
                    {
                        size_t oFilename;

                        oFilename = (unsigned)(pNode->pBase - pNode->pName);
                        strncpy(aName, pNode->pName, oFilename);
                        strcpy(aName+oFilename, pName);
                    }
                }
                else
                {
                    /* Standard case: build the pathname from the include
                     * pathname.
                     */

                    strcpy(aName, aIncl[index].pPath);
                    strcat(aName, pName);
                }

                /* Cleanup the filename and check if it is listed in
                 * the tree
                 */
                pCName = util_getpath(aName, &pCBase);
                if (!pCName)
                {
                    if (bVerbose)
                        printf("%-78s\r", "");
                    reader_close();
                    exit_nomem(" (readfiles: 1. util_getpath)");
                }

                pChild = nodes_findadd(pCName, TRUE);

                if (pChild->flags & NODE_NEW)
                {
                    /* New file: check if it exists and set up the
                     * node properly
                     */

                    struct stat aStat;

                    pChild->pName = pCName;
                    pChild->pBase = pCBase;

                    if (index >= 0)
                    {
                        pChild->pPath = util_getpath(pName, NULL);
                        pChild->iInclude = index;
                    }
                    else if (pNode->iInclude < 0 || pNode->flags & NODE_SOURCE)
                    {
                        pChild->pPath = util_getpath(pCName, NULL);
                        pChild->iInclude = -1;
                    }
                    else
                    {
                        strcpy(aName, pNode->pPath);
                        strcat(aName, pName);
                        pChild->pPath = util_getpath(aName, NULL);
                        pChild->iInclude = pNode->iInclude;
                    }
                    if (!pChild->pPath)
                    {
                        if (bVerbose)
                            printf("%-78s\r", "");
                        reader_close();
                        exit_nomem(" (readfiles: 2. util_getpath)");
                    }

                    pChild->flags = (short)(bSystem ? NODE_SYSTEM : 0);

                    /* It's ok to not find <>-includes - they just don't have
                     * to appear in the output then.
                     */
                    if (stat(pCName, &aStat))
                        pChild->flags |= NODE_NOTFND | (bSystem ? NODE_IGNORE : 0);
                }

                /* The pChFirst is needed if the include can't be found
                 * so we can keep track from where it is included.
                 */
                if (index < 0)
                    pChFirst = pChild;

                /* Test if the file for pChild exists.
                 */
                if (pChild->flags & NODE_NOTFND)
                {
                    /* Make sure that the file is listed in the warnings
                     * if appropriate.
                     */
                    if (index >= 0)
                        pChild->flags |= NODE_IGNORE;
                    else if ((pChild->flags & NODE_IGNORE) && !bSystem)
                        pChild->flags ^= NODE_IGNORE;
                    pChild = NULL;
                }
                
                /* For absolute pNames, only index -1 is tried */
                if ('/' == *pName)
                    break;
            } /* for (index = -1..iInclSize) */

            assert(pChFirst != NULL);

            if (pChild ? nodes_depend(pChild, pNode) 
                       : nodes_depend(pChFirst, pNode))
            {
                if (bVerbose)
                    printf("%-78s\r", "");
                reader_close();
                exit_nomem(" (readfiles: nodes_depend)");
            }
        } /* while(get pName from file */

        if (bVerbose)
            printf("%-78s\r", "");
        if (!reader_eof() || reader_close())
        {
            perror(aPgmName);
            printf("%s: Error reading '%s'\n", aPgmName, pNode->pName);
            rc = RETURN_ERROR;
        }
        else if (pNode->flags & NODE_SOURCE)
        {
            srcRead++;
        }
    } /* while (nodes_todo()) */

    if (!srcRead)
    {
        printf("%s: No source file read.\n", aPgmName);
        rc = RETURN_ERROR;
    }

    /* Walk tree and print all include files not found */
    nodes_initwalk();
    while (rc != RETURN_ERROR && NULL != (pNode = nodes_inorder()) )
    {
        if ((pNode->flags & (NODE_NOTFND|NODE_IGNORE)) == NODE_NOTFND)
        {
            if (pNode->pUsers)
                rc = readerror(pNode, rc, TRUE);
            else
                pNode->flags |= NODE_IGNORE;
        }
    }

    if (bVerbose)
        fflush(stdout);

    return rc;
}
Exemple #4
0
/*-------------------------------------------------------------------------*/
static int
output (int bAsMake)

/* Output the collected dependencies into the Makefile (bAsMake is TRUE)
 * resp. into the Depfile (bAsMake is FALSE).
 * Return 0 on success, RETURN_WARN on a mild error, RETURN_ERROR on a
 * severe error.
 */

{
  int       rc;
  char    * pBackup;  /* Name of the Makefilebackup */
  char    * pFile;    /* Name of file to create */
  Node    * pNode;

  pBackup = NULL;
  pFile = bAsMake ? sMake : sDepfile;

  assert(pFile);

  /* Rename old Makefile if necessary */
  if (bAsMake && bMakeExists)
  {
    pBackup = (char *)malloc(strlen(sMake)+5);
    strcpy(pBackup, sMake);
    strcat(pBackup, ".bak");
    remove(pBackup);
    if (rename(sMake, pBackup))
    {
      perror(aPgmName);
      printf("%s: Can't rename '%s' to '%s'.\n", aPgmName, sMake, pBackup);
      free(pBackup);
      return RETURN_ERROR;
    }
  }

  rc = RETURN_OK;
  do
  {
    char * pTagline;

    /* Open files */
    if (reader_openrw(pBackup, pFile))
    {
      perror(aPgmName);
      printf("%s: Can't write '%s'\n", aPgmName, pFile);
      rc = RETURN_ERROR;
      break;
    }

    if (bVerbose)
    {
      printf(" %s '%s'\r", (bMakeExists && bAsMake) ? "updating" : "creating", pFile);
      fflush(stdout);
    }

    /* Copy the Makefile up to the tagline */
    pTagline = IS_SELECT_MODE 
               ? "# --- DO NOT MODIFY THIS LINE -- SELECTED AUTO-DEPENDS FOLLOW ---\n"
               : "# --- DO NOT MODIFY THIS LINE -- AUTO-DEPENDS FOLLOW ---\n";
    if (bAsMake && reader_copymake(pTagline))
    {
      int i = errno;
      if (bVerbose)
        printf("%-78s\r", "");
      errno = i;
      perror(aPgmName);
      printf("%s: Error copying '%s' to '%s'.\n", aPgmName, pBackup, sMake);
      rc = RETURN_ERROR;
      break;
    }

    /* Walk and output the dependencies and users.
     * First all the files specified as root.
     */
    nodes_initwalk();
    while (rc != RETURN_ERROR && NULL != (pNode = nodes_inorder()) )
    {
      if ((pNode->flags & (NODE_SOURCE|NODE_AVOID|NODE_NOTFND)) == NODE_SOURCE)
        rc = output_node_flat(pNode, bAsMake, IS_SELECT_MODE);
    }  /* while (treewalk */

    /* Second (if wanted), all the files not specified as root. */
    if (RETURN_OK == rc && !bAsMake)
    {
      nodes_initwalk();
      while (rc != RETURN_ERROR && NULL != (pNode = nodes_inorder()) )
      {
        if ((pNode->flags & (NODE_SOURCE|NODE_AVOID)) != NODE_SOURCE
         && !(pNode->flags & NODE_NOTFND)
           )
          rc = output_node_flat(pNode, bAsMake, IS_SELECT_MODE);
      }  /* while (treewalk */
    }

    if (rc == RETURN_ERROR)
    {
      int i = errno;
      if (bVerbose)
        printf("%-78s\r", "");
      errno = i;
      perror(aPgmName);
      printf("%s: Error writing '%s'.\n", aPgmName, pFile);
      rc = RETURN_ERROR;
      break;
    }

    pTagline = IS_SELECT_MODE 
               ? "# --- DO NOT MODIFY THIS LINE -- SELECTED AUTO-DEPENDS PRECEDE ---\n"
               : "# --- DO NOT MODIFY THIS LINE -- AUTO-DEPENDS PRECEDE ---\n";
    if (bAsMake && reader_copymake2(pTagline))
    {
      int i = errno;
      if (bVerbose)
        printf("%-78s\r", "");
      errno = i;
      perror(aPgmName);
      printf("%s: Error copying '%s' to '%s'.\n", aPgmName, pBackup, sMake);
      rc = RETURN_ERROR;
      break;
    }
    else if (!bAsMake &&  reader_writeflush())
    {
      int i = errno;
      if (bVerbose)
        printf("%-78s\r", "");
      errno = i;
      perror(aPgmName);
      printf("%s: Error writing '%s'.\n", aPgmName, sDepfile);
      rc = RETURN_ERROR;
      break;
    }
    /* Finish up */
    if (bVerbose)
      printf("%-78s\r", "");

    if (reader_close())
    {
      perror(aPgmName);
      printf("%s: Error writing '%s'.\n", aPgmName, pFile);
      rc = RETURN_ERROR;
      break;
    }

    if (bAsMake && bMakeExists && chmod(sMake, aMakeStat.st_mode))
    {
      /* perror(aPgmName); */
      printf("%s: Warning: Can't update mode of '%s'.\n", aPgmName, sMake);
      rc = RETURN_WARN;
    }

    if (pBackup && remove(pBackup))
    {
      perror(aPgmName);
      printf("%s: Warning: Can't remove backup '%s'.\n", aPgmName, pBackup);
      rc = RETURN_WARN;
      break;
    }

  } while(0);

  /* Error cleanup */
  if (rc == RETURN_ERROR)
  {
    reader_close();
    remove(pFile);
    if (pBackup && rename(pBackup, sMake))
    {
      perror(aPgmName);
      printf("%s: Can't restore '%s' from backup '%s'\n", aPgmName, sMake, pBackup);
    }
  }

  if (bVerbose && rc != RETURN_ERROR)
    printf("%-78s\r", "");

  if (pBackup)
    free(pBackup);

  return rc;
}
Exemple #5
0
/* Trying to fill info from id3 tagged file */
static void parse_id3 (const char *path, stream_info *info)
{
	void *fd;
	unsigned char buf [2024];
	unsigned char g;

	/* Open stream */
	fd = reader_open (path, NULL, NULL);
	if (!fd)  return;

	/* --------------------------------------------------- */
	/* Trying to load id3v2 tags                           */
	if (reader_read (buf, 10, fd) != 10) {
		reader_close (fd);
		return;
	}

	if (memcmp(buf, "ID3", 3) == 0) {
		/* Parse id3v2 tags */

		/* Header */
		unsigned char major_version = buf [3];
		int f_unsynchronization = buf [5] & (1<<7);
		int f_extended_header = buf [5] & (1<<6);
		int f_experimental = buf [5] & (1<<5);
		int header_size = from_synchsafe4 (buf + 6);
		int name_size = buf [3] == 2 ? 3 : 4;
		int ext_size = 0;
		
		if (f_extended_header) {
//			alsaplayer_error ("FIXME: Extended header found in mp3."
//					"Please contact alsaplayer team.\n"
//					"Filename: %s", path);
	//		reader_close (fd);
	//		return;
			ext_size = 1;	//stupid but should do
		}

		if (f_unsynchronization) {
			alsaplayer_error ("FIXME: f_unsynchronization is set."
					"Please contact alsaplayer team.\n"
					"Filename: %s", path);
			reader_close (fd);
			return;
		}

		if (f_experimental) {
			alsaplayer_error ("FIXME: f_experimental is set."
					"Please contact alsaplayer team.\n"
					"Filename: %s", path);
			reader_close (fd);
			return;
		}

			if (ext_size) {
				char b[4];
				if (reader_read (b, 4, fd) != 4) {
						reader_close(fd);
						return;
				}
				if (major_version == 2)
					ext_size = from_synchsafe3 (b);
				else
					ext_size = from_synchsafe4 (b);
				
				if (reader_seek (fd, ext_size - 4, SEEK_CUR) < 0) {
					reader_close (fd);
					return;
				}
			
			}
			
		/* -- -- read frames -- -- */
		while (reader_tell (fd) <= header_size + 10) {
			unsigned int size;
			
			
			/* Get name of this frame */
			if (reader_read (buf, name_size, fd) != (unsigned)name_size) {
				reader_close (fd);
				return;
			}

			if (buf [0] == '\0')  break;
			if (buf [0] < 'A')  break;
			if (buf [0] > 'Z')  break;

			/* Get size */
			if (major_version == 2) {
				char sb [3];

				if (reader_read (sb, 3, fd) != 3) {
					reader_close (fd);
					return;
				}

				size = from_synchsafe3 (sb);
			} else {
				char sb [4];

				if (reader_read (sb, 4, fd) != 4) {
					reader_close (fd);
					return;
				}

				size = from_synchsafe4 (sb);
			}

			/* skip frame flags */
//			if (reader_seek (fd, 1, SEEK_CUR) == -1) {
//				reader_close (fd);
//				return;
//			}

			int start = 0;		
			// read them
			char b[2];
			if (reader_read (b, 2, fd) != 2) {
				reader_close (fd);
				return;
			} else {
			
				if (b[1] & (1 << 6)) {
//					printf ("Grouping added\n");
					start++;
				}
				if (b[1] & (1 << 3)) {
//					printf ("Compression added\n");
				}
				if (b[1] & (1 << 2)) {
//					printf ("Encryption added\n");
				}
				if (b[1] & (1 << 1)) {
//					printf ("Unsynch added\n");
				}
				if (b[1] & (1 << 0)) {
//					printf ("Length added\n");
					start+=4;
				}	
			}
				
				
				
				if (size>=1024) {
				/* I will not support such long tags...
				 * Only if someone ask for it...
				 * not now... */

				if (reader_seek (fd, size, SEEK_CUR) == -1) {
					reader_close (fd);
					return;
				}

				continue;
			}


			/* read info */
			if (reader_read (buf + name_size, size, fd) != size) {
				reader_close (fd);
				return;
			}

			/* !!! Ok. There we have frame name and data. */
			/* Lets use it. */
			if (name_size == 4) {
				if (memcmp (buf, "TIT2", 4)==0)
					fill_from_id3v2 (info->title, buf + name_size + start,
							sizeof (info->title), size - start);
				else if (memcmp (buf, "TPE1", 4)==0)
					fill_from_id3v2 (info->artist, buf + name_size + start,
							sizeof (info->artist), size - start);
				else if (memcmp (buf, "TALB", 4)==0)
					fill_from_id3v2 (info->album, buf + name_size + start,
							sizeof (info->album), size - start);
				else if (memcmp (buf, "TYER", 4)==0)
					fill_from_id3v2 (info->year, buf + name_size + start,
							sizeof (info->year), size - start);
				else if (memcmp (buf, "COMM", 4)==0)
					fill_from_id3v2 (info->comment, buf + name_size + start,
							sizeof (info->comment), size - start);
				else if (memcmp (buf, "TRCK", 4)==0)
					fill_from_id3v2 (info->track, buf + name_size + start,
							sizeof (info->track), size - start);
				else if (memcmp (buf, "TCON", 4)==0) {
					/* Genre */
					/* TODO: Optimize duplicated code */
					unsigned int gindex;

					if (sscanf (buf + name_size + start +1, "(%u)", &gindex)==1) {
						if (gindex==255)
							*info->genre = '\0';
						else if (sizeof (genres)/sizeof(char*) <= gindex)
							snprintf (info->genre, sizeof (info->genre), "(%u)", gindex);
						else
							snprintf (info->genre, sizeof (info->genre), "%s", genres[gindex]);
					} else
						fill_from_id3v2 (info->genre, buf + name_size + start,
								sizeof (info->genre), size - start);
				}
			} /* end of 'if name_size == 4' */

		} /* end of frames read */

		/* end parsing */
		reader_close (fd);
		return;
	} /* end of id3v2 parsing */

	/* --------------------------------------------------- */
	/* Trying to load id3v1 tags                           */
	if (reader_seek (fd, -128, SEEK_END) == -1) {
		reader_close (fd);
		return;
	}

	if (reader_read (buf, 128, fd) != 128) {
		reader_close (fd);
		return;
	}

	if (memcmp(buf, "TAG", 3) == 0) {
		/* ID3v1 frame found */

		/* title */
		strncpy (info->title, buf + 3, 30);
		rstrip (info->title);

		/* artist */
		strncpy (info->artist, buf + 33, 30);
		rstrip (info->artist);

		/* album */
		strncpy (info->album, buf + 63, 30);
		rstrip (info->album);

		/* year */
		strncpy (info->year, buf + 93, 4);
		rstrip (info->year);

		/* comment */
		strncpy (info->comment, buf + 97, 28);
		rstrip (info->comment);

		/* track number */
		if (buf [125] == '\0')
			snprintf (info->track, sizeof (info->track), "%u", buf [126]);

		/* genre */
		g = buf [127];
		if (g==255)
			*info->genre = '\0';
		else if (sizeof (genres)/sizeof(char*) <= g)
			snprintf (info->genre, sizeof (info->genre), "(%u)", g);
		else
			snprintf (info->genre, sizeof (info->genre), "%s", genres[g]);
	} /* end of id3v1 parsing */

	reader_close (fd);
}
Exemple #6
0
// Returns:
// E_PL_SUCCESS on success,
// E_PL_DUBIOUS if file doesn't appear to be in a known format,
// E_PL_BAD if file definitely isn't in a known format.
// If "force" is true, will try to load anyway instead of returning E_PL_DUBIOUS
enum plist_result
Playlist::Load(std::string const &uri, unsigned position, bool force)
{
	int pls = 0;

	// Check extension
	if(!force) {
		if(!is_playlist(uri.c_str()))
			return E_PL_DUBIOUS;
	}
	// Open Playlist
	reader_type *f = reader_open (uri.c_str(), NULL, NULL);
	if (!f)
	    return E_PL_BAD;

	// Base part of m3u uri, might need it later
	std::string base = uri;
	std::string::size_type i = base.rfind('/');
	if (i != std::string::npos)
	    base.erase(i);
	base += '/';

	// Read the file
	char path[READBUFSIZE + 1];
	memset(path, 0,READBUFSIZE);
	std::vector<std::string> newfiles;

	// Give up if too many failures (so we don't wait for almost ever if
	// someone tries clicking on an mp3 file...)
	// However, if its just that some of the files don't exist anymore,
	// don't give up.

	unsigned successes = 0;
	unsigned failures = 0;
	while(failures < MAXLOADFAILURES || failures < successes) {
		char *s, *p;
		if (!reader_readline (f, path, READBUFSIZE))
		    break;

		std::string newfile;

		if (*path == '#') {
		    // Comment... skip it for now
		    continue;
		} else if ((s=strstr(path, "File"))) {
			p = strstr(s, "=");
			if (p) {
				p++;
				// Make sure there are no trailing EOL's
				if ((s = strstr(p, "\r")))
					*s = '\0';
				if ((s = strstr(p, "\n")))
					*s = '\0';
				//alsaplayer_error("URI: %s", p);
				newfile = std::string(p);
			} else {
				continue;
			}
		} else if (pls && (strncasecmp(path, "Title", 5) == 0 ||
					strncasecmp(path, "Length", 6) == 0)) {
			/* Ignore title/length lines */
			continue;
		} else if (*path=='/') {
		     newfile = std::string(path); /* These 2 */
		} else if (reader_can_handle (path)) {
		    newfile = std::string(path); /* Should be one */
		} else if (*path == '\0') {
		    // No path
		    failures++;
		    continue;
		} else {
		    // This is probably realtive URI or not supported URI type.
		    newfile = base + std::string(path);
		}
		// Test result
		if (!reader_can_handle (newfile.c_str()))
		    continue;
		// Add this file
		newfiles.push_back(newfile);
		successes++;
	}

	// Entire file should be loaded
	/*
	if (!reader_eof(f)) {
	    reader_close (f);
	    return E_PL_BAD;
	}
	*/
	reader_close (f);

	// Do the insert
	Insert(newfiles, position);
	return E_PL_SUCCESS;
}
static int
flac_open (input_object * obj, const char * name)
{
    if (!obj)
	return 0;
    if (!name)
	return 0;

    reader_type * rdr = reader_open (name, NULL, NULL);
    if (!rdr)
    {
	alsaplayer_error ("flac_open: reader_open failed");
	return 0;
    }

    obj->flags = 0;
    Flac::FlacStream * f = 0;
    try
    {
	if (Flac::FlacStream::isFlacStream (name))
	{
	    if (reader_seekable (rdr))
	    {
		f = new Flac::FlacSeekableStream (name, rdr);
		obj->flags |= P_SEEK | P_PERFECTSEEK;
	    }
	    else
		f = new Flac::FlacStream (name, rdr);
	}
#ifdef HAVE_LIBOGGFLC
	else
	{
	    f = new Flac::OggFlacStream (name, rdr);
	}
#endif
    }
    catch (...)
    {
	alsaplayer_error ("flac_open: unable to allocate memory for plugin.");
	delete f;
	reader_close (rdr);
	return 0;
    }

    if (f && f->open ())
    {
	obj->block_size  = f->engine ()->apBlockSize ();

	// attach a song info tag

	if (Flac::FlacTag::hasTag (f->name ()))
	{
	    Flac::FlacTag * t = Flac::FlacTag::newTag (f->name ());
	    f->setTag (t);
	}

	if (strncasecmp (name, "http://", 7) == 0)
	    obj->flags |= P_STREAMBASED;
	else
	    obj->flags |= P_FILEBASED;
	obj->nr_channels  = f->engine ()->apChannels ();
	obj->flags       |= P_REENTRANT;
	obj->nr_blocks    = f->engine ()->apBlocks ();
	obj->nr_tracks    = 1;
	obj->ready        = 1;
	obj->local_data   = (void *) f;
	return 1;
    }
    else
    {
	alsaplayer_error ("flac_open: unable to open flac stream or "
			  "unsupported flac stream (%s)", name);
	delete f;
	obj->block_size  = 0;
	obj->nr_channels = 0;
	obj->flags       = 0;
	obj->nr_blocks   = 0;
	obj->nr_tracks   = 0;
	obj->ready       = 0;
	obj->local_data  = 0;
	return 0;
    }
}