⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lwld.c

📁 g729 coding ipaddressing
💻 C
📖 第 1 页 / 共 4 页
字号:
		else if (bcmp(p + 8, "SFms", 4) == 0) {
#ifdef HEXDUMP
		    if (hexdump) {
			fprintf(stderr, "%s: %d bytes sent to socket.\n",
				prog, messagel);
			xd(stderr, message, messagel, TRUE);
		    }
#endif
		    if (prolix) {
			printf("%s: %s server message request\n", prog, inet_ntoa(from.sin_addr));
		    }
		    if (send(csock, message, messagel, 0) < 0) {
			perror("sending server message");
		    }
		}
		break;

	    default:
		if (debugging || verbose) {
		    fprintf(stderr, "Bogus payload type %d\n",
#ifdef RationalWorld
				  rp->common.pt
#else
				  ((unsigned char *) rp)[1]
#endif
			   );
		}
		break;
	}
    }
    close(csock);
}

#ifdef THREADS

/*  Thread processing functions.  */

#ifdef DBTHREAD

/*  EDIT_THREAD  --  Edit information about a service thread from
		     its packet in the ballOstring chain.  */

static char *edit_thread(b)
  struct ballOstring *b;
{
    static char s[80];

    sprintf(s, "%d %s %s", b->thread, inet_ntoa(b->site), ctime(&b->startTime));
    s[strlen(s) - 1] = 0;
    return s;
}
#endif

/*  TIMEOUT_THREAD  --	Handle timeout of sites that go away without
			sending a "Bye" message.  */

static void *timeout_thread(arg)
  void *arg;
{
    long ct;
    struct ballOstring *b;

#ifdef DBTHREAD
fprintf(stderr, "Timeout thread running\n");
#endif
    while (TRUE) {
	sleep(120);		      /* Wait for next awake interval */
	time(&ct);
#ifdef DBTHREAD
fprintf(stderr, "Timeout thread scanning connections\n");
#endif
	Lock(bsLock);
	b = bshead.next;
	while (b != &bshead) {
#ifdef DBTHREAD
fprintf(stderr, "    Thread %s\n", edit_thread(b));
#endif
	    if ((b->startTime + ServiceThreadTimeout) < ct) {
#ifdef DBTHREAD
fprintf(stderr, "		Kill sent due to timeout.\n");
#endif
		pthread_kill(b->thread, SIGUSR1);
	    }
	    b = b->next;
	}
	Unlock(bsLock);
	release();
    }
}

/*  HTML_THREAD  --  Update the HTML database(s) if something has
		     changed since the last time.  */

static void *html_thread(arg)
  void *arg;
{
#ifdef DBTHREAD
fprintf(stderr, "HTML update thread running\n");
#endif
    while (TRUE) {
#ifdef DBTHREAD
fprintf(stderr, "HTML update thread examining connections\n");
#endif
	updHTML();

	/* In the threaded version, consider every 15 seconds as
	   equivalent to "immediate update on every change".
	   We could accomplish immediate update with a
	   semaphore signalling mechanism, but that would
	   cause the threaded and non-threaded versions to
	   diverge much more.  Besides, nobody runs in immediate
	   update mode anyway, as far as I can determine. */

	sleep((unsigned int) (htmlTime <= 0 ? 15 : htmlTime));
    }
}

/*  SERVICE_THREAD  --	Thread to process user packet.	One of
			these is created every time a connection is
			accepted.  */

struct service_arg {
    int sa_csock;
    struct sockaddr_in sa_from;
    struct ballOstring *sa_b;
};

static void killserv()
{
    pthread_t us = pthread_self();
    struct ballOstring *b;
#ifdef DBTHREAD
fprintf(stderr, "Gaaaak!!!  Killserv received by thread %d.\n", us);
#endif

    /* We're being killed by the timeout handler.  Search for
       our entry in the ballOstring chain. */

    Lock(bsLock);
    b = bshead.next;
    while (b != &bshead) {
	if (b->thread == us) {

	    /* Dechain from active thread list. */

	    b->prev->next = b->next;
	    b->next->prev = b->prev;
	    break;
	}
	b = b->next;
    }
    Unlock(bsLock);
    if (b != &bshead) {
	if (b->sa->sa_csock != -1) {
	    close(b->sa->sa_csock);
	}
#ifdef DBTHREAD
fprintf(stderr, "Thread killed by timeout: %s\n", edit_thread(b));
#endif
	free(b->sa);
	free(b);
	pthread_exit(NULL);
    } else {
#ifdef DBTHREAD
fprintf(stderr, "Oops!!!  Timeout kill request to thread %d, not in ballOstring.\n", us);
#endif
    }
}

static void *service_thread(arg)
  void *arg;
{
    struct service_arg *sa = arg;

#ifdef DBTHREAD
fprintf(stderr, "Server thread %d for host %s launched\n", pthread_self(), inet_ntoa(sa->sa_from.sin_addr));
#endif
    signal(SIGUSR1, killserv);	       /* Set signal to handle timeout */
    sa->sa_b->thread = pthread_self();
    servicePacket(sa->sa_csock, sa->sa_from);
#ifdef DBTHREAD
fprintf(stderr, "Server thread %d for host %s exiting\n", pthread_self(), inet_ntoa(sa->sa_from.sin_addr));
#endif

    /* Dechain this thread's item from the ballOstring list. */

#ifdef DBTHREAD
fprintf(stderr, "Thread exiting: %s\n", edit_thread(sa->sa_b));
#endif
    Lock(bsLock);
    sa->sa_b->prev->next = sa->sa_b->next;
    sa->sa_b->next->prev = sa->sa_b->prev;
    free(sa->sa_b);
    Unlock(bsLock);
    free(sa);			      /* Release request packet */
    pthread_exit(NULL);
}
#endif

/*  Main program.  */

main(argc, argv)
  int argc;
  char *argv[];
{
    int i, length;
    struct sockaddr_in name;
#ifdef THREADS
    pthread_t timeout_tid, html_tid;

    pthread_attr_init(&detached);
    pthread_attr_setdetachstate(&detached, PTHREAD_CREATE_DETACHED);
    pthread_attr_setstacksize(&detached, (size_t) 65536);
    bshead.next = bshead.prev = &bshead;
#endif

    /*	Process command line options.  */

    prog = prog_name(argv[0]);

#ifdef PRUNEFACE
    {	/* Interctive debugging of text pruning logic. */
	char s[132], p[132];
	char *zap;

	while (TRUE) {
	    printf("--> ");
	    if (fgets(s, sizeof s, stdin) == NULL) {
		break;
	    }
	    zap = p;
	    add_sdes_item(1, s, &zap);
	    *zap = 0;
	    printf(    "\"%s\"\n", p + 2);
	}
	exit(0);
    }
#endif

    for (i = 1; i < argc; i++) {
	char *op, opt;

	op = argv[i];
	if (*op == '-') {
	    opt = *(++op);
	    if (islower(opt)) {
		opt = toupper(opt);
	    }

	    switch (opt) {

		case 'D':	      /* -D  --  Debug output to stderr */
		    debugging = TRUE;
		    break;

		case 'F':	      /* -Fserv,...  --  Forward to listed servers. */
		    forwardList(op + 1);
		    break;

		case 'H':	      /* -Hname  --  HTML file name base path */
		    htmlFile = op + 1;
		    break;

		case 'I':	      /* -Isec	--  Interval between HTML updates */
		    htmlTime = atoi(op + 1);
		    break;

		case 'M':	      /* -Mfile  --  Load server message from file */
		    {
			FILE *fp = fopen(op + 1, "r");
			long fl;

			if (fp == NULL) {
			    fprintf(stderr, "%s: can't open server message file %s\n", prog, op + 1);
			    return 2;
			}
			fseek(fp, 0L, 2);
			fl = ftell(fp);
			rewind(fp);
			messagel = ((int) fl) + 13;
			message = (char *) malloc(messagel);
			if (message != NULL) {
			    rtcp_t *rp = (rtcp_t *) message;

#ifdef RationalWorld
			    rp->common.version = RTP_VERSION;
			    rp->common.p = 0;
			    rp->common.count = 1;
			    rp->common.pt = RTCP_APP;
#else
			    *((short *) rp) = htons((RTP_VERSION << 14) |
						    RTCP_APP | (1 << 8));
#endif
			    rp->r.sdes.src = 0;
			    bcopy("SFmr", message + 8, 4);
			    fread(message + 12, (int) fl, 1, fp);
			    message[messagel - 1] = 0;
			}
			fclose(fp);
		    }
		    break;

		case 'P':	      /* -Pport  --  Port to listen on */
		    lwlport = atoi(op + 1);
		    break;

		case 'U':	      /* -U  --  Print usage information */
		case '?':	      /* -?  --  Print usage information */
		    usage();
		    return 0;

		case 'V':	      /*  -V  -- Show connects/disconnects */
		    verbose = TRUE;
		    if (op[1] == 'v' || op[1] == 'V') {
			prolix = TRUE;
		    }
		    break;

#ifdef HEXDUMP
		case 'X':	      /* -X  --  Dump packets in hex */
		    hexdump = TRUE;
		    break;
#endif

		case 'Z':	      /* -Zname  --  HTML private file name base path */
		    htmlPrivateFile = op + 1;
		    break;
	    }
	} else {
	    usage();
	    return 2;
	}
    }

    /* If no server message has been loaded, create a void one. */

    if (message == NULL) {
	rtcp_t *rp;

	messagel = 13;
	message = (char *) malloc(messagel);
	rp = (rtcp_t *) message;

#ifdef RationalWorld
	rp->common.version = RTP_VERSION;
	rp->common.p = 0;
	rp->common.count = 1;
	rp->common.pt = RTCP_APP;
#else
	*((short *) rp) = htons((RTP_VERSION << 14) | RTCP_APP | (1 << 8));
#endif
	rp->r.sdes.src = 0;
	bcopy("SFmr", message + 8, 4);
	message[messagel - 1] = 0;
    }


    /* Create the socket from which to read */

    sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock < 0) {
	perror("opening stream socket");
	return 1;
    }

    /* Create name with wildcards. */

    name.sin_family = AF_INET;
    name.sin_addr.s_addr = INADDR_ANY;
    name.sin_port = htons(lwlport);
    if (bind(sock, (struct sockaddr *) &name, sizeof name) < 0) {
	perror("binding stream socket");
	return 1;
    }

    signal(SIGHUP, exiting);	      /* Set signal to handle termination */
    signal(SIGINT, exiting);	      /* Set signal to handle termination */
    signal(SIGTERM, exiting);	      /* Set signal to handle termination */

    signal(SIGPIPE, plumber);	      /* Catch "broken pipe" signals from disconnects */

    if (listen(sock, 25) < 0) {
	perror("calling listen for socket");
    }

    /* Find assigned port value and print it. */

    length = sizeof(name);
    if (getsockname(sock, (struct sockaddr *) &name, &length) < 0) {
	perror("getting socket name");
	return 1;
    }
#ifdef SHOW_SOCKET
    fprintf(stderr, "%s: socket port #%d\n", prog, ntohs(name.sin_port));
#endif

#ifdef THREADS
    pthread_create(&timeout_tid, &detached, timeout_thread, NULL);
    if (htmlFile != NULL || htmlPrivateFile != NULL) {
	pthread_create(&html_tid, &detached, html_thread, NULL);
    }
#else
    signal(SIGALRM, release);	      /* Set signal to handle timeout */
    alarm(TockTock);		      /* Set alarm clock to purge idle hosts */
#endif
    changed();			      /* Create initial HTML file */
    setlinebuf(stdout); 	      /* Set stdout to line buffering for log */

    /* Process requests from the socket. */

    while (TRUE) {
	int csock;
	struct sockaddr_in from;      /* Sending host address */
	int fromlen;		      /* Length of sending host address */
#ifdef THREADS
	struct service_arg *sap;
	pthread_t service_tid;
#endif

	errno = 0;
	do {
	    fromlen = sizeof from;
	    csock = accept(sock, (struct sockaddr *) &from, &fromlen);
#ifdef DBTHREAD
fprintf(stderr, "Accept %d\n", csock);
#endif
	    if (csock >= 0) {
		break;
	    }
	} while (errno == EINTR);
	if (csock < 0) {
	    perror("accepting connection to socket");
	    continue;
	}
	if (prolix) {
	    printf("%s: %s accept\n", prog, inet_ntoa(from.sin_addr));
	}
#ifdef THREADS
	sap = (struct service_arg *) malloc(sizeof(struct service_arg));
	if (sap != NULL) {
	    struct ballOstring *b;

	    sap->sa_csock = csock;
	    sap->sa_from = from;
	    b = (struct ballOstring *) malloc(sizeof(struct ballOstring));
	    if (b != NULL) {
		sap->sa_b = b;
		b->sa = sap;
		Lock(bsLock);
		b->next = bshead.next;
		b->prev = &bshead;
		bshead.next = b;
		b->next->prev = b;
		b->thread = -1;
		time(&(b->startTime));
		b->site = from.sin_addr;
		Unlock(bsLock);
		if (pthread_create(&service_tid, &detached, service_thread, sap) != 0) {
		    fprintf(stderr, "%s: Cannot launch server thread for request from %s: %s",
			prog, inet_ntoa(from.sin_addr), strerror(errno));
		    close(csock);
		}
	    } else {
		free(sap);
		fprintf(stderr, "Unable to allocate memory for ballOstring packet.\n");
		close(csock);
	    }
	} else {
	    fprintf(stderr, "Unable to allocate memory for service_arg packet.\n");
	    close(csock);
	}
#else
	servicePacket(csock, from);
#endif
    }
#ifdef MEANS_OF_EXIT
    close(sock);
    return 0;
#endif
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -