async function checkPorts (ipfsd) {
  const config = readConfigFile(ipfsd)

  const apiIsArr = Array.isArray(config.Addresses.API)
  const gatewayIsArr = Array.isArray(config.Addresses.Gateway)

  if (apiIsArr || gatewayIsArr) {
    logger.info('[daemon] custom configuration with array of API or Gateway addrs')
    return checkPortsArray(ipfsd, [].concat(config.Addresses.API, config.Addresses.Gateway))
  }

  const configApiMa = parseMultiaddr(config.Addresses.API)
  const configGatewayMa = parseMultiaddr(config.Addresses.Gateway)

  const isApiMaDaemon = await checkIfAddrIsDaemon(configApiMa.nodeAddress())
  const isGatewayMaDaemon = await checkIfAddrIsDaemon(configGatewayMa.nodeAddress())

  if (isApiMaDaemon && isGatewayMaDaemon) {
    logger.info('[daemon] ports busy by a daemon')
    return true
  }

  const apiPort = configApiMa.nodeAddress().port
  const gatewayPort = configGatewayMa.nodeAddress().port

  const freeGatewayPort = await findFreePort(gatewayPort)
  let freeApiPort = await findFreePort(apiPort)

  // ensure the picked ports are different
  while (freeApiPort === freeGatewayPort) {
    freeApiPort = await findFreePort(freeApiPort + 1)
  }

  const busyApiPort = apiPort !== freeApiPort
  const busyGatewayPort = gatewayPort !== freeGatewayPort

  if (!busyApiPort && !busyGatewayPort) {
    return true
  }

  // two "0" in config mean "pick free ports without any prompt"
  let promptUser = (apiPort !== 0 || gatewayPort !== 0)

  if (process.env.NODE_ENV === 'test' || process.env.CI != null) {
    logger.info('[daemon] CI or TEST mode, skipping busyPortDialog')
    promptUser = false
  }

  if (promptUser) {
    let useAlternativePorts = null

    if (busyApiPort && busyGatewayPort) {
      logger.info('[daemon] api and gateway ports busy')
      useAlternativePorts = dialogs.busyPortsDialog(apiPort, freeApiPort, gatewayPort, freeGatewayPort)
    } else if (busyApiPort) {
      logger.info('[daemon] api port busy')
      useAlternativePorts = dialogs.busyPortDialog(apiPort, freeApiPort)
    } else {
      logger.info('[daemon] gateway port busy')
      useAlternativePorts = dialogs.busyPortDialog(gatewayPort, freeGatewayPort)
    }

    if (!useAlternativePorts) {
      return false
    }
  }

  if (busyApiPort) {
    config.Addresses.API = config.Addresses.API.replace(apiPort.toString(), freeApiPort.toString())
  }

  if (busyGatewayPort) {
    config.Addresses.Gateway = config.Addresses.Gateway.replace(gatewayPort.toString(), freeGatewayPort.toString())
  }

  writeConfigFile(ipfsd, config)
  logger.info('[daemon] ports updated')
  return true
}
Check if ports are available and handle it. Returns
true if ports are cleared for IPFS to start.

@param {import('ipfsd-ctl').Controller} ipfsd
@returns {Promise<boolean>}