Пример #1
0
/**
  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;
}
Пример #2
0
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;
}