int cli_main( uint16_t port ) { struct sockaddr_in addr; struct sockaddr client_addr; int bindfd; int clientfd; cli_client_t* client; #ifdef _STANDALONE_CLI_ unsigned sock_len; #else int sock_len; #endif sock_len = sizeof(struct sockaddr); pthread_mutex_init( &parser_lock, NULL ); cli_init(); cli_parser_init(); cli_scanner_init(); /* create a socket to listen for connections on */ bindfd = socket( AF_INET, SOCK_STREAM, 0 ); if( bindfd == -1 ) { fprintf( stderr, "Error: unable to create a IPv4 TCP socket" ); return CLI_ERROR; } /* bind to the requested port */ addr.sin_port = htons(port); addr.sin_addr.s_addr = 0; memset(&(addr.sin_zero), 0, sizeof(addr.sin_zero)); if( bind(bindfd, (struct sockaddr*)&addr, sizeof(struct sockaddr)) ) { fprintf( stderr, "Error: CLI unable to bind to port %u", port ); return CLI_ERROR; } /* listen for clients */ listen( bindfd, 10 ); #ifndef _STANDALONE_CLI_ /* listen locally too */ cli_local_init( port ); #endif while( !cli_is_time_to_shutdown() ) { /* wait for a new client */ clientfd = accept(bindfd, &client_addr, &sock_len); if( clientfd == - 1 ) { if( errno == EINTR ) { /* Interrupt received, going back to accept() */ continue; } /* some error */ perror( "accept() failed" ); continue; } /* accepted a new connection client */ /* create a client record */ client = malloc_or_die( sizeof(cli_client_t) ); client->fd = clientfd; search_state_init( &client->state, CLI_INIT_BUF, CLI_MAX_BUF ); /* spawn a new thread to handle the client */ make_thread( cli_client_handler_main, client ); } return CLI_SHUTDOWN; }
// Parse commandline settings static inline void parse_cli_settings(int argc, const char* argv[]) { // runtime os version detection SInt32 osMajorVersion, osMinorVersion; if (!(Gestalt(gestaltSystemVersionMajor, &osMajorVersion) == noErr)) { osMajorVersion = 0; } if (!(Gestalt(gestaltSystemVersionMinor, &osMinorVersion) == noErr)) { osMinorVersion = 0; } if ((osMajorVersion == 10) & (osMinorVersion < 5)) { fprintf(stderr, "The FSEvents API is unavailable on this version of macos!\n"); exit(EXIT_FAILURE); } struct cli_info args_info; cli_parser_init(&args_info); if (cli_parser(argc, argv, &args_info) != 0) { exit(EXIT_FAILURE); } config.paths = CFArrayCreateMutable(NULL, (CFIndex)0, &kCFTypeArrayCallBacks); config.sinceWhen = args_info.since_when_arg; config.latency = args_info.latency_arg; config.format = args_info.format_arg; if (args_info.no_defer_flag) { config.flags |= kFSEventStreamCreateFlagNoDefer; } if (args_info.watch_root_flag) { config.flags |= kFSEventStreamCreateFlagWatchRoot; } if (args_info.ignore_self_flag) { if ((osMajorVersion == 10) & (osMinorVersion >= 6)) { config.flags |= kFSEventStreamCreateFlagIgnoreSelf; } else { fprintf(stderr, "MacOSX 10.6 or later is required for --ignore-self\n"); exit(EXIT_FAILURE); } } if (args_info.file_events_flag) { if ((osMajorVersion == 10) & (osMinorVersion >= 7)) { config.flags |= kFSEventStreamCreateFlagFileEvents; } else { fprintf(stderr, "MacOSX 10.7 or later required for --file-events\n"); exit(EXIT_FAILURE); } } if (args_info.inputs_num == 0) { append_path("."); } else { for (unsigned int i=0; i < args_info.inputs_num; ++i) { append_path(args_info.inputs[i]); } } cli_parser_free(&args_info); #ifdef DEBUG fprintf(stderr, "config.sinceWhen %llu\n", config.sinceWhen); fprintf(stderr, "config.latency %f\n", config.latency); // STFU clang #if defined(__LP64__) fprintf(stderr, "config.flags %#.8x\n", config.flags); #else fprintf(stderr, "config.flags %#.8lx\n", config.flags); #endif FLAG_CHECK_STDERR(config.flags, kFSEventStreamCreateFlagUseCFTypes, " Using CF instead of C types"); FLAG_CHECK_STDERR(config.flags, kFSEventStreamCreateFlagNoDefer, " NoDefer latency modifier enabled"); FLAG_CHECK_STDERR(config.flags, kFSEventStreamCreateFlagWatchRoot, " WatchRoot notifications enabled"); FLAG_CHECK_STDERR(config.flags, kFSEventStreamCreateFlagIgnoreSelf, " IgnoreSelf enabled"); FLAG_CHECK_STDERR(config.flags, kFSEventStreamCreateFlagFileEvents, " FileEvents enabled"); fprintf(stderr, "config.paths\n"); long numpaths = CFArrayGetCount(config.paths); for (long i = 0; i < numpaths; i++) { char path[PATH_MAX]; CFStringGetCString(CFArrayGetValueAtIndex(config.paths, i), path, PATH_MAX, kCFStringEncodingUTF8); fprintf(stderr, " %s\n", path); } fprintf(stderr, "\n"); #endif }