int main(int argc, char** argv) { int listenfd; int connfd; FILE* fp; set_options(argc, argv); /* Open the file early, so we may fail early. * To note that if no file is specified, stdin will be read instead */ if (strcmp(g_filename, "")) { if ((fp = fopen(g_filename, "r")) == NULL) { printerr("File not found"); return 1; } } else { fp = stdin; } /* Start listening */ listenfd = startup_server(g_port); if (listenfd < 0) return abs(listenfd); /* Start waiting for connections */ connfd = waitconn(listenfd); if (connfd < 0) return abs(connfd); /* Send stuff */ send_headers(connfd); send_file(connfd, fp); /* Cleanup */ fclose(fp); close(connfd); close(listenfd); return 0; }
/* * Main program */ int main(int argc, char *argv[]) { int i = 0; int ret = 0; struct sockaddr_in client_address; int client_sockfd = 0; pthread_t threads[MAX_THREADS]; /* Parse commandline args */ params = malloc(sizeof(cmd_params)); ret = parse_cmd_args(&argc, argv); if (params->help) { display_help_page(); exit(0); } if (params->version) { display_version_info(); exit(0); } if (ret < 0) { if (ret == -2) logline(LOG_ERROR, "Error: Invalid port range specified (-p)"); if (ret == -6) logline(LOG_ERROR, "Error: Invalid log level option specified (-l)."); logline(LOG_ERROR, "Use the -h option if you need help."); exit(ret); } /* Set log level */ switch (params->loglevel) { case 1: set_loglevel(LOG_ERROR); break; case 2: set_loglevel(LOG_INFO); break; case 3: set_loglevel(LOG_DEBUG); break; default: set_loglevel(LOG_ERROR); } /* Setup signal handler */ signal(SIGINT, shutdown_server); signal(SIGTERM, shutdown_server); /* Show banner and stuff */ show_gnu_banner(); /* Startup the server listener */ if (startup_server() < 0) { logline(LOG_ERROR, "Error during server startup. Please consult debug log for details."); exit(-1); } /* Post ready message */ logline(LOG_INFO, "Server listening on %s, port %d", params->ip, params->port); switch (params->loglevel) { case LOG_ERROR: logline(LOG_INFO, "Log level set to ERROR"); break; case LOG_INFO: logline(LOG_INFO, "Log level set to INFO"); break; case LOG_DEBUG: logline(LOG_INFO, "Log level set to DEBUG"); break; default: logline(LOG_INFO, "Unknown log level specified"); break; } /* Handle connections */ while (1) { logline(LOG_INFO, "Waiting for incoming connection..."); /* Accept a client connection */ client_len = sizeof(client_address); client_sockfd = accept(server_sockfd, (struct sockaddr *)&client_address, (socklen_t *)&client_len); if (client_sockfd > 0) { logline(LOG_INFO, "Server accepted new connection on socket id %d", client_sockfd); /* A connection between a client and the server has been established. * Now create a new thread and handover the client_sockfd */ pthread_mutex_lock(&curr_thread_count_mutex); if (curr_thread_count < MAX_THREADS) { /* Prepare client infos in handy structure */ client_info *ci = (client_info *)malloc(sizeof(client_info)); ci->sockfd = client_sockfd; ci->address = client_address; sprintf(ci->nickname, "anonymous_%d", client_sockfd); /* Add client info to linked list */ llist_insert(&list_start, ci); llist_show(&list_start); /* Pass client info and invoke new thread */ ret = pthread_create(&threads[curr_thread_count], NULL, (void *)&proc_client, (void *)&client_sockfd); /* only pass socket id ? */ if (ret == 0) { pthread_detach(threads[curr_thread_count]); curr_thread_count++; /* Notify server and clients */ logline(LOG_INFO, "User %s joined the chat.", ci->nickname); logline(LOG_DEBUG, "main(): Connections used: %d of %d", curr_thread_count, MAX_THREADS); } else { free(ci); close(client_sockfd); } } else { logline(LOG_ERROR, "Max. connections reached. Connection limit is %d. Connection dropped.", MAX_THREADS); close(client_sockfd); } pthread_mutex_unlock(&curr_thread_count_mutex); } else { /* Connection could not be established. Post error and exit. */ perror(strerror(errno)); exit(-3); } } free(params); return 0; }
static KWBoolean master( const char recvGrade, const KWBoolean overrideGrade, const KWBoolean runUUXQT ) { CONN_STATE m_state = CONN_INITSTAT; CONN_STATE old_state = CONN_EXIT; char sendGrade = ALL_GRADES; KWBoolean contacted = KWFalse; KWBoolean needUUXQT = KWFalse; /*--------------------------------------------------------------------*/ /* Validate the system to call */ /*--------------------------------------------------------------------*/ if ( !equal( Rmtname, "any" ) && !equal( Rmtname, "all" )) { if ( checkreal( Rmtname ) == NULL ) { printmsg(0,"%s is not \"any\", \"all\", or a valid system to call", Rmtname); printmsg(0,"Run UUNAME for a list of callable systems"); panic(); } } if ((fsys = FOPEN(E_systems, "r",TEXT_MODE)) == nil(FILE)) { printerr(E_systems); panic(); } setvbuf( fsys, NULL, _IONBF, 0); while (m_state != CONN_EXIT ) { printmsg(old_state == m_state ? 10 : 4 , "M state = %c", m_state); old_state = m_state; switch (m_state) { case CONN_INITSTAT: HostStatus(); m_state = CONN_INITIALIZE; break; case CONN_INITIALIZE: setTitle("Determining system to call"); hostp = NULL; if ( locked ) UnlockSystem(); m_state = getsystem(recvGrade); if ( hostp != NULL ) remote_stats.hstatus = hostp->status.hstatus; break; case CONN_CHECKTIME: sendGrade = checktime(flds[FLD_CCTIME]); if ( (overrideGrade && sendGrade) || callnow ) sendGrade = recvGrade; if ( !CallWindow( sendGrade )) m_state = CONN_INITIALIZE; else if ( LockSystem( hostp->hostname , B_UUCICO)) { dialed = KWTrue; time(&hostp->status.ltime); /* Save time of last attempt to call */ hostp->status.hstatus = HS_AUTODIAL; m_state = CONN_MODEM; } else m_state = CONN_INITIALIZE; break; case CONN_NOGRADE: CallWindow( 0 ); /* Simply to update last time called */ m_state = CONN_INITIALIZE; break; case CONN_MODEM: if (getmodem(flds[FLD_TYPE])) m_state = CONN_DIALOUT; else { hostp->status.hstatus = HS_INVALID_DEVICE; m_state = CONN_INITIALIZE; } break; case CONN_DIALOUT: if ( !IsNetwork() ) { setTitle( "Allocating modem on %s", M_device); if (suspend_other(KWTrue, M_device ) < 0 ) { hostp->status.hstatus = HS_NODEVICE; suspend_other(KWFalse, M_device ); /* Resume modem */ m_state = CONN_INITIALIZE; /* Try next system */ break; } } /* if */ setTitle( "Calling %s on %s", rmtname, M_device ); m_state = callup( ); break; case CONN_PROTOCOL: m_state = startup_server( (char) (bflag[F_SYMMETRICGRADES] ? sendGrade : recvGrade) ); break; case CONN_SERVER: if (bflag[F_MULTITASK]) dcupdate(); setTitle("%s connected to %s", securep->myname, hostp->via ); m_state = process( POLL_ACTIVE, sendGrade ); contacted = KWTrue; break; case CONN_TERMINATE: m_state = sysend(); if ( hostp != NULL ) { if (hostp->status.hstatus == HS_INPROGRESS) hostp->status.hstatus = HS_CALL_FAILED; dcstats(); needUUXQT = KWTrue; } break; case CONN_TIMESET: contacted = KWTrue; m_state = CONN_DROPLINE; break; case CONN_DROPLINE: setTitle("Closing port %s", M_device); shutDown(); UnlockSystem(); setTitle("Not connected"); m_state = CONN_CLEANUP; break; case CONN_CLEANUP: if ( runUUXQT && needUUXQT ) m_state = CONN_UUXQT; else m_state = CONN_INITIALIZE; break; case CONN_UUXQT: { char buf[100]; sprintf( buf, "-s %s -x %d", rmtname, debuglevel ); copylog(); execute( "uuxqt", buf, NULL, NULL, KWFalse, KWFalse ); openlog(NULL); } needUUXQT = KWFalse; m_state = CONN_INITIALIZE; break; case CONN_EXIT: break; default: printmsg(0,"dcpmain: Unknown master state = %c",m_state ); panic(); break; } /* switch */ if ( terminate_processing ) m_state = CONN_EXIT; } /* while */ setTitle("Exiting"); fclose(fsys); return contacted; } /* master */