/* * Given a subcommand to the DEVCTL_AP_CONTROL ioctl, rquest the size of * the data to be returned, allocate a buffer, then get the data. * Returns *descrp (which must be freed) and size. * * Note SATA_DESCR_TYPE_STRING returns an ASCII NULL-terminated string, * not a string descr. */ cfga_sata_ret_t do_control_ioctl(const char *ap_id, sata_cfga_apctl_t subcommand, uint_t arg, void **descrp, size_t *sizep) { int fd = -1; uint_t port; uint32_t local_size; cfga_sata_ret_t rv = CFGA_SATA_OK; struct sata_ioctl_data ioctl_data; assert(descrp != NULL); *descrp = NULL; assert(sizep != NULL); if ((rv = get_port_num(ap_id, &port)) != CFGA_SATA_OK) { goto bailout; } if ((fd = open(ap_id, O_RDONLY)) == -1) { (void) printf("do_control_ioctl: open failed: errno:%d\n", errno); rv = CFGA_SATA_OPEN; if (errno == EBUSY) { rv = CFGA_SATA_BUSY; } goto bailout; } ioctl_data.cmd = subcommand; ioctl_data.port = port; ioctl_data.misc_arg = (uint_t)arg; /* * Find out how large a buf we need to get the data. * Note the ioctls only accept/return a 32-bit int for a get_size * to avoid 32/64 and BE/LE issues. */ if ((subcommand == SATA_CFGA_GET_AP_TYPE) || (subcommand == SATA_CFGA_GET_DEVICE_PATH) || (subcommand == SATA_CFGA_GET_MODEL_INFO) || (subcommand == SATA_CFGA_GET_REVFIRMWARE_INFO) || (subcommand == SATA_CFGA_GET_SERIALNUMBER_INFO)) { ioctl_data.get_size = B_TRUE; ioctl_data.buf = (caddr_t)&local_size; ioctl_data.bufsiz = sizeof (local_size); if (ioctl(fd, DEVCTL_AP_CONTROL, &ioctl_data) != 0) { perror("ioctl failed (size)"); rv = CFGA_SATA_IOCTL; goto bailout; } *sizep = local_size; if (local_size == 0) { (void) printf("zero length data\n"); rv = CFGA_SATA_ZEROLEN; goto bailout; } if ((*descrp = malloc(*sizep)) == NULL) { (void) printf("do_control_ioctl: malloc failed\n"); rv = CFGA_SATA_ALLOC_FAIL; goto bailout; } } else { *sizep = 0; } ioctl_data.get_size = B_FALSE; ioctl_data.buf = *descrp; ioctl_data.bufsiz = *sizep; /* Execute IOCTL */ if (ioctl(fd, DEVCTL_AP_CONTROL, &ioctl_data) != 0) { rv = CFGA_SATA_IOCTL; goto bailout; } (void) close(fd); return (rv); bailout: if (fd != -1) { (void) close(fd); } if (*descrp != NULL) { free(*descrp); *descrp = NULL; } if (rv == CFGA_SATA_IOCTL && errno == EBUSY) { rv = CFGA_SATA_BUSY; } return (rv); }
/*ARGSUSED*/ cfga_err_t cfga_list_ext( const char *ap_id, cfga_list_data_t **ap_id_list, int *nlistp, const char *options, const char *listopts, char **errstring, cfga_flags_t flags) { int l_errno; char *ap_id_log = NULL; size_t size; nvlist_t *user_nvlist = NULL; devctl_hdl_t devctl_hdl = NULL; cfga_sata_ret_t rv = CFGA_SATA_OK; devctl_ap_state_t devctl_ap_state; char *pdyn; boolean_t pmult = B_FALSE; uint32_t port; if ((rv = verify_params(ap_id, options, errstring)) != CFGA_SATA_OK) { (void) cfga_help(NULL, options, flags); goto bailout; } /* We do not care here about dynamic AP name component */ if ((pdyn = GET_DYN(ap_id)) != NULL) { *pdyn = '\0'; } if (ap_id_list == NULL || nlistp == NULL) { rv = CFGA_SATA_DATA_ERROR; (void) cfga_help(NULL, options, flags); goto bailout; } /* Get ap status */ if ((rv = setup_for_devctl_cmd(ap_id, &devctl_hdl, &user_nvlist, DC_RDONLY)) != CFGA_SATA_OK) { goto bailout; } /* will call dc_cmd to send IOCTL to kernel */ if (devctl_ap_getstate(devctl_hdl, user_nvlist, &devctl_ap_state) == -1) { cleanup_after_devctl_cmd(devctl_hdl, user_nvlist); rv = CFGA_SATA_IOCTL; goto bailout; } cleanup_after_devctl_cmd(devctl_hdl, user_nvlist); /* * Create cfga_list_data_t struct. */ if ((*ap_id_list = (cfga_list_data_t *)malloc(sizeof (**ap_id_list))) == NULL) { rv = CFGA_SATA_ALLOC_FAIL; goto bailout; } *nlistp = 1; /* * Rest of the code fills in the cfga_list_data_t struct. */ /* Get /dev/cfg path to corresponding to the physical ap_id */ /* Remember ap_id_log must be freed */ rv = physpath_to_devlink(CFGA_DEV_DIR, (char *)ap_id, &ap_id_log, &l_errno); if (rv != 0) { rv = CFGA_SATA_DEVLINK; goto bailout; } /* Get logical ap_id corresponding to the physical */ if (ap_id_log == NULL || strstr(ap_id_log, CFGA_DEV_DIR) == NULL) { rv = CFGA_SATA_DEVLINK; goto bailout; } (void) strlcpy((*ap_id_list)->ap_log_id, /* Strip off /dev/cfg/ */ ap_id_log + strlen(CFGA_DEV_DIR)+ 1, sizeof ((*ap_id_list)->ap_log_id)); free(ap_id_log); ap_id_log = NULL; (void) strlcpy((*ap_id_list)->ap_phys_id, ap_id, sizeof ((*ap_id_list)->ap_phys_id)); switch (devctl_ap_state.ap_rstate) { case AP_RSTATE_EMPTY: (*ap_id_list)->ap_r_state = CFGA_STAT_EMPTY; break; case AP_RSTATE_DISCONNECTED: (*ap_id_list)->ap_r_state = CFGA_STAT_DISCONNECTED; break; case AP_RSTATE_CONNECTED: (*ap_id_list)->ap_r_state = CFGA_STAT_CONNECTED; break; default: rv = CFGA_SATA_STATE; goto bailout; } switch (devctl_ap_state.ap_ostate) { case AP_OSTATE_CONFIGURED: (*ap_id_list)->ap_o_state = CFGA_STAT_CONFIGURED; break; case AP_OSTATE_UNCONFIGURED: (*ap_id_list)->ap_o_state = CFGA_STAT_UNCONFIGURED; break; default: rv = CFGA_SATA_STATE; goto bailout; } switch (devctl_ap_state.ap_condition) { case AP_COND_OK: (*ap_id_list)->ap_cond = CFGA_COND_OK; break; case AP_COND_FAILING: (*ap_id_list)->ap_cond = CFGA_COND_FAILING; break; case AP_COND_FAILED: (*ap_id_list)->ap_cond = CFGA_COND_FAILED; break; case AP_COND_UNUSABLE: (*ap_id_list)->ap_cond = CFGA_COND_UNUSABLE; break; case AP_COND_UNKNOWN: (*ap_id_list)->ap_cond = CFGA_COND_UNKNOWN; break; default: rv = CFGA_SATA_STATE; goto bailout; } (*ap_id_list)->ap_class[0] = '\0'; /* Filled by libcfgadm */ (*ap_id_list)->ap_busy = devctl_ap_state.ap_in_transition; (*ap_id_list)->ap_status_time = devctl_ap_state.ap_last_change; (*ap_id_list)->ap_info[0] = NULL; if ((*ap_id_list)->ap_r_state == CFGA_STAT_CONNECTED) { char *str_p; int skip, i; /* * Fill in the 'Information' field for the -v option * Model (MOD:) */ if ((rv = do_control_ioctl(ap_id, SATA_CFGA_GET_MODEL_INFO, NULL, (void **)&str_p, &size)) != CFGA_SATA_OK) { (void) printf( "SATA_CFGA_GET_MODULE_INFO ioctl failed\n"); goto bailout; } /* drop leading and trailing spaces */ skip = strspn(str_p, " "); for (i = size - 1; i >= 0; i--) { if (str_p[i] == '\040') str_p[i] = '\0'; else if (str_p[i] != '\0') break; } (void) strlcpy((*ap_id_list)->ap_info, "Mod: ", sizeof ((*ap_id_list)->ap_info)); (void) strlcat((*ap_id_list)->ap_info, str_p + skip, sizeof ((*ap_id_list)->ap_info)); free(str_p); /* * Fill in the 'Information' field for the -v option * Firmware revision (FREV:) */ if ((rv = do_control_ioctl(ap_id, SATA_CFGA_GET_REVFIRMWARE_INFO, NULL, (void **)&str_p, &size)) != CFGA_SATA_OK) { (void) printf( "SATA_CFGA_GET_REVFIRMWARE_INFO ioctl failed\n"); goto bailout; } /* drop leading and trailing spaces */ skip = strspn(str_p, " "); for (i = size - 1; i >= 0; i--) { if (str_p[i] == '\040') str_p[i] = '\0'; else if (str_p[i] != '\0') break; } (void) strlcat((*ap_id_list)->ap_info, " FRev: ", sizeof ((*ap_id_list)->ap_info)); (void) strlcat((*ap_id_list)->ap_info, str_p + skip, sizeof ((*ap_id_list)->ap_info)); free(str_p); /* * Fill in the 'Information' field for the -v option * Serial Number (SN:) */ if ((rv = do_control_ioctl(ap_id, SATA_CFGA_GET_SERIALNUMBER_INFO, NULL, (void **)&str_p, &size)) != CFGA_SATA_OK) { (void) printf( "SATA_CFGA_GET_SERIALNUMBER_INFO ioctl failed\n"); goto bailout; } /* drop leading and trailing spaces */ skip = strspn(str_p, " "); for (i = size - 1; i >= 0; i--) { if (str_p[i] == '\040') str_p[i] = '\0'; else if (str_p[i] != '\0') break; } (void) strlcat((*ap_id_list)->ap_info, " SN: ", sizeof ((*ap_id_list)->ap_info)); (void) strlcat((*ap_id_list)->ap_info, str_p + skip, sizeof ((*ap_id_list)->ap_info)); free(str_p); /* Fill in ap_type which is collected from HBA driver */ /* call do_control_ioctl TBD */ if ((rv = do_control_ioctl(ap_id, SATA_CFGA_GET_AP_TYPE, NULL, (void **)&str_p, &size)) != CFGA_SATA_OK) { (void) printf( "SATA_CFGA_GET_AP_TYPE ioctl failed\n"); goto bailout; } (void) strlcpy((*ap_id_list)->ap_type, str_p, sizeof ((*ap_id_list)->ap_type)); free(str_p); /* * Checking device type. Port multiplier has no dynamic * suffix. */ if (strncmp((*ap_id_list)->ap_type, "sata-pmult", sizeof ("sata-pmult")) == 0) pmult = B_TRUE; if ((*ap_id_list)->ap_o_state == CFGA_STAT_CONFIGURED && pmult == B_FALSE) { char *dyncomp = NULL; /* * This is the case where we need to generate * a dynamic component of the ap_id, i.e. device. */ rv = sata_make_dyncomp(ap_id, &dyncomp, (*ap_id_list)->ap_type); if (rv != CFGA_SATA_OK) goto bailout; if (dyncomp != NULL) { (void) strcat((*ap_id_list)->ap_log_id, DYN_SEP); (void) strlcat((*ap_id_list)->ap_log_id, dyncomp, sizeof ((*ap_id_list)->ap_log_id)); free(dyncomp); } } } else { /* This is an empty port */ if (get_port_num(ap_id, &port) != SATA_CFGA_OK) { goto bailout; } if (port & SATA_CFGA_PMPORT_QUAL) { (void) strlcpy((*ap_id_list)->ap_type, "pmult-port", sizeof ((*ap_id_list)->ap_type)); } else { (void) strlcpy((*ap_id_list)->ap_type, "sata-port", sizeof ((*ap_id_list)->ap_type)); } } return (sata_err_msg(errstring, rv, ap_id, errno)); bailout: if (*ap_id_list != NULL) { free(*ap_id_list); } if (ap_id_log != NULL) { free(ap_id_log); } return (sata_err_msg(errstring, rv, ap_id, errno)); }
static cfga_sata_ret_t setup_for_devctl_cmd( const char *ap_id, devctl_hdl_t *devctl_hdl, nvlist_t **user_nvlistp, uint_t oflag) { uint_t port; cfga_sata_ret_t rv = CFGA_SATA_OK; char *lap_id, *pdyn; lap_id = strdup(ap_id); if (lap_id == NULL) return (CFGA_SATA_ALLOC_FAIL); if ((pdyn = GET_DYN(lap_id)) != NULL) { *pdyn = '\0'; } /* Get a devctl handle to pass to the devctl_ap_XXX functions */ if ((*devctl_hdl = devctl_ap_acquire((char *)lap_id, oflag)) == NULL) { (void) fprintf(stderr, "[libcfgadm:sata] " "setup_for_devctl_cmd: devctl_ap_acquire failed: %s\n", strerror(errno)); rv = CFGA_SATA_DEVCTL; goto bailout; } /* Set up nvlist to pass the port number down to the driver */ if (nvlist_alloc(user_nvlistp, NV_UNIQUE_NAME_TYPE, NULL) != 0) { *user_nvlistp = NULL; rv = CFGA_SATA_NVLIST; (void) printf("nvlist_alloc failed\n"); goto bailout; } /* * Get port id, for Port Multiplier port, things could be a little bit * complicated because of "port.port" format in ap_id, thus for * port multiplier port, port number should be coded as 32bit int * with the sig 16 bit as sata channel number, least 16 bit as * the port number of sata port multiplier port. */ if ((rv = get_port_num(lap_id, &port)) != CFGA_SATA_OK) { (void) printf( "setup_for_devctl_cmd: get_port_num, errno: %d\n", errno); goto bailout; } /* Creates an int32_t entry */ if (nvlist_add_int32(*user_nvlistp, PORT, port) == -1) { (void) printf("nvlist_add_int32 failed\n"); rv = CFGA_SATA_NVLIST; goto bailout; } free(lap_id); return (rv); bailout: free(lap_id); (void) cleanup_after_devctl_cmd(*devctl_hdl, *user_nvlistp); return (rv); }
int main() { /*---------- Initialized Server Variables ----------*/ char* the_host_name = malloc(MAX_HOST_NAME*sizeof(char)); the_host_name = get_host_name(); unsigned short port_number = get_port_num(); int socket; /*===== End of Initialized Server Vairables ======*/ /*---------- Initial User Input Variables ----------*/ size_t n; size_t max = 40; char *buff; /*===== End of Initial User Input Variables ======*/ int t; /*---------- Program Loop ----------*/ printf("Enter a nickname: "); while (fgets(buff,max,stdin)) { //Gets the length of the buffer n = strlen(buff); //Gets a connection if ((socket = call_socket(the_host_name, port_number)) < 0) { perror("call_socket"); exit(0); } //Checks if the user inputs a blank string if ( n==1 && buff[n-1] == '\n') { //sends an exit command if( write_data(socket, "\0", MAX_BUFFER_SIZE) < 0) { prompt_error("Write Data Failed"); close(socket); exit(0); } //exits break; } else { //If the user doesnt enter a blank string -> Server request routine if (write_data(socket, buff, MAX_BUFFER_SIZE) < 0) { prompt_error("Write Data Failed"); close(socket); exit(0); } else { printf("Write data success!!\n"); } if (read_data(socket, buff, MAX_BUFFER_SIZE) < 0) { prompt_error("Read Data Failed"); close(socket); exit(0); } else { printf("Data read success.............. \n "); } printf("The server responded with: %s\n", buff); close(socket); } printf("Enter a nickname: "); } /*===== End of Program Loop ======*/ /*---------- Ending Program ----------*/ printf("Ending client program......................\n"); free(the_host_name); close(socket); return 0; /*===== End of Ending Programs ======*/ }