static char * unquote_parse( char * raw_string ) { if ( raw_string == NULL ) { return NULL ; } switch ( raw_string[0] ) { case '"': case '\'': if ( raw_string[1] == '\0' ) { owfree( raw_string ) ; return owstrdup("") ; } else { char * unquoted = owstrdup( raw_string+1 ) ; char * unquoted_end = unquoted + strlen(unquoted) -1 ; if ( unquoted_end[0] == raw_string[0] ) { unquoted_end[0] = '\0' ; } owfree( raw_string ) ; return unquoted ; } break ; default: return raw_string ; } }
static struct BrowseStruct *Browse_Struct_Create(const char *name, const char *type, const char *domain) { struct BrowseStruct *browse_struct = owmalloc(sizeof(struct BrowseStruct)); if ( browse_struct == NULL ) { return NULL ; } browse_struct->name = ( name != NULL ) ? owstrdup(name) : NULL; browse_struct->type = ( type != NULL ) ? owstrdup(type) : NULL; browse_struct->domain = ( domain != NULL ) ? owstrdup(domain) : NULL; return browse_struct; }
static char * trim_parse( char * raw_string ) { char * start_position ; char * end_position ; char * return_string ; // trim off preamble whitespace for ( start_position = raw_string ; start_position[0] ; ++ start_position ) { switch ( start_position[0] ) { case ' ': case '\t': // ignore these characters continue ; case '\n': case '\r': // end of the line -- empty string return owfree( raw_string ); return owstrdup("") ; default: break ; } // getting here means a valid character found break ; } // delete old string and use new copy starting at first non whitespace position return_string = owstrdup ( start_position ) ; owfree( raw_string ) ; // trim off for ( end_position = return_string + strlen( return_string ) ; end_position >= return_string ; -- end_position ) { switch ( end_position[0] ) { case ' ': case '\0': case '\r': case '\n': case '\t': // ignorable end char -- make null end_position[0] = '\0' ; continue ; default: // good char break ; } // getting here means a valid character found break ; } return return_string ; }
GOOD_OR_BAD Detail_Add( const char *arg ) { char * arg_copy = owstrdup( arg ) ; char * next_p = arg_copy ; while ( next_p != NULL ) { BYTE sn[SERIAL_NUMBER_SIZE] ; BYTE length[SERIAL_NUMBER_SIZE] ; char * this_p = strsep( &next_p, " ," ) ; length[0] = SerialNumber_length( this_p, sn ) ; if ( length[0] > 0 ) { ++ DD.details ; switch (Globals.daemon_status) { case e_daemon_want_bg: case e_daemon_unknown: Globals.daemon_status = e_daemon_fg ; break ; default: break ; } DirblobAdd( sn, &(DD.sn) ) ; DirblobAdd( length, &(DD.length) ) ; } } return gbGOOD ; }
/* It does call lower level functions for higher ones, which of course is pointless since the lower ones don't work either */ GOOD_OR_BAD BadAdapter_detect(struct port_in *pin) { struct connection_in * in = pin->first ; pin->type = ct_none ; pin->file_descriptor = FILE_DESCRIPTOR_BAD ; in->Adapter = adapter_Bad; /* OWFS assigned value */ in->iroutines.reset = BadAdapter_reset; in->iroutines.next_both = NO_NEXT_BOTH_ROUTINE; in->iroutines.PowerByte = NO_POWERBYTE_ROUTINE; in->iroutines.ProgramPulse = NO_PROGRAMPULSE_ROUTINE; in->iroutines.sendback_data = NO_SENDBACKDATA_ROUTINE; in->iroutines.sendback_bits = BadAdapter_sendback_bits; in->iroutines.select = NO_SELECT_ROUTINE; in->iroutines.select_and_sendback = NO_SELECTANDSENDBACK_ROUTINE; in->iroutines.set_config = NO_SET_CONFIG_ROUTINE; in->iroutines.get_config = NO_GET_CONFIG_ROUTINE; in->iroutines.reconnect = NO_RECONNECT_ROUTINE; in->iroutines.close = BadAdapter_close; in->iroutines.verify = NO_VERIFY_ROUTINE ; in->iroutines.flags = ADAP_FLAG_sham; in->adapter_name = "Bad Adapter"; SAFEFREE( DEVICENAME(in) ) ; DEVICENAME(in) = owstrdup("None") ; pin->busmode = bus_bad ; return gbGOOD; }
/* Sent back from Bonjour -- arbitrarily use it to set the Ref for Deallocation */ static void RegisterBack(DNSServiceRef s, DNSServiceFlags f, DNSServiceErrorType e, const char *name, const char *type, const char *domain, void *v) { struct connection_out * out = v ; LEVEL_DETAIL ("RegisterBack ref=%d flags=%d error=%d name=%s type=%s domain=%s", s, f, e, SAFESTRING(name), SAFESTRING(type), SAFESTRING(domain)); if (e != kDNSServiceErr_NoError) { return ; } out->sref0 = s; SAFEFREE( out->zero.name ) ; out->zero.name = owstrdup(name) ; SAFEFREE( out->zero.type ) ; out->zero.type = owstrdup(type) ; SAFEFREE( out->zero.domain ) ; out->zero.domain = owstrdup(domain) ; }
GOOD_OR_BAD FS_FindHA7(void) { struct addrinfo *ai; struct addrinfo hint; struct addrinfo *now; int number_found = 0; int getaddr_error ; LEVEL_DEBUG("Attempting udp multicast search for the HA7Net bus master at %s:%s",HA7_DISCOVERY_ADDRESS,HA7_DISCOVERY_PORT); Setup_HA7_hint( &hint ) ; if ((getaddr_error = getaddrinfo(HA7_DISCOVERY_ADDRESS, HA7_DISCOVERY_PORT, &hint, &ai))) { LEVEL_CONNECT("Couldn't set up HA7 broadcast message %s", gai_strerror(getaddr_error)); return gbBAD; } for (now = ai; now; now = now->ai_next) { ASCII name[INET_ADDRSTRLEN+20]; // tcp quad + port struct port_in * pin ; struct connection_in *in; if ( Get_HA7_response( now, name ) ) { continue ; } pin = NewPort(NO_CONNECTION) ; if (pin == NULL) { continue; } in = pin->first ; pin->type = ct_tcp ; pin->init_data = owstrdup(name); DEVICENAME(in) = owstrdup(name); pin->busmode = bus_ha7net; LEVEL_CONNECT("HA7Net bus master discovered at %s",DEVICENAME(in)); ++number_found ; } freeaddrinfo(ai); return number_found > 0 ? gbGOOD : gbBAD ; }
static void create_subdirs( char * s_prop, char * s_family ) { char * slash ; char * subdir = owstrdup( s_prop ) ; if ( subdir == NULL ) { return ; } while ( (slash = strrchr( subdir, '/' )) != NULL ) { slash[0] = '\0' ; AddPropertyToTree( subdir, s_family, ft_subdir, 1, ag_separate, ag_numbers, 0, fc_subdir, "", "", "", "", et_none ) ; } owfree(subdir) ; }
static ssize_t OW_init_both(const char *params, enum restart_init repeat) { /* Set up owlib */ API_setup(program_type_clibrary); /* Proceed with init while lock held */ /* grab our executable name */ Globals.progname = owstrdup("OWCAPI"); if ( BAD( API_init(params, repeat) ) ) { API_finish(); return ReturnAndErrno(-EINVAL) ; } return ReturnAndErrno(0); }
ZERO_OR_ERROR FS_r_external( struct one_wire_query * owq ) { ZERO_OR_ERROR zoe = -ENOENT ; // default char * device_property = owstrdup( PN(owq)->device_name ) ; // copy of device/property part of path if ( device_property != NULL ) { char * property = device_property ; char * device = strsep( &property, "/" ) ; // separate out property char * extension = property ; if ( property != NULL ) { // pare off extension property = strsep( &extension, "." ) ; } zoe = OW_trees_for_read( device, property, owq ) ; owfree( device_property ) ; // clean up } return zoe ; }
static void GetAllDeviceNames( struct port_in * pin ) { struct connection_in * in = pin->first ; ASCII * remaining_device_list = owstrdup( pin->init_data ) ; ASCII * remember_location = remaining_device_list ; while (remaining_device_list != NULL) { const ASCII *current_device_start; for (current_device_start = strsep(&remaining_device_list, " ,"); current_device_start[0] != '\0'; ++current_device_start) { // note that strsep updates "remaining_device_list" pointer if (current_device_start[0] != ' ' && current_device_start[0] != ',') { break; } } GetDeviceName( ¤t_device_start, in ) ; } SAFEFREE( remember_location ) ; in->AnyDevices = (DirblobElements(&(in->master.fake.main)) > 0) ? anydevices_yes : anydevices_no ; }
void Setup_Systemd( void ) { int fds = sd_listen_fds(0) ; int fd_count = 0 ; int i ; for ( i = 0 ; i < fds ; ++i ) { struct connection_out *out = NewOut(); if (out == NULL) { break ; } out->file_descriptor = i + SD_LISTEN_FDS_START ; ++ fd_count ; out->name = owstrdup("systemd"); out->inet_type = inet_systemd ; } if ( fd_count > 0 ) { Globals.daemon_status = e_daemon_sd ; Globals.inet_type = inet_systemd ; } }
static void SetConninData( int indx, const char * type, struct port_in *pin ) { struct connection_in * in = pin->first ; char name[20] ; pin->file_descriptor = indx; pin->type = ct_none ; in->master.fake.index = indx; in->master.fake.templow = Globals.templow; in->master.fake.temphigh = Globals.temphigh; LEVEL_CONNECT("Setting up %s Bus Master (%d)", type, indx); UCLIBCLOCK ; snprintf(name, 18, "%s.%d", type, indx); UCLIBCUNLOCK ; GetAllDeviceNames( pin ) ; // Device name and init_data diverge now SAFEFREE(DEVICENAME(in)) ; DEVICENAME(in) = owstrdup(name); }
/* ---------------------------------------------- */ int main(int argc, char *argv[]) { int c; struct Fuse_option fuse_options; /* Set up owlib */ LibSetup(program_type_filesystem); /* grab our executable name */ if (argc > 0) { Globals.progname = owstrdup(argv[0]); } //mtrace() ; /* process command line arguments */ while ((c = getopt_long(argc, argv, OWLIB_OPT, owopts_long, NULL)) != -1) { switch (c) { case 'V': fprintf(stderr, "%s version:\n\t" VERSION "\n", argv[0]); break; case e_fuse_opt: /* fuse_mnt_opt */ if (fuse_mnt_opt) { owfree(fuse_mnt_opt); } fuse_mnt_opt = Fuse_arg(optarg, "FUSE mount options"); if (fuse_mnt_opt == NULL) { ow_exit(0); } break; case e_fuse_open_opt: /* fuse_open_opt */ if (fuse_open_opt) { owfree(fuse_open_opt); } fuse_open_opt = Fuse_arg(optarg, "FUSE open options"); if (fuse_open_opt == NULL) { ow_exit(0); } break; } if ( BAD( owopt(c, optarg) ) ) { ow_exit(0); /* rest of message */ } } /* non-option arguments */ while (optind < argc - 1) { ARG_Generic(argv[optind]); ++optind; } while (optind < argc) { if (Outbound_Control.active) { ARG_Generic(argv[optind]); } else { ARG_Server(argv[optind]); } ++optind; } if (Outbound_Control.active == 0) { LEVEL_DEFAULT("No mount point specified.\nTry '%s -h' for help.", argv[0]); ow_exit(1); } // FUSE directory mounting LEVEL_CONNECT("fuse mount point: %s", Outbound_Control.head->name); // Signal handler is set in fuse library //set_signal_handlers(exit_handler); /* Set up adapters */ if ( BAD(LibStart()) ) { ow_exit(1); } #if FUSE_VERSION >= 14 /* Set up "command line" for main fuse routines */ Fuse_setup(&fuse_options); // command line setup Fuse_add(Outbound_Control.head->name, &fuse_options); // mount point #if FUSE_VERSION >= 22 Fuse_add("-o", &fuse_options); // add "-o direct_io" to prevent buffering Fuse_add("direct_io", &fuse_options); #endif /* FUSE_VERSION >= 22 */ if (!Globals.want_background) { Fuse_add("-f", &fuse_options); // foreground for fuse too if (Globals.error_level > 2) { Fuse_add("-d", &fuse_options); // debug for fuse too } } Fuse_parse(fuse_mnt_opt, &fuse_options); LEVEL_DEBUG("fuse_mnt_opt=[%s]", fuse_mnt_opt); Fuse_parse(fuse_open_opt, &fuse_options); LEVEL_DEBUG("fuse_open_opt=[%s]", fuse_open_opt); if (Globals.allow_other) { Fuse_add("-o", &fuse_options); // add "-o allow_other" to permit other users access Fuse_add("allow_other", &fuse_options); } #if OW_MT == 0 Fuse_add("-s", &fuse_options); // single threaded #endif /* OW_MT */ Globals.now_background = Globals.want_background; // tell "error" that we are background #if 0 { int i; for (i = 0; i < fuse_options.argc; i++) { LEVEL_DEBUG("fuse_options.argv[%d]=[%s]", i, fuse_options.argv[i]); } } #endif #if FUSE_VERSION > 25 fuse_main(fuse_options.argc, fuse_options.argv, &owfs_oper, NULL); #else /* FUSE_VERSION <= 25 */ fuse_main(fuse_options.argc, fuse_options.argv, &owfs_oper); #endif /* FUSE_VERSION <= 25 */ Fuse_cleanup(&fuse_options); #endif ow_exit(0); return 0; }
static enum parse_enum Parse_Property(char *filename, struct parsedname *pn) { struct device * pdev = pn->selected_device ; struct filetype * ft ; static regex_t rx_extension ; static regex_t rx_all ; static regex_t rx_byte ; static regex_t rx_number ; static regex_t rx_letter ; int extension_given ; struct ow_regmatch orm ; orm.number = 0 ; ow_regcomp( &rx_extension, "\\.", 0 ) ; ow_regcomp( &rx_all, "\\.all$", REG_ICASE ) ; ow_regcomp( &rx_byte, "\\.byte$", REG_ICASE ) ; ow_regcomp( &rx_number, "\\.[[:digit:]]+$", 0 ) ; ow_regcomp( &rx_letter, "\\.[[:alpha:]]$", REG_ICASE ) ; //printf("FilePart: %s %s\n", filename, pn->path); // Special case for remote device. Use distant data if ( pdev == &RemoteDevice ) { // remote device, no known sn, handle property in server. return parse_done ; } // separate filename.dot // filename = strsep(&dot, "."); if ( ow_regexec( &rx_extension, filename, &orm ) == 0 ) { // extension given extension_given = 1 ; ft = bsearch(orm.pre[0], pdev->filetype_array, (size_t) pdev->count_of_filetypes, sizeof(struct filetype), filetype_cmp) ; ow_regexec_free( &orm ) ; } else { // no extension given extension_given = 0 ; ft = bsearch(filename, pdev->filetype_array, (size_t) pdev->count_of_filetypes, sizeof(struct filetype), filetype_cmp) ; } pn->selected_filetype = ft ; if (ft == NO_FILETYPE ) { LEVEL_DEBUG("Unknown property for this device %s",SAFESTRING(filename) ) ; return parse_error; /* filetype not found */ } //printf("FP known filetype %s\n",pn->selected_filetype->name) ; /* Filetype found, now process extension */ if (extension_given==0) { /* no extension */ if (ft->ag != NON_AGGREGATE) { return parse_error; /* aggregate filetypes need an extension */ } pn->extension = 0; /* default when no aggregate */ // Non-aggregate cannot have an extension } else if (ft->ag == NON_AGGREGATE) { return parse_error; /* An extension not allowed when non-aggregate */ // Sparse uses the extension verbatim (text or number) } else if (ft->ag->combined==ag_sparse) { /* Sparse */ if (ft->ag->letters == ag_letters) { /* text string */ pn->extension = 0; /* text extension, not number */ ow_regexec( &rx_extension, filename, &orm ) ; // don't need to test -- already succesful pn->sparse_name = owstrdup(orm.post[0]) ; ow_regexec_free( &orm ) ; LEVEL_DEBUG("Sparse alpha extension found: <%s>",pn->sparse_name); } else { /* Numbers */ if ( ow_regexec( &rx_number, filename, &orm ) == 0 ) { pn->extension = atoi( &orm.match[0][1] ); /* Number conversion */ ow_regexec_free( &orm ) ; LEVEL_DEBUG("Sparse numeric extension found: <%ld>",(long int) pn->extension); } else { LEVEL_DEBUG("Non numeric extension for %s",filename ) ; return parse_error ; } } // Non-sparse "ALL" } else if (ow_regexec( &rx_all, filename, NULL ) == 0) { //printf("FP ALL\n"); pn->extension = EXTENSION_ALL; /* ALL */ // Non-sparse "BYTE" } else if (ft->format == ft_bitfield && ow_regexec( &rx_byte, filename, NULL) == 0) { pn->extension = EXTENSION_BYTE; /* BYTE */ //printf("FP BYTE\n") ; // Non-sparse extension -- interpret and check bounds } else { /* specific extension */ if (ft->ag->letters == ag_letters) { /* Letters */ //printf("FP letters\n") ; if ( ow_regexec( &rx_letter, filename, &orm ) == 0 ) { pn->extension = toupper(orm.match[0][1]) - 'A'; /* Letter extension */ ow_regexec_free( &orm ) ; } else { return parse_error; } } else { /* Numbers */ if ( ow_regexec( &rx_number, filename, &orm ) == 0 ) { pn->extension = atoi( &orm.match[0][1] ); /* Number conversion */ ow_regexec_free( &orm ) ; } else { return parse_error; } } //printf("FP ext=%d nr_elements=%d\n", pn->extension, pn->selected_filetype->ag->elements) ; /* Now check range */ if ((pn->extension < 0) || (pn->extension >= ft->ag->elements)) { //printf("FP Extension out of range %d %d %s\n", pn->extension, pn->selected_filetype->ag->elements, pn->path); LEVEL_DEBUG("Extension %d out of range",pn->extension ) ; return parse_error; /* Extension out of range */ } //printf("FP in range\n") ; } //printf("FP Good\n") ; switch (ft->format) { case ft_directory: // aux or main if ( pn->type == ePN_structure ) { // special case, structure for aux and main return parse_done; } if (BranchAdd(pn) != 0) { //printf("PN BranchAdd failed for %s\n", filename); return parse_error; } /* STATISTICS */ STATLOCK; if (pn->ds2409_depth > dir_depth) { dir_depth = pn->ds2409_depth; } STATUNLOCK; return parse_branch; case ft_subdir: //printf("PN %s is a subdirectory\n", filename); pn->subdir = ft; pn->selected_filetype = NO_FILETYPE; return parse_subprop; default: return parse_done; } }
// Look through text_string, ignore backslash and match quoting varibles // allocates a new string with the token static char * string_parse( char * text_string, char delim, char ** last_char ) { char * copy_string ; char * old_string_pointer = text_string ; char * new_string_pointer ; //printf("->>>STRING (%c) PARSE <%s>\n",delim,text_string); if ( text_string == NULL ) { *last_char = text_string ; return owstrdup("") ; } new_string_pointer = copy_string = owstrdup( text_string ) ; // more than enough room if ( copy_string == NULL ) { *last_char = text_string ; return NULL ; } while ( 1 ) { char current_char = old_string_pointer[0] ; new_string_pointer[0] = current_char ; // default copy if ( current_char == '\0' ) { // end of string *last_char = old_string_pointer ; //printf("<<<-STRING (%c) PARSE <%s>, end:<%s>\n",delim,copy_string,*last_char); return copy_string ; } else if ( current_char == '\\' ) { // backslash, use next char literally if ( old_string_pointer[1] ) { new_string_pointer[0] = old_string_pointer[1] ; ++ new_string_pointer ; old_string_pointer += 2 ; } else { // unless there is no next char *last_char = old_string_pointer + 1 ; //printf("<<<-STRING (%c) PARSE <%s>, end:<%s>\n",delim,copy_string,*last_char); return copy_string ; } } else if ( current_char == delim ) { // found delimitter match // point to it, and null terminate *last_char = old_string_pointer ; new_string_pointer[1] = '\0' ; //printf("<<<-STRING (%c) PARSE <%s>, end:<%s>\n",delim,copy_string,*last_char); return copy_string ; } else if ( current_char == '"' || current_char == '\'' ) { // quotation -- find matching end char * quote_last_char ; char * quoted_string = string_parse( old_string_pointer+1, current_char, "e_last_char ) ; //printf("----STRING (%c) PARSE Quote <%s> end:<%s>\n",delim,quoted_string,quote_last_char); if ( quoted_string ) { strcpy( new_string_pointer+1, quoted_string ) ; new_string_pointer += strlen( quoted_string ) + 1 ; if ( quote_last_char[0] == current_char ) { quote_last_char[0] = '\0' ; // clear trailing quote old_string_pointer = quote_last_char + 1 ; } else { old_string_pointer = quote_last_char ; } owfree( quoted_string ) ; } else { new_string_pointer[1] = '\0' ; *last_char = old_string_pointer ; //printf("<<<-STRING (%c) PARSE <%s>, end:<%s>\n",delim,copy_string,*last_char); return copy_string ; } } else { ++ old_string_pointer ; ++ new_string_pointer ; } } }
/* Device-specific functions */ GOOD_OR_BAD ENET_monitor_detect(struct port_in *pin) { struct connection_in * in = pin->first ; struct address_pair ap ; pthread_t thread ; /* init_data has form "scan" or "scan:15" (15 seconds) */ Parse_Address( pin->init_data, &ap ) ; in->master.enet_monitor.enet_scan_interval = DEFAULT_ENET_SCAN_INTERVAL ; switch ( ap.entries ) { case 0: in->master.enet_monitor.enet_scan_interval = DEFAULT_ENET_SCAN_INTERVAL ; break ; case 1: switch( ap.first.type ) { case address_numeric: in->master.enet_monitor.enet_scan_interval = ap.first.number ; break ; default: in->master.enet_monitor.enet_scan_interval = DEFAULT_ENET_SCAN_INTERVAL ; break ; } break ; case 2: switch( ap.second.type ) { case address_numeric: in->master.enet_monitor.enet_scan_interval = ap.second.number ; break ; default: in->master.enet_monitor.enet_scan_interval = DEFAULT_ENET_SCAN_INTERVAL ; break ; } break ; } Free_Address( &ap ) ; pin->type = ct_none ; // Device name will not be init_data copy SAFEFREE(DEVICENAME(in)) ; DEVICENAME(in) = owstrdup("ENET bus monitor") ; pin->file_descriptor = FILE_DESCRIPTOR_BAD; in->iroutines.detect = ENET_monitor_detect; in->Adapter = adapter_enet_monitor; in->iroutines.reset = NO_RESET_ROUTINE; in->iroutines.next_both = NO_NEXT_BOTH_ROUTINE; in->iroutines.PowerByte = NO_POWERBYTE_ROUTINE; in->iroutines.ProgramPulse = NO_PROGRAMPULSE_ROUTINE; in->iroutines.sendback_data = NO_SENDBACKDATA_ROUTINE; in->iroutines.sendback_bits = NO_SENDBACKBITS_ROUTINE; in->iroutines.select = NO_SELECT_ROUTINE; in->iroutines.select_and_sendback = NO_SELECTANDSENDBACK_ROUTINE ; in->iroutines.set_config = NO_SET_CONFIG_ROUTINE; in->iroutines.get_config = NO_GET_CONFIG_ROUTINE; in->iroutines.reconnect = NO_RECONNECT_ROUTINE; in->iroutines.close = ENET_monitor_close; in->iroutines.verify = NO_VERIFY_ROUTINE ; in->iroutines.flags = ADAP_FLAG_sham; in->adapter_name = "ENET scan"; pin->busmode = bus_enet_monitor ; // repeat since can come via usb=scan Init_Pipe( in->master.enet_monitor.shutdown_pipe ) ; if ( pipe( in->master.enet_monitor.shutdown_pipe ) != 0 ) { ERROR_DEFAULT("Cannot allocate a shutdown pipe. The program shutdown may be messy"); Init_Pipe( in->master.enet_monitor.shutdown_pipe ) ; } if ( BAD( ENET_monitor_in_use(pin) ) ) { LEVEL_CONNECT("Second call for ENET scanning ignored") ; return gbBAD ; } if ( pthread_create(&thread, DEFAULT_THREAD_ATTR, ENET_monitor_loop, (void *) in) != 0 ) { ERROR_CALL("Cannot create the ENET monitoring program thread"); return gbBAD ; } return gbGOOD ; }
GOOD_OR_BAD ClientAddr(char *sname, char * default_port, struct connection_in *in) { struct port_in * pin = in->pown ; struct addrinfo hint; struct address_pair ap ; int ret; Parse_Address( sname, &ap ) ; switch ( ap.entries ) { case 0: // Complete default address pin->dev.tcp.host = NULL; pin->dev.tcp.service = owstrdup(default_port); break ; case 1: // single entry -- usually port unless a dotted quad switch ( ap.first.type ) { case address_none: pin->dev.tcp.host = NULL; pin->dev.tcp.service = owstrdup(default_port); break ; case address_dottedquad: // looks like an IP address pin->dev.tcp.host = owstrdup(ap.first.alpha); pin->dev.tcp.service = owstrdup(default_port); break ; case address_numeric: pin->dev.tcp.host = NULL; pin->dev.tcp.service = owstrdup(ap.first.alpha); break ; default: // assume it's a port if it's the SERVER if ( strcasecmp( default_port, DEFAULT_SERVER_PORT ) == 0 ) { pin->dev.tcp.host = NULL; pin->dev.tcp.service = owstrdup(ap.first.alpha); } else { pin->dev.tcp.host = owstrdup(ap.first.alpha); pin->dev.tcp.service = owstrdup(default_port); } break ; } break ; case 2: default: // address:port format -- unambiguous pin->dev.tcp.host = ( ap.first.type == address_none ) ? NULL : owstrdup(ap.first.alpha) ; pin->dev.tcp.service = ( ap.second.type == address_none ) ? owstrdup(default_port) : owstrdup(ap.second.alpha) ; break ; } Free_Address( &ap ) ; memset(&hint, 0, sizeof(struct addrinfo)); // hint.ai_socktype = SOCK_STREAM | SOCK_CLOEXEC ; hint.ai_socktype = SOCK_STREAM ; #if OW_CYGWIN hint.ai_family = AF_INET; if( pin->dev.tcp.host == NULL) { /* getaddrinfo doesn't work with host=NULL for cygwin */ pin->dev.tcp.host = owstrdup("127.0.0.1"); } #else hint.ai_family = AF_UNSPEC; #endif LEVEL_DEBUG("IP address=[%s] port=[%s]", SAFESTRING( pin->dev.tcp.host), pin->dev.tcp.service); ret = getaddrinfo( pin->dev.tcp.host, pin->dev.tcp.service, &hint, &( pin->dev.tcp.ai) ) ; if ( ret != 0 ) { LEVEL_CONNECT("GETADDRINFO error %s", gai_strerror(ret)); return gbBAD; } return gbGOOD; }