示例#1
0
static int
optiserr(int argc, char* const *argv, int oint, const char* optstr,
	int optchr, int err)
{
	if (opterr)
	{
		qtss_fprintf(stderr, "Error in argument %d, char %d: ", oint, optchr + 1);
		switch (err)
		{
		case OPTERRCOLON:
			qtss_fprintf(stderr, ": in flags\n");
			break;
		case OPTERRNF:
			qtss_fprintf(stderr, "option not found %c\n", argv[oint][optchr]);
			break;
		case OPTERRARG:
			qtss_fprintf(stderr, "no argument for option %c\n", argv[oint][optchr]);
			break;
		default:
			qtss_fprintf(stderr, "unknown\n");
			break;
		}
	}
	optopt = argv[oint][optchr];
	return('?');
}
示例#2
0
OS_Error    OSFileSource::ReadFromPos(UInt64 inPosition, void* inBuffer, UInt32 inLength, UInt32* outRcvLen)
{   
#if TEST_TIME
    {   
        startTime = OS::Milliseconds();
        sReadCount++;
        if (outRcvLen)
            *outRcvLen = 0;
        qtss_printf("OSFileSource::Read sReadCount = %" _S32BITARG_ " totalbytes=%" _S32BITARG_ " readsize=%"   _U32BITARG_   "\n",sReadCount,sByteCount,inLength);
    }
#endif

    this->Seek(inPosition);
    OS_Error err =  this->ReadFromDisk(inBuffer,inLength,outRcvLen);
    
#if READ_LOG
        if (fFileLog)
        {   fFileLog = ::fopen(fFilePath,"a");
            if (fFileLog)
            {   qtss_fprintf(fFileLog, "read: %qu %"   _U32BITARG_   " %"   _U32BITARG_   "\n",inPosition, *outRcvLen, xTrackID);
                ::fclose(fFileLog);
            }
        }
            
#endif
#if TEST_TIME
    {
        durationTime += OS::Milliseconds() - startTime;
        sByteCount += *outRcvLen;
    }
#endif

    return err;
}
示例#3
0
void XMLParser::WriteToFile(char** fileHeader)
{
    char theBuffer[8192];
    ResizeableStringFormatter formatter(theBuffer, 8192);
    
    //
    // Write the file header
    for (UInt32 a = 0; fileHeader[a] != NULL; a++)
    {
        formatter.Put(fileHeader[a]);
        formatter.Put(kEOLString);
    }
    
        if (fRootTag)
                fRootTag->FormatData(&formatter, 0);

    //
    // New libC code. This seems to work better on Win32
    formatter.PutTerminator();
    FILE* theFile = ::fopen(fFilePath, "w");
    if (theFile == NULL)
        return;
        
    qtss_fprintf(theFile, "%s", formatter.GetBufPtr());
    ::fclose(theFile);
    
#if __MacOSX__
    (void) ::chown(fFilePath,76,80);//owner qtss, group admin
#endif

#ifndef __Win32__
    ::chmod(fFilePath, S_IRUSR | S_IWUSR | S_IRGRP );
#endif
}
/*
 * AddPassword: Prompts the user for a password
 *              and adds the entry in the file
 *              user:crpytofpassword:md5hash(user:realm:password) 
 */
static void AddPassword(char *user, char* realm, FILE *f)
{
    char *pw, *crpw, cpw[120], salt[9], *dpw;
    int len = 0, i = 0, crpwLen = 0;
    char *checkw;

    pw = CopyString((char *) getpass("New password:"******"Password cannot be blank, sorry.\n");
        delete(checkw);
        CleanupAndExit();
    }
    delete(checkw);
    
    if (strcmp(pw, (char *) getpass("Re-type new password:"******"They don't match, sorry.\n");
		CleanupAndExit();
    }
	
    (void) srand((int) time((time_t *) NULL));
    to64(&salt[0], rand(), 8);
    salt[8] = '\0';

#ifdef __Win32__
    MD5Encode((char *)pw, (char *)salt, cpw, sizeof(cpw));
#else
    crpw = (char *)crypt(pw, salt); // cpw is crypt of password
    crpwLen = ::strlen(crpw);
    strncpy(cpw, crpw, crpwLen);
    cpw[crpwLen] = '\0';
#endif
    
    dpw = (char *)Digest(user, pw, realm); // dpw is digest of password
    
    qtss_fprintf(f, "%s:%s:%s\n", user, cpw, dpw);
    free(pw); // Do after cpw and dpw are used. 
}
void MP3Broadcaster::PrintPlaylistElement(PLDoubleLinkedListNode<SimplePlayListElement> *node,void *file)
{   
    sBroadcaster->mElementCount ++;
    if (sBroadcaster->mElementCount <= sBroadcaster->mUpcomingSongsListSize)    
    {   
        char* thePick = node->fElement->mElementName;
        qtss_fprintf((FILE*)file,"%s\n", thePick);
    }
}
示例#6
0
void OSFileSource::SetLog(const char *inPath)
{
    fFilePath[0] =0;
    ::strcpy(fFilePath,inPath);
    
    if (fFile != -1 && fFileLog == NULL)
    {
        ::strcat(fFilePath,inPath);
        ::strcat(fFilePath,".readlog");
        fFileLog = ::fopen(fFilePath,"w+");
        if (fFileLog && IsValid())
        {   qtss_fprintf(fFileLog, "%s","QTFILE_READ_LOG\n");
            qtss_fprintf(fFileLog, "size: %qu\n",GetLength());
            qtss_printf("OSFileSource::SetLog=%s\n",fFilePath);
            
        }
        ::fclose(fFileLog);
    }
}
void WriteHitCountToFile()
{
    FILE* hitfile = fopen("hitcount.txt", "w");
    
    int i=0;
    for (i=0;gHitcountArray[i].url[0] && i<512; i++)
    {
        qtss_fprintf(hitfile, "%s %d\n", gHitcountArray[i].url, gHitcountArray[i].hitcount);
    }
    
    fclose(hitfile);
}
示例#8
0
文件: hmi.c 项目: ACEZLY/EasyDarwin
void
main(int argc, char **argv)
{
    int i, j;
    SInt64 ts1, ts2;
    SInt64 ts3, ts4;
    struct timescale tsc;
    double scale;

    if (argc <= 1) {
        qtss_fprintf(stderr, "Usage: %s loop-count\n", argv[0]);
        exit(1);
    }

    j = atoi(argv[1]);

    ts1 = timestamp();  /* START */

    /* Loop for the given loop-count */
    for (i=0; i < j; i++) {
        ;
    }

    ts2 = timestamp();  /* END */

    qtss_printf("ts1 = %qd, ts2 = %qd\n", ts1, ts2);

    utimescale(&tsc);
    scale = (double)tsc.tsc_numerator / (double)tsc.tsc_denominator;

    ts1 = (SInt64)((double)ts1 * scale);
    ts2 = (SInt64)((double)ts2 * scale);

    qtss_printf("ts1 = %qd, ts2 = %qd, micro seconds = %qd\n",
            ts1, ts2, (ts2 - ts1));

    /* Use the scaledtimestamp() now */

    ts3 = scaledtimestamp(scale);   /* START */

    /* Loop for the given loop-count */
    for (i=0; i < j; i++) {
        ;
    }

    ts4 = scaledtimestamp(scale);   /* END */

    qtss_printf("ts3 = %qd, ts4 = %qd, micro seconds = %qd\n",
            ts3, ts4, (ts4 - ts3));

}
/*
 * CleanupAndExit:	Deletes the temp file
 *					and exits with code -1
 *
 */
static void CleanupAndExit(void)
{
    if (13 == errno)
    {    
        qtss_fprintf(stderr, "You must use the sudo command to edit the users and groups files.\n");
        qtss_fprintf(stderr, "Example: sudo qtpasswd user\n");
    }


	if(tempUsersFile)
	{
		unlink(tempUsersFile);
		delete [] tempUsersFile;
	}
	
	if(tempGroupsFile)
	{
		unlink(tempGroupsFile);
		delete [] tempGroupsFile;
	}
	
	exit(1);
}
void MP3Broadcaster::UpdateCurrentFile(char *thePick)
{
    if (NULL == thePick)
        return;
        
    // save currently playing song to .current file 
    if (mShowCurrent) 
    {   FILE *currentFile = fopen(mCurrentFile, "w");
        if(currentFile)
        {
            qtss_fprintf(currentFile,"u=%s\n",thePick);

            fclose(currentFile);
        }   
    }
}
示例#11
0
int
main(int argc, char** argv)
{
	int c;
	extern char *optarg;
	extern int optind;
	int aflg = 0;
	int bflg = 0;
	int errflg = 0;
	char *ofile = NULL;

	while ((c = getopt(argc, argv, "abo:")) != EOF)
		switch (c) {
		case 'a':
			if (bflg)
				errflg++;
			else
				aflg++;
			break;
		case 'b':
			if (aflg)
				errflg++;
			else
				bflg++;
			break;
		case 'o':
			ofile = optarg;
			(void)qtss_printf("ofile = %s\n", ofile);
			break;
		case '?':
			errflg++;
		}
	if (errflg) {
		(void)qtss_fprintf(stderr,
			"usage: cmd [-a|-b] [-o <filename>] files...\n");
		exit(2);
	}
	for (; optind < argc; optind++)
		(void)qtss_printf("%s\n", argv[optind]);
	return 0;
}
示例#12
0
void FilePrefsSource::WriteToConfigFile(const char* configFilePath)
{
	FILE* fileDesc = ::fopen(configFilePath, "w");

	if (fileDesc != NULL)
	{
		int err = ::fseek(fileDesc, 0, SEEK_END);
		Assert(err == 0);

		KeyValuePair* keyValue = fKeyValueList;

		while (keyValue != NULL)
		{
			(void)qtss_fprintf(fileDesc, "%s   %s\n\n", keyValue->fKey, keyValue->fValue);

			keyValue = keyValue->fNext;
		}

		err = ::fclose(fileDesc);
		Assert(err == 0);
	}
}
/* Allocates memory; remember to delete it afterwards */
char* GetTempFileAtPath(char* templatePath, int templatePathLength)
{
	char* tempFile = new char[templatePathLength];
	memcpy(tempFile, templatePath, templatePathLength);
	char* theResultTempFile = NULL;
	
#ifdef __Win32__	
	theResultTempFile = mktemp(tempFile);
#else	
	int theErr = mkstemp(tempFile);
	if (theErr != -1)
		theResultTempFile = tempFile;
#endif

	if (theResultTempFile == NULL)
	{
		char buffer[kErrorStrSize];
		qtss_fprintf(stderr, "Could not create a temp file at %s. (err=%d:%s)\n", tempFile, errno,  qtss_strerror(errno, buffer, sizeof(buffer)));
		CleanupAndExit();
	}
	
	return theResultTempFile;
}
/*
 * AddPasswordWithoutPrompt:    Adds the entry in the file
 *                              user:crpytofpassword:md5hash(user:realm:password) 
 */
static void AddPasswordWithoutPrompt(char *user, char* password, char* realm, FILE *f)
{
    char salt[9];

    (void) srand((int) time((time_t *) NULL));
    to64(&salt[0], rand(), 8);
    salt[8] = '\0';

    char cpw[120], *dpw;
    int crpwLen = 0;

#ifdef __Win32__
    MD5Encode((char *)password, (char *)salt, cpw, sizeof(cpw));
#else
    char *crpw = (char *)crypt(password, salt); // cpw is crypt of password
    crpwLen = ::strlen(crpw);
    strncpy(cpw, crpw, crpwLen);
    cpw[crpwLen] = '\0';
#endif
    
    dpw = (char *)Digest(user, password, realm); // dpw is digest of password
    
    qtss_fprintf(f, "%s:%s:%s\n", user, cpw, dpw);
}
示例#15
0
void LogStatus(QTSS_ServerState theServerState)
{
    static QTSS_ServerState lastServerState = 0;
    static char *sPLISTHeader[] =
    {     "<?xml version=\"1.0\" encoding=\"UTF-8\"?>",
#if __MacOSX__
        "<!DOCTYPE plist SYSTEM \"file://localhost/System/Library/DTDs/PropertyList.dtd\">",
#else
        "<!ENTITY % plistObject \"(array | data | date | dict | real | integer | string | true | false )\">",
        "<!ELEMENT plist %plistObject;>",
        "<!ATTLIST plist version CDATA \"0.9\">",
        "",
        "<!-- Collections -->",
        "<!ELEMENT array (%plistObject;)*>",
        "<!ELEMENT dict (key, %plistObject;)*>",
        "<!ELEMENT key (#PCDATA)>",
        "",
        "<!--- Primitive types -->",
        "<!ELEMENT string (#PCDATA)>",
        "<!ELEMENT data (#PCDATA)> <!-- Contents interpreted as Base-64 encoded -->",
        "<!ELEMENT date (#PCDATA)> <!-- Contents should conform to a subset of ISO 8601 (in particular, YYYY '-' MM '-' DD 'T' HH ':' MM ':' SS 'Z'.  Smaller units may be omitted with a loss of precision) -->",
        "",
        "<!-- Numerical primitives -->",
        "<!ELEMENT true EMPTY>  <!-- Boolean constant true -->",
        "<!ELEMENT false EMPTY> <!-- Boolean constant false -->",
        "<!ELEMENT real (#PCDATA)> <!-- Contents should represent a floating point number matching (\"+\" | \"-\")? d+ (\".\"d*)? (\"E\" (\"+\" | \"-\") d+)? where d is a digit 0-9.  -->",
        "<!ELEMENT integer (#PCDATA)> <!-- Contents should represent a (possibly signed) integer number in base 10 -->",
        "]>",
#endif
    };

    static int numHeaderLines = sizeof(sPLISTHeader) / sizeof(char*);

    static char*    sPlistStart = "<plist version=\"0.9\">";
    static char*    sPlistEnd = "</plist>";
    static char*    sDictStart = "<dict>";
    static char*    sDictEnd = "</dict>";
    
    static char*    sKey    = "     <key>%s</key>\n";
    static char*    sValue  = "     <string>%s</string>\n";
    
    static char *sAttributes[] =
    {
        "qtssSvrServerName",
        "qtssSvrServerVersion",
        "qtssSvrServerBuild",
        "qtssSvrServerPlatform",
        "qtssSvrRTSPServerComment",
        "qtssSvrServerBuildDate",
        "qtssSvrStartupTime",
        "qtssSvrCurrentTimeMilliseconds",
        "qtssSvrCPULoadPercent",
         "qtssSvrState",
        "qtssRTPSvrCurConn",
        "qtssRTSPCurrentSessionCount",
        "qtssRTSPHTTPCurrentSessionCount",
        "qtssRTPSvrCurBandwidth",
        "qtssRTPSvrCurPackets",
        "qtssRTPSvrTotalConn",
        "qtssRTPSvrTotalBytes",
        "qtssMP3SvrCurConn",
        "qtssMP3SvrTotalConn",
        "qtssMP3SvrCurBandwidth",
        "qtssMP3SvrTotalBytes"
    };
    static int numAttributes = sizeof(sAttributes) / sizeof(char*);
        
    static StrPtrLen statsFileNameStr("server_status");    
    
    if (false == sServer->GetPrefs()->ServerStatFileEnabled())
        return;
        
    UInt32 interval = sServer->GetPrefs()->GetStatFileIntervalSec();
    if (interval == 0 || (OS::UnixTime_Secs() % interval) > 0 ) 
        return;
    
    // If the total number of RTSP sessions is 0  then we 
    // might not need to update the "server_status" file.
    char* thePrefStr = NULL;
    // We start lastRTSPSessionCount off with an impossible value so that
    // we force the "server_status" file to be written at least once.
    static int lastRTSPSessionCount = -1; 
    // Get the RTSP session count from the server.
    (void)QTSS_GetValueAsString(sServer, qtssRTSPCurrentSessionCount, 0, &thePrefStr);
    int currentRTSPSessionCount = ::atoi(thePrefStr);
    delete [] thePrefStr; thePrefStr = NULL;
    if (currentRTSPSessionCount == 0 && currentRTSPSessionCount == lastRTSPSessionCount)
    {
        // we don't need to update the "server_status" file except the
        // first time we are in the idle state.
        if (theServerState == qtssIdleState && lastServerState == qtssIdleState)
        {
            lastRTSPSessionCount = currentRTSPSessionCount;
            lastServerState = theServerState;
            return;
        }
    }
    else
    {
        // save the RTSP session count for the next time we execute.
        lastRTSPSessionCount = currentRTSPSessionCount;
    }

    StrPtrLenDel pathStr(sServer->GetPrefs()->GetErrorLogDir());
    StrPtrLenDel fileNameStr(sServer->GetPrefs()->GetStatsMonitorFileName());
    ResizeableStringFormatter pathBuffer(NULL,0);
    pathBuffer.PutFilePath(&pathStr,&fileNameStr);
    pathBuffer.PutTerminator();
    
    char*   filePath = pathBuffer.GetBufPtr();    
    FILE*   statusFile = ::fopen(filePath, "w");
    char*   theAttributeValue = NULL;
    int     i;
    
    if (statusFile != NULL)
    {
        ::chmod(filePath, 0640);
        for ( i = 0; i < numHeaderLines; i++)
        {    
            qtss_fprintf(statusFile, "%s\n",sPLISTHeader[i]);    
        }

        qtss_fprintf(statusFile, "%s\n", sPlistStart);
        qtss_fprintf(statusFile, "%s\n", sDictStart);    

          // show each element value
         for ( i = 0; i < numAttributes; i++)
        {
            (void)QTSS_GetValueAsString(sServer, QTSSModuleUtils::GetAttrID(sServer,sAttributes[i]), 0, &theAttributeValue);
            if (theAttributeValue != NULL)
             {
                qtss_fprintf(statusFile, sKey, sAttributes[i]);    
               qtss_fprintf(statusFile, sValue, theAttributeValue);    
                delete [] theAttributeValue;
                theAttributeValue = NULL;
             }
         }
                  
        qtss_fprintf(statusFile, "%s\n", sDictEnd);
        qtss_fprintf(statusFile, "%s\n\n", sPlistEnd);    
         
          ::fclose(statusFile);
    }
    lastServerState = theServerState;
}
int main(int argc, char *argv[])
{
    FILE *usersFilePtr = NULL, *tempUsersFilePtr = NULL, *passFilePtr = NULL, *groupsFilePtr = NULL;
    //char line[MAX_STRING_LEN + 1];
    char line[MAX_LINE_LEN];
    char lineFromFile[MAX_LINE_LEN];
    char usernameFromFile[MAX_STRING_LEN + 1];
    char realmFromFile[MAX_STRING_LEN + 1];
    int found;
    int result;
    static char choice[81];

    int doCreateNewFile = 0;
    int doDeleteUser = 0;
	int addUserToGroup = 0;
	int deleteUserFromGroup = 0;
	int createGroup = 0;
	int deleteGroup = 0;
    int confirmPotentialDamage = 1;
    char* qtusersFilePath = NULL;
	char* qtgroupsFilePath = NULL;
    char* userName = NULL;
	char* groupName = NULL;
    char* realmString = NULL;
    char* password = NULL;
    char* passwordFilePath = NULL;
    int ch;
    extern char* optarg;
    extern int optind;

	/* Read command line arguments */
    while ((ch = getopt(argc, argv, "f:cg:r:p:P:A:D:C:R:dFhv?")) != EOF)
    {
        switch(ch) 
        {

            case 'f':
                    qtusersFilePath = CopyString(optarg);
            break;
			
            case 'c':
                    doCreateNewFile = 1;
            break;
			
            case 'g':
                    qtgroupsFilePath = CopyString(optarg);
            break;
			
            case 'r':
                    realmString = CopyString(optarg);
                    if (::strlen(realmString) > MAX_STRING_LEN)
                    {
                        qtss_fprintf(stderr, "Realm cannot have more than %d characters.\n", MAX_STRING_LEN);
                        qtss_printf("Exiting! \n");
                        exit(1);
                    }
            break;

            case 'p':
                    password = CopyString(optarg);
					::memset(optarg, 0, ::strlen(optarg));
					
                    if (::strlen(password) > MAX_PASSWORD_LEN)
                    {
                        qtss_fprintf(stderr, "Password cannot have more than %d characters.\n", MAX_PASSWORD_LEN);
                        qtss_printf("Exiting! \n");
                        exit(1);
                    }
            break;

            case 'P':
                    passwordFilePath = CopyString(optarg);
            break;

            case 'A':
                    groupName = CopyString(optarg);
					addUserToGroup = 1;
            break;

            case 'D':
                    groupName = CopyString(optarg);
					deleteUserFromGroup = 1;
            break;

            case 'C':
                    groupName = CopyString(optarg);
					createGroup = 1;
            break;

            case 'R':
                    groupName = CopyString(optarg);
					deleteGroup = 1;
            break;			

            case 'd':
                    doDeleteUser = 1;
            break;
			
            case 'F':
                    confirmPotentialDamage = 0;
            break;

        case 'h':
        case 'v':
            case '?':
            default:
                usage(); 
            break;
        }
    }

	/* If password is to be read from a file, check validity of the password */
	if ((password == NULL) && (passwordFilePath != NULL))
    {
		if ((passFilePtr = fopen(passwordFilePath, "r")) != NULL ) 
		{
			char passline[MAX_STRING_LEN];
			char passFromFile[MAX_STRING_LEN];
			int passLen = 0;
			
			::memset(passline, 0, MAX_STRING_LEN);
			::memset(passFromFile, 0, MAX_STRING_LEN);
			
			GetLine(passline, MAX_STRING_LEN, passFilePtr);
	
			if (passline[0] == '\'')        // if it is single quoted, read until the end single quote
				GetWord(passFromFile, (passline + 1), '\'');
			else if (passline[0] == '"')        // if it is double quoted, read until the end double quote
				GetWord(passFromFile, (passline + 1), '"');
			else                    // if it is not quoted, read until the first whitespace
				GetWord(passFromFile, passline, ' ');
				
			passLen = ::strlen(passFromFile);
				
			if (passLen == 0)
			{
				qtss_fprintf(stderr, "Password in file %s is blank.\n", passwordFilePath);
				qtss_printf("Exiting! \n");
				exit(1);
			}
			else if (passLen > MAX_PASSWORD_LEN)
			{
				qtss_fprintf(stderr, "Password in file %s has more than %d characters. Cannot accept password.\n", passwordFilePath, MAX_PASSWORD_LEN);
				qtss_printf("Exiting! \n");
				exit(1);
			}
			else
				password = CopyString(passFromFile);

            fclose(passFilePtr);
        }
    }

    /* deleting a user and (creating a file or setting a password) don't make sense together */
    if ( doDeleteUser && (doCreateNewFile || password != NULL) )
    {
		qtss_fprintf(stderr, "Cannot use the -c option (to create the file) with the -d option (to delete the user).\n");
		qtss_printf("Exiting! \n");
        usage();
    }

    /* realm name only makes sense when creating a new password file */
    if ( !doCreateNewFile && (realmString != NULL) )
    {
		qtss_fprintf(stderr, "Can use the -r option only with the -c option (when creating the file).\n");
		qtss_printf("Exiting! \n");
		usage();
    }

	/* group name checks */
	if (groupName != NULL) 
	{
		/* check length < MAX_STRING_LEN */
		if (::strlen(groupName) > MAX_STRING_LEN)
		{
			qtss_fprintf(stderr, "Group name cannot have more than %d characters.\n", MAX_STRING_LEN);
			qtss_printf("Exiting! \n");
			exit(1);
		}	
		
		/* check for : */
        if (strchr(groupName, ':') != NULL) 
        {
            qtss_printf("Group name cannot contain a ':' character.\n");
			qtss_printf("Exiting! \n");
			exit(1);
        }
		
		/* can't add user to group and delete user from a group at the same time */
		if (addUserToGroup && deleteUserFromGroup)
        {
            qtss_printf("Cannot add to or delete from a group at the same time (use either -A or -D option, not both!).\n");
			qtss_printf("Exiting! \n");
			exit(1);
        }
		
		/* can't create and delete group at the same time */
		if (createGroup && deleteGroup)
        {
            qtss_printf("Cannot create new group and delete group at the same time (use either -C or -R option, not both!).\n");
			qtss_printf("Exiting! \n");
			exit(1);
        }
	}

	/* Read in the username */
    if (argv[optind] != NULL)
    {
		/* If group needs to be created or deleted, username will be ignored. */
		if (createGroup || deleteGroup)
		{
			qtss_fprintf(stderr, "Warning: username cannot be specified with -C or -R option and will be ignored!\n");
		}
		else
		{
			userName = CopyString(argv[optind]);
			
			/* check length < MAX_STRING_LEN */		
			if (::strlen(userName) > MAX_STRING_LEN)
			{
			qtss_fprintf(stderr, "Username cannot have more than %d characters.\n", MAX_STRING_LEN);
			qtss_printf("Exiting! \n");
			exit(1);
			}
		}
    }
    else
	{
		/* Exit if username is not given, unless a group has to be created or deleted. */
		if (!createGroup && !deleteGroup)
		{
			qtss_fprintf(stderr, "Username not given!\n");
			qtss_printf("Exiting! \n");
			usage();
		}
    }

    if (confirmPotentialDamage && doDeleteUser)
    {
        qtss_printf("Delete user %s (will also delete user from groups in the groups file)? y or n [y] ", userName);
        fgets( (char*)&choice, 80, stdin);
        if( choice[0] == 'n' || choice[0] == 'N' ) 
            exit(0);
    }

    if (qtusersFilePath == NULL)
    {
        qtusersFilePath = new char[strlen(kDefaultQTPasswdFilePath)+1];
        strcpy(qtusersFilePath, kDefaultQTPasswdFilePath);
    }

    if (qtgroupsFilePath == NULL)
    {
        qtgroupsFilePath = new char[strlen(kDefaultQTGroupsFilePath)+1];
        strcpy(qtgroupsFilePath, kDefaultQTGroupsFilePath);
    }
	
    if (realmString  == NULL)
    {
        char* kDefaultRealmString = "Streaming Server";

        realmString = new char[strlen(kDefaultRealmString)+1];
        strcpy(realmString, kDefaultRealmString);
    }

    
    tempUsersFile = NULL;
	tempGroupsFile = NULL;
	
#ifndef __Win32__
    signal(SIGINT, (void(*)(int))CleanupAndExit);
    //create file with owner RW permissions only
    umask(S_IRWXO|S_IRWXG);
#endif

    if (doCreateNewFile)
    {
        if (confirmPotentialDamage)
            if( (usersFilePtr = fopen(qtusersFilePath, "r")) != NULL ) 
            {
                fclose(usersFilePtr);
    
                qtss_printf("File already exists. Do you wish to overwrite it? y or n [y] ");
                fgets( (char*)&choice, 80, stdin);
                if( choice[0] == 'n' || choice[0] == 'N' ) 
                    CleanupAndExit();
                    
            }

        //create new file or truncate existing one to 0
        if ( (usersFilePtr = fopen(qtusersFilePath, "w")) == NULL)
        {   
			char buffer[kErrorStrSize];
            qtss_fprintf(stderr, "Could not open password file %s for writing. (err=%d %s)\n", qtusersFilePath, errno, qtss_strerror(errno, buffer, sizeof(buffer)));
            perror("fopen");
            CleanupAndExit();
        }

        qtss_printf("Creating password file for realm %s.\n", realmString);

        //write the realm into the file
        qtss_fprintf(usersFilePtr, "realm %s\n", realmString);

        fclose(usersFilePtr);
	    SetPrivileges(qtusersFilePath);


    }

#ifdef __Win32__
    char separator = '\\';
#else
    char separator = '/';
#endif
	char* tmpFile = "tmp.XXXXXX";
	char* alternateTempPath = "./tmp.XXXXXX";
    char* tempFilePath;
	int	tempFilePathLength = 0;
    char* lastOccurOfSeparator = strrchr(qtusersFilePath, separator);
    int pathLength = strlen(qtusersFilePath);
	
    if(lastOccurOfSeparator != NULL) 
    {
		int filenameLength = ::strlen(lastOccurOfSeparator) + sizeof(char);
		tempFilePathLength = pathLength - filenameLength + sizeof(char) + ::strlen(tmpFile);
		
		tempFilePath = new char[tempFilePathLength];
		memcpy(tempFilePath, qtusersFilePath, (pathLength - filenameLength));
		memcpy(tempFilePath + (pathLength - filenameLength), tmpFile, ::strlen(tmpFile));
		tempFilePath[pathLength - filenameLength + ::strlen(tmpFile)] = '\0';
		
		/* Get temp users file path name */
		if (!createGroup && !deleteGroup)
			tempUsersFile = GetTempFileAtPath(tempFilePath, tempFilePathLength);

		/* Get temp groups file path name */		
		if ((groupName != NULL) || doDeleteUser)
			tempGroupsFile = GetTempFileAtPath(tempFilePath, tempFilePathLength);
		
		delete [] tempFilePath;
    }
    else 
    {
		if (!createGroup && !deleteGroup)
			tempUsersFile = GetTempFileAtPath(alternateTempPath, ::strlen(alternateTempPath));
		if ((groupName != NULL) || doDeleteUser)
			tempGroupsFile = GetTempFileAtPath(alternateTempPath, ::strlen(alternateTempPath));
	}
		
	if ((groupName != NULL) && !(groupsFilePtr = fopen(qtgroupsFilePath, "r")))
	{
		char buffer[kErrorStrSize];
		qtss_fprintf(stderr, "Could not open groups file %s to manipulate groups file. (err=%d:%s)\n", qtgroupsFilePath, errno,  qtss_strerror(errno, buffer, sizeof(buffer)));
				
		//create new file
        if ( (groupsFilePtr = fopen(qtgroupsFilePath, "w")) == NULL)
        {   
			char buffer[kErrorStrSize];
            qtss_fprintf(stderr, "Could not create a new groups file %s either. (err=%d %s)\n", qtgroupsFilePath, errno, qtss_strerror(errno, buffer, sizeof(buffer)));
			CleanupAndExit();
        }
		else
			qtss_printf("Created new groups file %s.\n", qtgroupsFilePath);

        fclose(groupsFilePtr);
	    SetPrivileges(qtgroupsFilePath);
	}
	
	if (createGroup)
	{
		AddOrDeleteGroup(1, groupName, qtgroupsFilePath, tempGroupsFile);
		qtss_printf("Created new group %s\n", groupName);
		return 0;
	}
	
	if (deleteGroup)
	{
		AddOrDeleteGroup(0, groupName, qtgroupsFilePath, tempGroupsFile);
		qtss_printf("Deleted group %s\n", groupName);
		return 0;
	}
	
    if (!(tempUsersFilePtr = fopen(tempUsersFile, "w"))) 
    {   
        char buffer[kErrorStrSize];
        qtss_printf("failed\n");
        qtss_fprintf(stderr, "Could not open temp users file. (err=%d %s)\n", errno,  qtss_strerror(errno, buffer, sizeof(buffer)));
		CleanupAndExit();
    }
	
    if (!(usersFilePtr = fopen(qtusersFilePath, "r")))
    {   
        char buffer[kErrorStrSize];
        qtss_fprintf(stderr, "Could not open passwd file %s for reading. (err=%d:%s)\n", qtusersFilePath, errno,  qtss_strerror(errno, buffer, sizeof(buffer)));
        qtss_fprintf(stderr, "Use -c option to create new one.\n");
		CleanupAndExit();
    }

    // Get the realm from the first line
    while (!(GetLine(line, MAX_LINE_LEN, usersFilePtr))) 
    {
        if ((line[0] == '#') || (!line[0]))
        {
            PutLine(tempUsersFilePtr, line);
            continue;
        }
        else
        {
            // line is "realm somename"
            if( strncmp(line, "realm", strlen("realm")) != 0 )
            {
                    qtss_fprintf(stderr, "Invalid users file.\n");
                    qtss_fprintf(stderr, "The first non-comment non-blank line must be the realm line\n");
                    qtss_fprintf(stderr, "The file may have been tampered manually!\n");				
					CleanupAndExit();
            }
            strcpy(realmFromFile ,line + strlen("realm")+1); 
            PutLine(tempUsersFilePtr, line);
            break;  
        }
    }
    // Look for an existing entry with the username
    found = 0;
    while (!(GetLine(line, MAX_LINE_LEN, usersFilePtr))) 
    {
        //write comments and blank lines out to temp file
        if (found || (line[0] == '#') || (line[0] == 0)) 
        {
            PutLine(tempUsersFilePtr, line);
            continue;
        }
        strcpy(lineFromFile, line);
        GetWord(usernameFromFile, lineFromFile, ':');

        //if not the user we're looking for, write the line out to the temp file
        if (strcmp(userName, usernameFromFile) != 0) 
        {
            PutLine(tempUsersFilePtr, line);
            continue;
        }
        else 
        {
            if (doDeleteUser)
            {   //to delete a user - just don't write it out to the temp file
                qtss_printf("Deleting user %s\n", userName);
				//delete user from all groups in the group file
				qtss_printf("Deleting user %s from all groups\n", userName);
				AddOrDeleteUserFromGroup(0, userName, NULL, qtgroupsFilePath, tempGroupsFile);
				
            }
            else
            {
				if (addUserToGroup)
				{
					PutLine(tempUsersFilePtr, line);
					
					qtss_printf("Adding user %s to group %s\n", userName, groupName);
					AddOrDeleteUserFromGroup(1, userName, groupName, qtgroupsFilePath, tempGroupsFile);
				}
				else if (deleteUserFromGroup)
				{
					PutLine(tempUsersFilePtr, line);
					
					qtss_printf("Deleting user %s from group %s\n", userName, groupName);
					AddOrDeleteUserFromGroup(0, userName, groupName, qtgroupsFilePath, tempGroupsFile);
				}
				else
				{
					qtss_printf("Changing password for user %s\n", userName);
					if(password != NULL)
						AddPasswordWithoutPrompt(userName, password, realmFromFile, tempUsersFilePtr);
					else 
						AddPassword(userName, realmFromFile, tempUsersFilePtr);
				}
            }
            found = 1;
        }
    }
    
    if (!found) 
    {
        if (doDeleteUser)
        {
            qtss_printf("Username %s not found in users file.\n", userName);
			
			//delete user from all groups in the group file
			qtss_printf("Deleting user %s from all groups if found in groups file\n", userName);
			AddOrDeleteUserFromGroup(0, userName, NULL, qtgroupsFilePath, tempGroupsFile);
			CleanupAndExit();
        }

        /* check for : in name before adding user */
        if(strchr(userName, ':') != NULL) 
        {
            qtss_printf("Username cannot contain a ':' character.");
			CleanupAndExit();
        }
    
        qtss_printf("Adding userName %s\n", userName);
        if(password != NULL)
            AddPasswordWithoutPrompt(userName, password, realmFromFile, tempUsersFilePtr);
        else 
            AddPassword(userName, realmFromFile, tempUsersFilePtr);
			
		if (addUserToGroup)
		{
			qtss_printf("Adding user %s to group %s\n", userName, groupName);
			AddOrDeleteUserFromGroup(1, userName, groupName, qtgroupsFilePath, tempGroupsFile);
		}
		else if (deleteUserFromGroup)
		{
			qtss_printf("Deleting user %s from group %s\n", userName, groupName);
			AddOrDeleteUserFromGroup(0, userName, groupName, qtgroupsFilePath, tempGroupsFile);
		}
    }
    	
    fclose(usersFilePtr);
    fclose(tempUsersFilePtr);
    
    // Remove old file and change name of temp file to match new file
    remove(qtusersFilePath);
    
    result = rename(tempUsersFile, qtusersFilePath);
    if(result != 0)
	{
        perror("rename failed with error");
		CleanupAndExit();
	}
	SetPrivileges(qtusersFilePath);

    return 0;
}
static void AddOrDeleteGroup(int add, char *groupName, char *inGroupsFilePath, char *inTempGroupsFilePath)
{
    char line[MAX_LINE_LEN];
    char lineFromFile[MAX_LINE_LEN];
    char groupNameFromFile[MAX_STRING_LEN + 1];
    bool foundGroup = false;
	FILE *groupsFilePtr, *tempGroupsFilePtr;
	bool addedGroup = false;
	
    if (!(groupsFilePtr = fopen(inGroupsFilePath, "r")))
    {   
		if (add)
		{
			char buffer[kErrorStrSize];
			qtss_fprintf(stderr, "Could not open groups file %s for reading. (err=%d:%s)\n", inGroupsFilePath, errno,  qtss_strerror(errno, buffer, sizeof(buffer)));
			CleanupAndExit();
		}
		else
			return;
    }
		
	if (!(tempGroupsFilePtr = fopen(inTempGroupsFilePath, "w"))) 
    {   
        char buffer[kErrorStrSize];
        qtss_fprintf(stderr, "Could not open temp groups file. (err=%d %s)\n", errno,  qtss_strerror(errno, buffer, sizeof(buffer)));
		CleanupAndExit();
    }
	
	while (!(GetLine(line, MAX_LINE_LEN, groupsFilePtr))) 
    {
        //write comments and blank lines out to temp file
        if (foundGroup || (line[0] == '#') || (line[0] == 0)) 
        {
            PutLine(tempGroupsFilePtr, line);
            continue;
        }
		
        strcpy(lineFromFile, line);
		EatWhitespace(lineFromFile);
        GetWord(groupNameFromFile, lineFromFile, ':');

        //if it's not the group we're looking for, write the line out to the temp file
        if ((groupName != NULL) && strcmp(groupName, groupNameFromFile) != 0) 
        {
            PutLine(tempGroupsFilePtr, line);
            continue;
        }
        else if (add) // if we are trying to add the group and it already exists, leave it in
		{
			PutLine(tempGroupsFilePtr, line);
			addedGroup = true;
		}
		
		foundGroup = true;
	}		
	
	if (add && !addedGroup)
	{
		PutWord(tempGroupsFilePtr, groupName, ':');
		fputc('\n', tempGroupsFilePtr);
	}
							
	fclose(tempGroupsFilePtr);
	fclose(groupsFilePtr);
	
    // Rename the temp groups file to the groups file
    //remove(qtusersFilePath);
    
    if (rename(inTempGroupsFilePath, inGroupsFilePath) != 0)
	{
        perror("rename failed with error");
		CleanupAndExit();
	} 
}
/*
 * Usage:   Prints the usage and calls exit
 */
static void usage(void)
{
    qtss_fprintf(stderr, "  qtpasswd %s built on: %s\n", kVersionString, __DATE__ ", "__TIME__);
    qtss_fprintf(stderr, "  Usage: qtpasswd [-F] [-f filename] [-c] [-g groupsfilename] [-r realm] [-p password] [-P passwordfile] [-A group] [-D group] [-d] [username]\n");
    qtss_fprintf(stderr, "  -F   Don't ask for confirmation when deleting users or overwriting existing files.\n");
    qtss_fprintf(stderr, "  -f   Password file to manipulate (Default is \"%s\").\n", kDefaultQTPasswdFilePath);
    qtss_fprintf(stderr, "  -c   Create new file.\n");
    qtss_fprintf(stderr, "  -g   Groups file to manipulate (Default is \"%s\"). If not found, will create one when necessary.\n", kDefaultQTGroupsFilePath);
    qtss_fprintf(stderr, "  -r   The realm name to use when creating a new file via \"-c\" (Default is \"%s\").\n", kDefaultRealmString);
    qtss_fprintf(stderr, "  -p   Allows entry of password at command line rather than prompting for it.\n");
    qtss_fprintf(stderr, "  -P   File to read the password from rather than prompting for it.\n");
    qtss_fprintf(stderr, "  -d   Delete the user. (Deletes the user from all groups)\n");
    qtss_fprintf(stderr, "  -A   Add user to group. Will create group automatically if group is not already present.\n");
    qtss_fprintf(stderr, "  -D   Delete the user from the group.\n");
    qtss_fprintf(stderr, "  -C   Create new group. Do not specify username with this option.\n");
    qtss_fprintf(stderr, "  -R   Delete the group. Do not specify username with this option.\n");
    qtss_fprintf(stderr, "  -h   Displays usage.\n");
    qtss_fprintf(stderr, "  -v   Displays usage.\n");
    qtss_fprintf(stderr, "  -?   Displays usage.\n");
    qtss_fprintf(stderr, "  Note:\n");
    qtss_fprintf(stderr, "  The username must always be specified except when -C and -R options are used to create/delete group.\n");
    qtss_fprintf(stderr, "  Usernames cannot be more than %d characters long and must not include a colon [:].\n", MAX_STRING_LEN);
    qtss_fprintf(stderr, "  Passwords cannot be more than %d characters long.\n", MAX_PASSWORD_LEN);
    qtss_fprintf(stderr, "  Groups cannot be more than %d characters long and must not include a colon [:].\n", MAX_STRING_LEN);
    qtss_fprintf(stderr, "  If the username/password contains whitespace or characters that may be\n");
    qtss_fprintf(stderr, "  interpreted by the shell please enclose it in single quotes,\n");
    qtss_fprintf(stderr, "  to prevent it from being interpolated.\n");
    qtss_fprintf(stderr, "\n");
    exit(1);
}
void MP3Broadcaster::PreFlightOrBroadcast( bool preflight, bool daemonize, bool showMovieList, bool currentMovie, bool checkMP3s, const char* errorlog)
{
    PlaylistPicker*     picker = NULL;
    PlaylistPicker*     insertPicker = NULL;
    MP3FileBroadcaster  fileBroadcaster(&mSocket, mBitRate, mFrequency);
    MP3MetaInfoUpdater* metaInfoUpdater = NULL;
    
    SInt32                moviePlayCount;
    char*               thePick = NULL;
    SInt32                numMovieErrors;
   	bool				didAtLeastOneMoviePlay = false;
    int err;
        
        mPreflight = preflight;
        
    if ( preflight )
        ShowSetupParams();

    if (preflight)
        picker = new PlaylistPicker(false);             // make sequential picker, no looping
    else
    {   
        picker = MakePickerFromConfig(); // make  picker according to parms
        mTempPicker =  new PlaylistPicker(false);
        insertPicker = new PlaylistPicker(false);
        insertPicker->mRemoveFlag = true;
    }
    
    // initial call uses empty string for path, NULL for loop detection list
    (void)PopulatePickerFromFile( picker, mPlayListPath, "", NULL );
    
    if ( preflight )
    {
        if ( picker->mNumToPickFrom == 1 )
            qtss_printf( "\nThere is one movie in the Playlist.\n\n" );
        else
            qtss_printf( "\nThere are (%li) movies in the Playlist.\n\n", (SInt32) picker->mNumToPickFrom );
    }   
    
    if ( picker->mNumToPickFrom == 0 )
    {   
        qtss_printf( "- MP3Broadcaster setup failed: There are no movies to play.\n" );
        mNumErrors++;
        goto bail;
    }
    

    // check that we have enough movies to cover the recent movies list.
    if ( preflight )
    {
        if (  !strcmp( mPlayMode, "weighted_random" ) ) // this implies "random" play
        {   
            if ( mRecentSongsListSize >=  picker->mNumToPickFrom )
            {
                mRecentSongsListSize = picker->mNumToPickFrom - 1;
                qtss_printf("- PlaylistBroadcaster Warning:\n  The recent_movies_list_size setting is greater than \n");
                qtss_printf("  or equal to the number of movies in the playlist.\n" );
                                mNumWarnings++;
            }
        }
    }
    
    // create the log file
    mLog = new MP3BroadcasterLog( mWorkingDirPath,  mLogFile, mLogging );
    
//  if ( !PreflightTrackerFileAccess( R_OK | W_OK ) )
//      goto bail;

    if (!preflight)
    {
        err = ConnectToServer();
        if (err)
        {       
                        if (err == EACCES)
                            qtss_printf("- MP3Broadcaster: Disconnected from Server. Bad password or mount point\n  Exiting.\n" );
                        else
                            qtss_printf("- MP3Broadcaster: Couldn't connect to server\n  Exiting.\n" );
            mNumErrors++;
            goto bail;
        }
    }
    
    //Unless the Debug command line option is set, daemonize the process at this point
    if (daemonize)
    {   
#ifndef __Win32__
        qtss_printf("- MP3Broadcaster: Started in background.\n");
        
        // keep the same working directory..
#ifdef __sgi__
		if (::_daemonize(_DF_NOCHDIR, STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO) != 0)
#else
        if (::daemon( 1, 0 ) != 0)
#endif
        {
            qtss_printf("- MP3Broadcaster:  System error (%i).\n", errno);
            mNumErrors++;
            goto bail;
        }

#endif      
    }
    
        if (daemonize && (errorlog != NULL))
    {   
                freopen(errorlog, "a", stdout);
        ::setvbuf(stdout, (char *)NULL, _IONBF, 0);
    }
        
        if (!preflight)
        {
                metaInfoUpdater = new MP3MetaInfoUpdater(mPassword, mMountPoint, mSocket.GetRemoteAddr(), mPort);
                metaInfoUpdater->Start();
                fileBroadcaster.SetInfoUpdater(metaInfoUpdater);
    }
        
        // ^ daemon must be called before we Open the log and tracker since we'll
    // get a new pid, our files close,  ( does SIGTERM get sent? )
    
    if (( mLog ) && ( mLogging ))
        mLog->EnableLog( false ); // don't append ".log" to name for PLB
    
    if ( mLogging && !mLog->IsLogEnabled() )
    {
        if (  mLog->LogDirName() && *mLog->LogDirName() )
            qtss_printf("- MP3Broadcaster: The log file failed to open.\n  ( path: %s/%s )\n  Exiting.\n", mLog->LogDirName(), mLog->LogFileName() );
        else
            qtss_printf("- MP3Broadcaster: The log file failed to open.\n  ( path: %s )\n  Exiting.\n", mLog->LogFileName() );
        
        mNumErrors++;
        goto bail;
    }
    
    
    if (mPIDFile[0] != 0)
    {
        if(!FileCreateAndCheckAccess(mPIDFile))
        {
            FILE *pidFile = fopen(mPIDFile, "w");
            if(pidFile)
            {
                qtss_fprintf(pidFile,"%d\n",getpid());
                fclose(pidFile);
            }   
        }
    }
    
//  AddOurPIDToTracker( bcastSetupFilePath ); // <-- exits on failure

    if ( !preflight )
        mLog->LogInfo( "MP3Broadcaster started." );
    else
        mLog->LogInfo( "MP3Broadcaster preflight started." );

    if(!preflight)
    {   
        CreateCurrentAndUpcomingFiles();
        SendXAudioCastHeaders();
    }
        
    if (!preflight)
    {
        // check the frequency of the first song
        fileBroadcaster.PlaySong( picker->GetFirstFile(), NULL, true, true );
    }
    
    moviePlayCount = 0;
    numMovieErrors = 0;
 	didAtLeastOneMoviePlay = false;
           
    while (true)
    {   
    
        if (!showMovieList && !preflight)
            UpdatePlaylistFiles(picker, insertPicker);
             
        if (NULL != insertPicker)
            thePick = insertPicker->PickOne(); 
            
        if (NULL == thePick && (NULL != picker))
            thePick = picker->PickOne();
                
        if ( (thePick != NULL) && (!preflight && showMovieList) )
        {
            // display the picks in debug mode, but not preflight
            qtss_printf( "[%li] %s picked\n", moviePlayCount, thePick );
        }
        
        
        if ( !showMovieList )
        {
            int playError;
                
            if(!preflight)
            {   UpdateCurrentFile(thePick);
                /* if playlist is about to run out repopulate it */
                if  (   !::strcmp(mPlayMode, "sequential_looped") )
                {   
                    if(NULL == thePick &&!picker->mStopFlag)
                    {   
                        if (picker->GetNumMovies() == 0) 
                            break;
                        else
                            continue;
                    }
                        
                }
            }

            if (thePick == NULL)
                break;
            
            ++moviePlayCount;
            
            if(!preflight)
            {
            
                SInt64 startTime = OS::Milliseconds();
                SInt64 endTime = 0;
                playError = fileBroadcaster.PlaySong( thePick, mCurrentFile );
                endTime = OS::Milliseconds();
                
				//were we able to actually play the movie?
				didAtLeastOneMoviePlay = didAtLeastOneMoviePlay || (playError == 0);
				
				//ok, we've reached the end of the current playlist
				if (picker->GetNumMovies() == 0)
				{
					//If we determine that every one of the movies resulted in an error, then bail
					if (!didAtLeastOneMoviePlay)
					{
						qtss_printf("Quitting:  Playlist contains no valid files.\n");
						mLog->LogInfo( "Quitting:  Playlist contains no valid files.\n" );
						goto bail;
					}
					else
					{
						didAtLeastOneMoviePlay = false;
					}
				}
                
                mLog->LogMediaData(thePick, fileBroadcaster.GetTitle(), 
                                            fileBroadcaster.GetArtist(), 
                                            fileBroadcaster.GetAlbum(),
                                            (UInt32) ((endTime - startTime)/1000L),
                                            playError);
            }
            else
            {
                playError = fileBroadcaster.PlaySong( thePick, NULL, preflight, !checkMP3s );
            }
            
            if (playError == MP3FileBroadcaster::kConnectionError)
            {
                // do something
                mNumErrors++;
                goto bail;
            }
            
            if ( !preflight && (playError != 0))
            {    
                 qtss_printf("File %s : ", thePick);
                 mLog->LogMediaError( thePick, MapErrorToString(playError), NULL );
            }
            else if (playError != 0)
            {
                qtss_printf("File %s : ", thePick);
                MapErrorToString(playError);
                numMovieErrors++;
                mNumWarnings++;
            }
        }
        

        delete [] thePick;
        thePick = NULL;
    } //while (true)
    
    remove(mCurrentFile);
    remove(mUpcomingFile);  

    if ( preflight )
    {
        char    str[256];   
        qtss_printf( " - "  );
        if (numMovieErrors == 1)
            strcpy(str, "MP3Broadcaster found one problem MP3 file.");
        else
            qtss_sprintf( str, "MP3Broadcaster found %li problem MP3 files." , numMovieErrors );
        qtss_printf( "%s\n", str );
        if (mLog) mLog->LogInfo( str );
        
        if (numMovieErrors == moviePlayCount)
        {
            qtss_printf("There are no valid MP3s to play\n");
            mNumErrors++;
        }
    }
    
bail:

    delete picker;

    if (metaInfoUpdater)
        delete metaInfoUpdater;
        
        Cleanup();

#ifndef __Win32__
/*
    if ( sgTrackingSucceeded )
    {
        // remove ourselves from the tracker
        // this is the "normal" remove, also signal handlers
        // may remove us.
        
        BCasterTracker  tracker( sgTrackerFilePath );
        
        tracker.RemoveByProcessID( getpid() );
        tracker.Save();
    }
*/
#endif
}
示例#20
0
文件: nilib2.c 项目: 9crk/EasyDarwin
int
do_open(char *tool, char *name, void **domain, bool bytag, int timeout, char *user, char *passwd)
{
    /* do an ni_open or an ni_connect, as appropriate */

    char *tag;
    enum ni_parse_status pstatus;
    ni_status status;
    struct sockaddr_in server;
    ni_id rootdir;

    if (bytag) {
        /* connect by tag */
        /* call a function to parse the input arg */
        pstatus = ni_parse_server_tag(name, &server, &tag);
        if (pstatus != NI_PARSE_OK)
        {
            qtss_fprintf(stderr, "%s: incorrect format for domain %s (%s)\n",
                tool, name, ni_parse_error_string(pstatus));
            qtss_fprintf(stderr, "usage: -t <host>/<tag>\n");
            qtss_fprintf(stderr, "<host> can be a host name or IP address\n");
                        return NI_FAILED + 1 + pstatus;
        }

        /* connect to the specified server */
        *domain = ni_connect(&server, tag);
        if (*domain == NULL) {
            qtss_fprintf(stderr, "%s: can't connect to server %s\n", tool, name);
            free(tag);
                        return NI_FAILED + 1;
        }
    }

    else {
        /* open domain */
        status = ni_open(NULL, name, domain);
        if (status != NI_OK) {
            qtss_fprintf(stderr, "%s: can't connect to server for domain %s\n",
                tool, name);
                        return status;
        }
    }

    /* abort on errors */
    ni_setabort(*domain, 1);
    
    /* set timeouts */
    ni_setreadtimeout(*domain, timeout);
    ni_setwritetimeout(*domain, timeout);

    /* authentication */
    if (user != NULL) {
        ni_setuser(*domain, user);
        if (passwd != NULL) ni_setpassword(*domain, passwd);
    }

    /* get the root directory to see if the connection is alive */
    status = ni_root(*domain, &rootdir);
    if (status != NI_OK) {
        if (bytag)
            qtss_fprintf(stderr, "%s: can't connect to server %s: %s\n",
                tool, name, ni_error(status));
        else
            qtss_fprintf(stderr, "%s: can't connect to server for domain %s: %s\n",
                tool, name, ni_error(status));
                return status;
    }

    return 0;
}
示例#21
0
文件: nilib2.c 项目: 9crk/EasyDarwin
enum ni_parse_status
ni_parse_server_tag(char *str, struct sockaddr_in *server, char **t)
{
    /* utility to parse a server/tag string */

    int len, i;
    char *host, *tag, *slash;
    struct hostent *hent;

    len = strlen(str);

    /* find the "/" character */
    slash = index(str, '/');

    /* check to see if the "/" is missing */
    if (slash == NULL) return NI_PARSE_BADFORMAT;

    /* find the location of the '/' */
    i = slash - str;

    /* check if host string is empty */
    if (i == 0) return NI_PARSE_NOHOST;

    /* check if tag string is empty */
    if (i == (len - 1)) return NI_PARSE_NOTAG;

    /* allocate some space for the host and tag */
    host = (char *)malloc(i + 1);
    *t = (char *)malloc(len - i);
    tag = *t;

    /* copy out the host */
    strncpy(host, str, i);
    host[i] = '\0';

    /* copy out the tag */
    strcpy(tag, slash + 1);

    /* try interpreting the host portion as an address */
    server->sin_addr.s_addr = inet_addr(host);

    if (server->sin_addr.s_addr == -1)
    {
        /* This isn't a valid address.  Is it a known hostname? */
        hent = gethostbyname(host);
        if (hent != NULL)
        {
            /* found a host with that name */
            bcopy(hent->h_addr, &server->sin_addr, hent->h_length);
        }
        else
        {
            qtss_fprintf(stderr, "Can't find address for %s\n", host);
            free(host);
            free(tag);
            return NI_PARSE_HOSTNOTFOUND;
        }
   }

    free(host);
    return NI_PARSE_OK;
}
/* changed by [email protected] (see relaod.txt for info) */
int QTFileBroadcaster::Play(char *mTimeFile)
/* ***************************************************** */
{
    SInt16  err = 0;
    Float64 transmitTime = 0;
    MediaStream *theStreamPtr = NULL;   
    RTpPacket   rtpPacket;
    unsigned int sleptTime;
    SInt32 movieStartOffset = 0; //z
    Bool16      negativeTime = false;
    fMovieDuration = fRTPFilePtr->GetMovieDuration();
    fSendTimeOffset = 0.0;
    fMovieStart = true;
    fNumMoviesPlayed ++;
    
    if (fMovieEndTime > 0) // take into account the movie load time as well as the last movie early end.
    {   UInt64 timeNow = PlayListUtils::Milliseconds();
        fMovieIntervalTime = timeNow - fMovieEndTime;

        SInt32 earlySleepTimeMilli = (SInt32)(fMovieTimeDiffMilli - fMovieIntervalTime);
        earlySleepTimeMilli -= 40; // Don't sleep the entire time we need some time to execute or else we will be late
        if (earlySleepTimeMilli > 0)
        {   OSThread::Sleep( earlySleepTimeMilli);
        }
    }
    
    fMovieStartTime = PlayListUtils::Milliseconds();    
    fMediaStreamList.MovieStarted(fMovieStartTime); 
    
/* changed by [email protected] (see relaod.txt for info) */
    if(mTimeFile!=NULL)
    {
        FILE *fTimeFile = NULL;
        struct timeval start, dur, end;
        struct tm tm_start, tm_dur, tm_end, timeResult;

        memset (&start,0, sizeof(start));

        SInt64 timenow = OS::Milliseconds();
        start.tv_sec = (long) OS::TimeMilli_To_UnixTimeSecs(timenow);
        start.tv_usec = (long) ((OS::TimeMilli_To_UnixTimeMilli(timenow) - (start.tv_sec * 1000)) * 1000);

        dur.tv_sec = (long)fMovieDuration;
        dur.tv_usec = (long)((fMovieDuration - dur.tv_sec) * 1000000);
        
        end.tv_sec = start.tv_sec + dur.tv_sec + (long)((start.tv_usec + dur.tv_usec) / 1000000);
        end.tv_usec = (start.tv_usec + dur.tv_usec) % 1000000;
                time_t startSecs = start.tv_sec;
                time_t endSecs = end.tv_sec;
        memcpy(&tm_start, qtss_localtime(&startSecs, &timeResult), sizeof(struct tm));
        memcpy(&tm_end, qtss_localtime(&endSecs, &timeResult), sizeof(struct tm));

        tm_dur.tm_hour = dur.tv_sec / 3600;
        tm_dur.tm_min = (dur.tv_sec % 3600) / 60;
        tm_dur.tm_sec = (dur.tv_sec % 3600) % 60;
        
        // initialize all current movie parameters to unkown ("-").
        
        ::strcpy(fCurrentMovieName, "-");
        ::strcpy(fCurrentMovieCopyright, "-");
        ::strcpy(fCurrentMovieComment, "-");
        ::strcpy(fCurrentMovieAuthor, "-");
        ::strcpy(fCurrentMovieArtist, "-");
        ::strcpy(fCurrentMovieAlbum, "-");

        /* save start time, stop time and length of currently playing song to .current file */
        fTimeFile = fopen(mTimeFile, "a");
        if(fTimeFile)
        {   
            SimpleString *theQTTextPtr = fMovieSDPParser->fQTTextLines.Begin();
            while (theQTTextPtr != NULL)
            {
                char tmp[256];
                ::memcpy(tmp, theQTTextPtr->fTheString, theQTTextPtr->fLen);
                tmp[theQTTextPtr->fLen] = 0;
                // if this SDP parameter is needed for logging then cache it here so
                // we can log it later.
                if (::strstr(theQTTextPtr->fTheString, "a=x-qt-text-nam:")!=NULL)
                    ::strcpy(fCurrentMovieName, &tmp[16]);
                if (::strstr(theQTTextPtr->fTheString, "a=x-qt-text-cpy:")!=NULL)
                    ::strcpy(fCurrentMovieCopyright, &tmp[16]);
                if (::strstr(theQTTextPtr->fTheString, "a=x-qt-text-cmt:")!=NULL)
                    ::strcpy(fCurrentMovieComment, &tmp[16]);
                if (::strstr(theQTTextPtr->fTheString, "a=x-qt-text-aut:")!=NULL)
                    ::strcpy(fCurrentMovieAuthor, &tmp[16]);
                if (::strstr(theQTTextPtr->fTheString, "a=x-qt-text-ART:")!=NULL)
                    ::strcpy(fCurrentMovieArtist, &tmp[16]);
                if (::strstr(theQTTextPtr->fTheString, "a=x-qt-text-alb:")!=NULL)
                    ::strcpy(fCurrentMovieAlbum, &tmp[16]);
                fwrite(theQTTextPtr->fTheString,theQTTextPtr->fLen, sizeof(char),fTimeFile);
                qtss_fprintf(fTimeFile,"\n");
                theQTTextPtr = fMovieSDPParser->fQTTextLines.Next();
            }

            time_t startTime = (time_t) start.tv_sec;
            time_t endTime = (time_t) end.tv_sec;
            char buffer[kTimeStrSize];
            char *timestringStart = qtss_ctime(&startTime, buffer, sizeof(buffer));
            qtss_fprintf(fTimeFile,"b=%02d:%02d:%02d:%06d %ld %s", (int) tm_start.tm_hour, (int) tm_start.tm_min, (int) tm_start.tm_sec, (int)start.tv_usec, (long int) startTime, timestringStart);
            char *timestringEnd = qtss_ctime(&endTime, buffer, sizeof(buffer));
            qtss_fprintf(fTimeFile,"e=%02d:%02d:%02d:%06d %ld %s", (int)tm_end.tm_hour, (int) tm_end.tm_min,(int)  tm_end.tm_sec, (int) end.tv_usec,(long int) endTime, timestringEnd);
            qtss_fprintf(fTimeFile,"d=%02d:%02d:%02d:%06d %d \n", (int) tm_dur.tm_hour, (int) tm_dur.tm_min,(int)  tm_dur.tm_sec, (int) dur.tv_usec, (int)dur.tv_sec);

            fclose(fTimeFile);
        }   
    }

    while (true) 
    {
        if (fQuitImmediatePtr && *fQuitImmediatePtr){err = 0; break; } // quit now not an error
        
        if (fBroadcastDefPtr->mTheSession)
        {   UInt32 thePacketQLen = 0;
            thePacketQLen = fBroadcastDefPtr->mTheSession->GetPacketQLen();
            SInt64 maxSleep = PlayListUtils::Milliseconds() + 1000; 
            if (thePacketQLen > eMaxPacketQLen)
            {   //qtss_printf("PacketQ too big = %lu \n", (UInt32) thePacketQLen);
                while ( (eMaxPacketQLen/2) < fBroadcastDefPtr->mTheSession->GetPacketQLen())
                {   this->SleepInterval(100.0);
                    if (maxSleep < PlayListUtils::Milliseconds())
                        break;
                }
                //qtss_printf("PacketQ after sleep = %lu \n", (UInt32) fBroadcastDefPtr->mTheSession->GetPacketQLen());
                continue;
            }
        }
        
        
        transmitTime = fRTPFilePtr->GetNextPacket(&rtpPacket.fThePacket, &rtpPacket.fLength);
            theStreamPtr = (MediaStream*)fRTPFilePtr->GetLastPacketTrack()->Cookie1;
        err = fRTPFilePtr->Error();
        if (err != QTRTPFile::errNoError)   {err = eMovieFileInvalid; break; } // error getting packet
        if (NULL == rtpPacket.fThePacket)   {err = 0; break; } // end of movie not an error
        if (NULL == theStreamPtr)           {err = eMovieFileInvalid; break; }// an error

        
        transmitTime *= (Float64) PlayListUtils::eMilli; // convert to milliseconds
        if (transmitTime < 0.0 && negativeTime == false) // Deal with negative transmission times
        {   movieStartOffset += (SInt32) (transmitTime / 15.0);
            negativeTime = true;
        }
        sleptTime = (unsigned int) Sleep(transmitTime);
        
        err = theStreamPtr->Send(&rtpPacket);
            
        if (err != 0)  { break; } 
        err = fMediaStreamList.UpdateStreams();
        if (err != 0)  { break; } 
        
        if (    (fBroadcastDefPtr != NULL)
            &&  (fBroadcastDefPtr->mTheSession != NULL)
            &&  (fBroadcastDefPtr->mTheSession->GetReasonForDying() != BroadcasterSession::kDiedNormally)   
            )   
         { break; } 
    };
    
    fMovieEndTime = (SInt64) PlayListUtils::Milliseconds(); 
    fMediaStreamList.MovieEnded(fMovieEndTime);

    // see if the movie duration is greater than the time it took to send the packets.
    // the difference is a delay that we insert before playing the next movie.
    SInt64 playDurationMilli = (SInt64) fMovieEndTime - (SInt64) fMovieStartTime;
    fMovieTimeDiffMilli =  ((SInt64) ( (Float64) fMovieDuration * (Float64) PlayListUtils::eMilli)) - (SInt64) playDurationMilli;
    fMovieTimeDiffMilli-= (movieStartOffset/2);

    return err;
}
示例#23
0
void print_status(FILE* file, FILE* console, char* format, char* theStr)
{
    if (file) qtss_fprintf(file, format, theStr);
    if (console) qtss_fprintf(console, format, theStr);

}
void MP3Broadcaster::UpdatePlaylistFiles(PlaylistPicker *picker,PlaylistPicker *insertPicker)
{
    if ( (NULL == picker) || (NULL == insertPicker) ) 
        return;
        
    /* if .stoplist file exists - prepare to stop broadcast */
    if(!access(mStopFile, R_OK))
    {
        picker->CleanList();
        PopulatePickerFromFile(picker, mStopFile, "", NULL);

        mTempPicker->CleanList();

        remove(mStopFile);
        picker->mStopFlag = true;
    }

    /* if .replacelist file exists - replace current playlist */
    if(!access(mReplaceFile, R_OK))
    {
        picker->CleanList();     
        PopulatePickerFromFile(picker, mReplaceFile, "", NULL);
        
        mTempPicker->CleanList();
        
        remove(mReplaceFile);
        picker->mStopFlag = false;
    }

    /* if .insertlist file exists - insert into current playlist */
    if(!access(mInsertFile, R_OK))
    {
        insertPicker->CleanList();
        mTempPicker->CleanList();

        PopulatePickerFromFile(insertPicker, mInsertFile, "", NULL);
        remove(mInsertFile);
        picker->mStopFlag = false;
    }


                // write upcoming playlist to .upcoming file 
    if (mShowUpcoming) 
    {
        FILE *upcomingFile = fopen(mUpcomingFile, "w");
        if(upcomingFile)
        {
            mElementCount = 0;
        
            if (!::strcmp(mPlayMode, "weighted_random")) 
                qtss_fprintf(upcomingFile,"#random play - upcoming list not supported\n");
            else
            {   qtss_fprintf(upcomingFile,"*PLAY-LIST*\n");
                ShowPlaylistElements(insertPicker,upcomingFile);
                ShowPlaylistElements(picker,upcomingFile);
                if (    picker->GetNumMovies() == 0 
                        && !picker->mStopFlag 
                        && 0 != ::strcmp(mPlayMode, "sequential") 
                    )
                {   picker->CleanList();
                    PopulatePickerFromFile(picker,mPlayListPath,"",NULL);
                    ShowPlaylistElements(picker,upcomingFile);
                    mTempPicker->CleanList();
                    PopulatePickerFromFile(mTempPicker,mPlayListPath,"",NULL);
                }
                
                if  (   mElementCount <= mUpcomingSongsListSize 
                        && 0 == ::strcmp(mPlayMode, "sequential_looped")
                    )
                {   if (mTempPicker->GetNumMovies() == 0)
                    {   mTempPicker->CleanList();
                        PopulatePickerFromFile(mTempPicker,mPlayListPath,"",NULL);
                    }
                    //sElementCount can be zero if the playlist contains no paths to valid files
                    while ( (mElementCount != 0) && mElementCount <= mUpcomingSongsListSize )
                        ShowPlaylistElements(mTempPicker,upcomingFile);
                }
            }
            fclose(upcomingFile);
        }   
    }
    else
    {   
        if (    picker->GetNumMovies() == 0 
                && !picker->mStopFlag 
                && ::strcmp(mPlayMode, "sequential") 
            )
        {   picker->CleanList();
            PopulatePickerFromFile(picker,mPlayListPath,"",NULL);
        }       
    }
}