/** Function for 'tftp' command. @param[in] ImageHandle Handle to the Image (NULL if Internal). @param[in] SystemTable Pointer to the System Table (NULL if Internal). @return SHELL_SUCCESS The 'tftp' command completed successfully. @return SHELL_ABORTED The Shell Library initialization failed. @return SHELL_INVALID_PARAMETER At least one of the command's arguments is not valid. @return SHELL_OUT_OF_RESOURCES A memory allocation failed. @return SHELL_NOT_FOUND Network Interface Card not found or server error or file error. **/ SHELL_STATUS EFIAPI ShellCommandRunTftp ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { SHELL_STATUS ShellStatus; EFI_STATUS Status; LIST_ENTRY *CheckPackage; CHAR16 *ProblemParam; UINTN ParamCount; CONST CHAR16 *UserNicName; BOOLEAN NicFound; CONST CHAR16 *ValueStr; CONST CHAR16 *RemoteFilePath; CHAR8 *AsciiRemoteFilePath; CONST CHAR16 *Walker; CONST CHAR16 *LocalFilePath; EFI_MTFTP4_CONFIG_DATA Mtftp4ConfigData; EFI_HANDLE *Handles; UINTN HandleCount; UINTN NicNumber; CHAR16 NicName[IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH]; EFI_HANDLE ControllerHandle; EFI_HANDLE Mtftp4ChildHandle; EFI_MTFTP4_PROTOCOL *Mtftp4; UINTN FileSize; VOID *Data; SHELL_FILE_HANDLE FileHandle; ShellStatus = SHELL_INVALID_PARAMETER; ProblemParam = NULL; NicFound = FALSE; AsciiRemoteFilePath = NULL; Handles = NULL; FileSize = 0; // // Initialize the Shell library (we must be in non-auto-init...) // Status = ShellInitialize (); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); return SHELL_ABORTED; } // // Parse the command line. // Status = ShellCommandLineParse (ParamList, &CheckPackage, &ProblemParam, TRUE); if (EFI_ERROR (Status)) { if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL) ) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellTftpHiiHandle, L"tftp", ProblemParam ); FreePool (ProblemParam); } else { ASSERT (FALSE); } goto Error; } // // Check the number of parameters // ParamCount = ShellCommandLineGetCount (CheckPackage); if (ParamCount > 4) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellTftpHiiHandle, L"tftp" ); goto Error; } if (ParamCount < 3) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellTftpHiiHandle, L"tftp" ); goto Error; } Mtftp4ConfigData = DefaultMtftp4ConfigData; // // Check the host IPv4 address // ValueStr = ShellCommandLineGetRawValue (CheckPackage, 1); Status = NetLibStrToIp4 (ValueStr, &Mtftp4ConfigData.ServerIp); if (EFI_ERROR (Status)) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellTftpHiiHandle, L"tftp", ValueStr ); goto Error; } RemoteFilePath = ShellCommandLineGetRawValue (CheckPackage, 2); AsciiRemoteFilePath = AllocatePool ( (StrLen (RemoteFilePath) + 1) * sizeof (CHAR8) ); if (AsciiRemoteFilePath == NULL) { ShellStatus = SHELL_OUT_OF_RESOURCES; goto Error; } UnicodeStrToAsciiStr (RemoteFilePath, AsciiRemoteFilePath); if (ParamCount == 4) { LocalFilePath = ShellCommandLineGetRawValue (CheckPackage, 3); } else { Walker = RemoteFilePath + StrLen (RemoteFilePath); while ((--Walker) >= RemoteFilePath) { if ((*Walker == L'\\') || (*Walker == L'/' ) ) { break; } } LocalFilePath = Walker + 1; } // // Get the name of the Network Interface Card to be used if any. // UserNicName = ShellCommandLineGetValue (CheckPackage, L"-i"); ValueStr = ShellCommandLineGetValue (CheckPackage, L"-l"); if (ValueStr != NULL) { if (!StringToUint16 (ValueStr, &Mtftp4ConfigData.LocalPort)) { goto Error; } } ValueStr = ShellCommandLineGetValue (CheckPackage, L"-r"); if (ValueStr != NULL) { if (!StringToUint16 (ValueStr, &Mtftp4ConfigData.InitialServerPort)) { goto Error; } } ValueStr = ShellCommandLineGetValue (CheckPackage, L"-c"); if (ValueStr != NULL) { if (!StringToUint16 (ValueStr, &Mtftp4ConfigData.TryCount)) { goto Error; } } ValueStr = ShellCommandLineGetValue (CheckPackage, L"-t"); if (ValueStr != NULL) { if (!StringToUint16 (ValueStr, &Mtftp4ConfigData.TimeoutValue)) { goto Error; } if (Mtftp4ConfigData.TimeoutValue == 0) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellTftpHiiHandle, L"tftp", ValueStr ); goto Error; } } // // Locate all MTFTP4 Service Binding protocols // ShellStatus = SHELL_NOT_FOUND; Status = gBS->LocateHandleBuffer ( ByProtocol, &gEfiManagedNetworkServiceBindingProtocolGuid, NULL, &HandleCount, &Handles ); if (EFI_ERROR (Status) || (HandleCount == 0)) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_NO_NIC), gShellTftpHiiHandle ); goto Error; } for (NicNumber = 0; (NicNumber < HandleCount) && (ShellStatus != SHELL_SUCCESS); NicNumber++) { ControllerHandle = Handles[NicNumber]; Data = NULL; Status = GetNicName (ControllerHandle, NicNumber, NicName); if (EFI_ERROR (Status)) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_NIC_NAME), gShellTftpHiiHandle, NicNumber, Status ); continue; } if (UserNicName != NULL) { if (StrCmp (NicName, UserNicName) != 0) { continue; } NicFound = TRUE; } Status = CreateServiceChildAndOpenProtocol ( ControllerHandle, &gEfiMtftp4ServiceBindingProtocolGuid, &gEfiMtftp4ProtocolGuid, &Mtftp4ChildHandle, (VOID**)&Mtftp4 ); if (EFI_ERROR (Status)) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_OPEN_PROTOCOL), gShellTftpHiiHandle, NicName, Status ); continue; } Status = Mtftp4->Configure (Mtftp4, &Mtftp4ConfigData); if (EFI_ERROR (Status)) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_CONFIGURE), gShellTftpHiiHandle, NicName, Status ); goto NextHandle; } Status = GetFileSize (Mtftp4, AsciiRemoteFilePath, &FileSize); if (EFI_ERROR (Status)) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_FILE_SIZE), gShellTftpHiiHandle, RemoteFilePath, NicName, Status ); goto NextHandle; } Status = DownloadFile (Mtftp4, RemoteFilePath, AsciiRemoteFilePath, FileSize, &Data); if (EFI_ERROR (Status)) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_DOWNLOAD), gShellTftpHiiHandle, RemoteFilePath, NicName, Status ); goto NextHandle; } if (!EFI_ERROR (ShellFileExists (LocalFilePath))) { ShellDeleteFileByName (LocalFilePath); } Status = ShellOpenFileByName ( LocalFilePath, &FileHandle, EFI_FILE_MODE_CREATE | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_READ, 0 ); if (EFI_ERROR (Status)) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellTftpHiiHandle, L"tftp", LocalFilePath ); goto NextHandle; } Status = ShellWriteFile (FileHandle, &FileSize, Data); if (!EFI_ERROR (Status)) { ShellStatus = SHELL_SUCCESS; } else { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_WRITE), gShellTftpHiiHandle, LocalFilePath, Status ); } ShellCloseFile (&FileHandle); NextHandle: if (Data != NULL) { gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Data, EFI_SIZE_TO_PAGES (FileSize)); } CloseProtocolAndDestroyServiceChild ( ControllerHandle, &gEfiMtftp4ServiceBindingProtocolGuid, &gEfiMtftp4ProtocolGuid, Mtftp4ChildHandle ); } if ((UserNicName != NULL) && (!NicFound)) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_NIC_NOT_FOUND), gShellTftpHiiHandle, UserNicName ); } Error: ShellCommandLineFreeVarList (CheckPackage); if (AsciiRemoteFilePath != NULL) { FreePool (AsciiRemoteFilePath); } if (Handles != NULL) { FreePool (Handles); } return ShellStatus; }
int main(int argc, char ** argv) { int c; uint8 hfi = 1; uint8 port = 0; int index; QUERY query; OutputStringMap_t *outputTypeMap = NULL; memset(&query, 0, sizeof(query)); // initialize reserved fields // default query for this application is for all node records query.InputType = InputTypeNoInput; query.OutputType = OutputTypeStlNodeRecord; // process command line arguments while (-1 != (c = getopt_long(argc,argv, "vIh:p:l:k:i:t:s:n:g:u:m:d:P:G:a:A:o:S:L:", options, &index))) { switch (c) { case '$': Usage_full(); break; case 'v': g_verbose++; if (g_verbose>1) oib_set_dbg(stderr); if (g_verbose>2) umad_debug(g_verbose-2); break; case 'I': // issue query in legacy InfiniBand format (IB) g_IB = 1; query.OutputType = OutputTypeNodeRecord; break; case 'h': // hfi to issue query from if (FSUCCESS != StringToUint8(&hfi, optarg, NULL, 0, TRUE)) { fprintf(stderr, "opasaquery: Invalid HFI Number: %s\n", optarg); Usage(); } break; case 'p': // port to issue query from if (FSUCCESS != StringToUint8(&port, optarg, NULL, 0, TRUE)) { fprintf(stderr, "opasaquery: Invalid Port Number: %s\n", optarg); Usage(); } break; case 'l': // query by lid multiInputCheck(query.InputType); query.InputType = InputTypeLid; if (FSUCCESS != StringToUint16(&query.InputValue.Lid, optarg, NULL, 0, TRUE)) { fprintf(stderr, "opasaquery: Invalid LID: %s\n", optarg); Usage(); } break; case 'k': // query by pkey multiInputCheck(query.InputType); query.InputType = InputTypePKey; if (FSUCCESS != StringToUint16(&query.InputValue.PKey, optarg, NULL, 0, TRUE)) { fprintf(stderr, "opasaquery: Invalid PKey: %s\n", optarg); Usage(); } break; case 'i': // query by vfindex multiInputCheck(query.InputType); query.InputType = InputTypeIndex; if (FSUCCESS != StringToUint16(&query.InputValue.vfIndex, optarg, NULL, 0, TRUE)) { fprintf(stderr, "opasaquery: Invalid vfIndex: %s\n", optarg); Usage(); } break; case 'S': // query by serviceId multiInputCheck(query.InputType); query.InputType = InputTypeServiceId; if (FSUCCESS != StringToUint64(&query.InputValue.ServiceId, optarg, NULL, 0, TRUE)) { fprintf(stderr, "opasaquery: Invalid ServiceId: %s\n", optarg); Usage(); } break; case 'L': // query by service level multiInputCheck(query.InputType); query.InputType = InputTypeSL; if (FSUCCESS != StringToUint8(&query.InputValue.SL, optarg, NULL, 0, TRUE) || query.InputValue.SL > 15) { fprintf(stderr, "opasaquery: Invalid SL: %s\n", optarg); Usage(); } break; case 't': // query by node type multiInputCheck(query.InputType); query.InputType = InputTypeNodeType; query.InputValue.TypeOfNode = checkNodeType(optarg); break; case 's': // query by system image guid multiInputCheck(query.InputType); query.InputType = InputTypeSystemImageGuid; if (FSUCCESS != StringToUint64(&query.InputValue.Guid, optarg, NULL, 0, TRUE)) { fprintf(stderr, "opasaquery: Invalid GUID: %s\n", optarg); Usage(); } break; case 'n': // query by node guid multiInputCheck(query.InputType); query.InputType = InputTypeNodeGuid; if (FSUCCESS != StringToUint64(&query.InputValue.Guid, optarg, NULL, 0, TRUE)) { fprintf(stderr, "opasaquery: Invalid GUID: %s\n", optarg); Usage(); } break; case 'g': // query by port guid multiInputCheck(query.InputType); query.InputType = InputTypePortGuid; if (FSUCCESS != StringToUint64(&query.InputValue.Guid, optarg, NULL, 0, TRUE)) { fprintf(stderr, "opasaquery: Invalid GUID: %s\n", optarg); Usage(); } break; case 'u': // query by gid multiInputCheck(query.InputType); query.InputType = InputTypePortGid; if (FSUCCESS != StringToGid(&query.InputValue.Gid.AsReg64s.H,&query.InputValue.Gid.AsReg64s.L, optarg, NULL, TRUE)) { fprintf(stderr, "opasaquery: Invalid GID: %s\n", optarg); Usage(); } break; case 'm': // query by multicast gid multiInputCheck(query.InputType); query.InputType = InputTypeMcGid; if (FSUCCESS != StringToGid(&query.InputValue.Gid.AsReg64s.H,&query.InputValue.Gid.AsReg64s.L, optarg, NULL, TRUE)) { fprintf(stderr, "opasaquery: Invalid GID: %s\n", optarg); Usage(); } break; case 'd': // query by node description multiInputCheck(query.InputType); query.InputType = InputTypeNodeDesc; query.InputValue.NodeDesc.NameLength = MIN(strlen(optarg), NODE_DESCRIPTION_ARRAY_SIZE); strncpy((char*)query.InputValue.NodeDesc.Name, optarg, NODE_DESCRIPTION_ARRAY_SIZE); break; case 'P': // query by source:dest port guids { char *p; multiInputCheck(query.InputType); query.InputType = InputTypePortGuidPair; if (FSUCCESS != StringToUint64(&query.InputValue.PortGuidPair.SourcePortGuid, optarg, &p, 0, TRUE) || ! p || *p == '\0') { fprintf(stderr, "opasaquery: Invalid GUID Pair: %s\n", optarg); Usage(); } if (FSUCCESS != StringToUint64(&query.InputValue.PortGuidPair.DestPortGuid, p, NULL, 0, TRUE)) { fprintf(stderr, "opasaquery: Invalid GUID Pair: %s\n", optarg); Usage(); } } break; case 'G': // query by source:dest port gids { char *p; multiInputCheck(query.InputType); query.InputType = InputTypeGidPair; if (FSUCCESS != StringToGid(&query.InputValue.GidPair.SourceGid.AsReg64s.H,&query.InputValue.GidPair.SourceGid.AsReg64s.L, optarg, &p, TRUE) || ! p || *p == '\0') { fprintf(stderr, "opasaquery: Invalid GID Pair: %s\n", optarg); Usage(); } if (FSUCCESS != StringToGid(&query.InputValue.GidPair.DestGid.AsReg64s.H,&query.InputValue.GidPair.DestGid.AsReg64s.L, p, NULL, TRUE)) { fprintf(stderr, "opasaquery: Invalid GID Pair: %s\n", optarg); Usage(); } } break; case 'a': // multipath query by src1:src2:...;dest1:dest2:... port guids { char *p =optarg; int i = 0; errno = 0; multiInputCheck(query.InputType); query.InputType = InputTypePortGuidList; do { if (FSUCCESS != StringToUint64(&query.InputValue.PortGuidList.GuidList[i], p, &p, 0, TRUE)) { fprintf(stderr, "opasaquery: Invalid GUID List: %s\n", optarg); Usage(); } i++; query.InputValue.PortGuidList.SourceGuidCount++; } while (p && *p != '\0' && *p != ';'); if (p && *p != '\0') { p++; // skip the semi-colon. do { if (FSUCCESS != StringToUint64(&query.InputValue.PortGuidList.GuidList[i], p, &p, 0, TRUE)) { fprintf(stderr, "opasaquery: Invalid GUID List: %s\n", optarg); Usage(); } i++; query.InputValue.PortGuidList.DestGuidCount++; } while (p && *p != '\0'); } else { Usage(); } } break; case 'A': // multipath query by src1:src2:...;dest1:dest2:... gids { char *p=optarg; int i = 0; errno = 0; multiInputCheck(query.InputType); query.InputType = InputTypeGidList; do { if (FSUCCESS != StringToGid(&query.InputValue.GidList.GidList[i].AsReg64s.H,&query.InputValue.GidList.GidList[i].AsReg64s.L, p, &p, TRUE)) { fprintf(stderr, "opasaquery: Invalid GID List: %s\n", optarg); Usage(); } i++; query.InputValue.GidList.SourceGidCount++; } while (p && *p != '\0' && *p != ';'); if (p && *p != '\0') { p++; // skip the semi-colon do { if (FSUCCESS != StringToGid(&query.InputValue.GidList.GidList[i].AsReg64s.H,&query.InputValue.GidList.GidList[i].AsReg64s.L, p, &p, TRUE)) { fprintf(stderr, "opasaquery: Invalid GID List: %s\n", optarg); Usage(); } i++; query.InputValue.GidList.DestGidCount++; } while (p && *p != '\0'); } else { Usage(); } } break; case 'o': // select output record desired outputTypeMap = GetOutputTypeMap(optarg); break; default: fprintf(stderr, "opasaquery: Invalid option -%c\n", c); Usage(); break; } } /* end while */ if (optind < argc) { Usage(); } if (NULL != outputTypeMap) query.OutputType = GetOutputType(outputTypeMap); PrintDestInitFile(&g_dest, stdout); if (g_verbose) PrintDestInitFile(&g_dbgDest, stdout); else PrintDestInitNone(&g_dbgDest); if(oib_open_port_by_num(&sa_oib_session,hfi,port) != 0) { fprintf(stderr, "opasaquery: Could not open oib session.\n"); return FERROR; } // perform the query and display output do_query(sa_oib_session, &query); oib_close_port(sa_oib_session); if (g_exitstatus == 2) Usage(); return g_exitstatus; }