summaryrefslogtreecommitdiff
path: root/mit-pthreads/bin/finger/finger.c
diff options
context:
space:
mode:
Diffstat (limited to 'mit-pthreads/bin/finger/finger.c')
-rwxr-xr-xmit-pthreads/bin/finger/finger.c231
1 files changed, 231 insertions, 0 deletions
diff --git a/mit-pthreads/bin/finger/finger.c b/mit-pthreads/bin/finger/finger.c
new file mode 100755
index 00000000000..33b3011e8bb
--- /dev/null
+++ b/mit-pthreads/bin/finger/finger.c
@@ -0,0 +1,231 @@
+/* ==== finger.c ============================================================
+ * Copyright (c) 1993 by Chris Provenzano, proven@athena.mit.edu
+ *
+ * Copyright (c) 1989 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Tony Nardo of the Johns Hopkins University/Applied Physics Lab.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Chris Provenzano,
+ * the University of California, Berkeley and its contributors.
+ * 4. Neither the name of Chris Provenzano, the University nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY CHRIS PROVENZANO, THE REGENTS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 1.00 93/08/26 proven
+ * -Pthread redesign of this file.
+ *
+ * 1.10 95/02/11 proven
+ * -Now that gethostbyname works ....
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1989 The Regents of the University of California.\n\
+ @(#) Copyright (c) 1993, 1995 Chris Provenzano.\n\
+ @(#) Copyright (c) 1995 Greg Stark.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#include <pthreadutil.h>
+#include <sys/param.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+void *netfinger();
+
+void usage(int eval)
+{
+ fprintf(stderr,
+ "usage: finger [-lps] [-c <net_count>] [-t|T <timeout>] [-f <filename>] [login ...]\n");
+ exit(eval);
+}
+
+/*
+ * These globals are set initialy and then are only read.
+ * They do not need mutexes.
+ */
+int thread_time = 0, program_timeout = 0, lflag = 0;
+pthread_tad_t parse_file_tad;
+pthread_tad_t netfinger_tad;
+
+void * timeout_thread(void * arg)
+{
+ sleep(program_timeout);
+ exit(0);
+}
+
+void * signal_thread(void * arg)
+{
+ int sig;
+ sigset_t program_signals;
+ sigemptyset(&program_signals);
+ sigaddset(&program_signals, SIGINT);
+ sigwait(&program_signals, &sig);
+ exit(0);
+}
+
+#ifndef MAXHOSTNAMELEN
+#define MAXHOSTNAMELEN 64
+#endif
+
+void * parse_file(void * arg)
+{
+ char hostname[MAXHOSTNAMELEN];
+ char * filename = arg;
+ pthread_atexit_t atexit_id;
+ pthread_attr_t attr;
+ pthread_t thread_id;
+ char * thread_arg;
+ FILE * fp;
+ int len;
+
+ netsetupwait();
+
+ /* Parse the file and create a thread per connection */
+ if ((fp = fopen(filename, "r")) == NULL) {
+ fprintf(stderr, "Can't open file %s\n", filename);
+ pthread_exit(NULL);
+ }
+ pthread_atexit_add(&atexit_id, fclose_nrv, fp);
+
+ if (pthread_attr_init(&attr)) {
+ fprintf(stderr, "Error: Can't initialize thread attributes\n");
+ exit(2);
+ }
+ pthread_atexit_add(&atexit_id, pthread_attr_destroy_nrv, &attr);
+
+ while (fgets(hostname, MAXHOSTNAMELEN, fp)) {
+ if ((thread_arg = (char *)malloc(len = strlen(hostname))) == NULL) {
+ fprintf(stderr, "Error: out of memory\n");
+ exit(2);
+ }
+
+ hostname[len - 1] = '\0';
+ strcpy(thread_arg, hostname);
+ pthread_attr_setcleanup(&attr, free, thread_arg);
+ if (pthread_tad_create(&netfinger_tad, &thread_id, NULL,
+ netfinger, thread_arg)) {
+ fprintf(stderr, "Error: pthread_tad_create() netfinger_tad.\n");
+ exit(2);
+ }
+ }
+ pthread_exit(NULL);
+}
+
+main(int argc, char **argv)
+{
+ pthread_atexit_t atexit_id;
+ pthread_t thread_id;
+ int max_count = 0;
+ char ch;
+
+ /* getopt variables */
+ extern char *optarg;
+ extern int optind;
+
+ /* Setup tad for parse_file() threads */
+ if (pthread_tad_init(&parse_file_tad, max_count)) {
+ fprintf(stderr,"Error: couldn't create parse_file() TAD.\n");
+ exit(1);
+ }
+
+ while ((ch = getopt(argc, argv, "c:f:t:T:ls")) != (char)EOF)
+ switch(ch) {
+ case 't': /* Time to let each thread run */
+ if ((thread_time = atoi(optarg)) <= 0) {
+ usage(1);
+ }
+ break;
+ case 'T': /* Time to let entire program run */
+ if ((program_timeout = atoi(optarg)) <= 0) {
+ usage(1);
+ }
+ break;
+ case 'f': /* Parse file for list of places to finger */
+ if (pthread_tad_create(&parse_file_tad, &thread_id, NULL,
+ parse_file, optarg)) {
+ fprintf(stderr,"Error: pthread_tad_create() parse_file_tad.\n");
+ exit(1);
+ }
+ break;
+ case 'c':
+ max_count = atoi(optarg);
+ break;
+ case 'l': /* long format */
+ lflag = 1;
+ break;
+ case 's': /* short format */
+ lflag = 0;
+ break;
+ case '?':
+ usage(0);
+ default:
+ usage(1);
+ }
+
+ /* The rest of the argumants are hosts */
+ argc -= optind;
+ argv += optind;
+
+ /* Setup timeout thread, if there is one */
+ if (program_timeout) {
+ if (pthread_create(&thread_id, NULL, timeout_thread, NULL)) {
+ fprintf(stderr,"Error: couldn't create program_timeout() thread\n");
+ exit(1);
+ }
+ }
+
+ /* Setup cleanup thread for signals */
+ if (pthread_create(&thread_id, NULL, signal_thread, NULL)) {
+ fprintf(stderr,"Error: couldn't create signal_timeout() thread\n");
+ exit(1);
+ }
+
+ /* Setup tad for netfinger() threads */
+ if (pthread_tad_init(&netfinger_tad, max_count)) {
+ fprintf(stderr,"Error: couldn't create netfinger() TAD.\n");
+ exit(1);
+ }
+
+ /* Setup the net and let everyone run */
+ netsetup();
+
+ while (*argv) {
+ if (pthread_tad_create(&netfinger_tad, &thread_id, NULL,
+ netfinger, *argv)) {
+ fprintf(stderr, "Error: pthread_tad_create() netfinger_tad.\n");
+ exit(2);
+ }
+ argv++;
+ }
+ pthread_tad_wait(&parse_file_tad, 0);
+ pthread_tad_wait(&netfinger_tad, 0);
+ exit(0);
+}
+