Exemple #1
0
static int
retrievePeerCredentials (PeerCredentials *credentials, int fd) {
  if (getpeereid(fd, &credentials->euid, &credentials->egid) != -1) return 1;
  logSystemError("getpeereid");
  return 0;
}
Exemple #2
0
int
usbReadDeviceDescriptor (UsbDevice *device) {
  errno = ENOSYS;
  logSystemError("USB device descriptor read");
  return 0;
}
Exemple #3
0
int
runCommand (
    int *result,
    const char *const *command,
    HostCommandStream *streams,
    int asynchronous
) {
    int ok = 0;
    sigset_t newMask, oldMask;
    pid_t pid;

    sigemptyset(&newMask);
    sigaddset(&newMask, SIGCHLD);
    sigprocmask(SIG_BLOCK, &newMask, &oldMask);

    switch ((pid = fork())) {
    case -1: /* error */
        logSystemError("fork");
        break;

    case 0: /* child */
        sigprocmask(SIG_SETMASK, &oldMask, NULL);

        if (processHostCommandStreams(childHostCommandStream, streams)) {
            execvp(command[0], (char *const*)command);
            logSystemError("execvp");
        }

        _exit(1);

    default: /* parent */
        if (processHostCommandStreams(parentHostCommandStream, streams)) {
            ok = 1;

            if (asynchronous) {
                *result = 0;
            } else {
                int status;

                if (waitpid(pid, &status, 0) == -1) {
                    logSystemError("waitpid");
                } else if (WIFEXITED(status)) {
                    *result = WEXITSTATUS(status);
                    logMessage(LOG_DEBUG, "host command exit status: %d: %s",
                               *result, command[0]);
                } else if (WIFSIGNALED(status)) {
                    *result = WTERMSIG(status);
                    logMessage(LOG_DEBUG, "host command termination signal: %d: %s",
                               *result, command[0]);
                    *result += 0X80;
                } else if (WIFSTOPPED(status)) {
                    *result = WSTOPSIG(status);
                    logMessage(LOG_DEBUG, "host command stop signal: %d: %s",
                               *result, command[0]);
                    *result += 0X80;
                } else {
                    logMessage(LOG_DEBUG, "unknown host command status: 0X%X: %s",
                               status, command[0]);
                }
            }
        }

        break;
    }

    sigprocmask(SIG_SETMASK, &oldMask, NULL);
    return ok;
}
Exemple #4
0
static int
readPacket (BrailleDisplay *brl, Packet *packet) {
  while (1) {
    int size = sizeof(PacketHeader);
    int hasPayload = 0;

    if (brl->data->inputCount >= sizeof(PacketHeader)) {
      if (brl->data->inputBuffer.packet.header.type & 0X80) {
        hasPayload = 1;
        size += brl->data->inputBuffer.packet.header.arg1 + 1;
      }
    }

    if (size <= brl->data->inputCount) {
      logInputPacket(brl->data->inputBuffer.bytes, size);

      if (hasPayload) {
        unsigned char checksum = 0;
        int index;

        for (index=0; index<size; index+=1)
          checksum -= brl->data->inputBuffer.bytes[index];

        if (checksum) logMessage(LOG_WARNING, "Input packet checksum error.");
      }

      memcpy(packet, &brl->data->inputBuffer, size);
      memmove(&brl->data->inputBuffer.bytes[0], &brl->data->inputBuffer.bytes[size],
              brl->data->inputCount -= size);
      return size;
    }

  retry:
    {
      int count = gioReadData(brl->data->gioEndpoint,
                              &brl->data->inputBuffer.bytes[brl->data->inputCount],
                              size - brl->data->inputCount,
                              0);

      if (count < 1) {
        if (count == -1) {
          logSystemError("read");
        } else if ((count == 0) && (brl->data->inputCount > 0)) {
          if (gioAwaitInput(brl->data->gioEndpoint, 1000)) goto retry;
          if (errno != EAGAIN) count = -1;
          logPartialPacket(brl->data->inputBuffer.bytes, brl->data->inputCount);
          brl->data->inputCount = 0;
        }

        return count;
      }
      brl->data->acknowledgementsMissing = 0;

      if (!brl->data->inputCount) {
        static const unsigned char packets[] = {
          PKT_ACK, PKT_NAK,
          PKT_KEY, PKT_EXTKEY, PKT_BUTTON, PKT_WHEEL,
          PKT_INFO
        };
        int first;

        for (first=0; first<count; first+=1)
          if (memchr(packets, brl->data->inputBuffer.bytes[first], sizeof(packets)))
            break;

        if (first) {
          logDiscardedBytes(brl->data->inputBuffer.bytes, first);
          memmove(&brl->data->inputBuffer.bytes[0], &brl->data->inputBuffer.bytes[first], count-=first);
        }
      }

      brl->data->inputCount += count;
    }
  }
}
Exemple #5
0
UsbDevice *
usbFindDevice (UsbDeviceChooser chooser, void *data) {
  UsbDevice *device = NULL;
  int result;

  {
    static int initialized = 0;
    if (!initialized) {
      usb_init();
      initialized = 1;
    }
  }

  if ((result = usb_find_busses()) >= 0) {
    if ((result = usb_find_devices()) >= 0) {
      struct usb_bus *bus = usb_get_busses();

      if (bus) {
        struct usb_bus *bus0 = bus;

        do {
          struct usb_device *dev = bus->devices;

          if (dev) {
            struct usb_device *dev0 = dev;

            do {
              UsbDeviceExtension *devx;

              if ((devx = malloc(sizeof(*devx)))) {
                if ((devx->handle = usb_open(dev))) {
                  if ((device = usbTestDevice(devx, chooser, data))) return device;

                  usb_close(devx->handle);
                } else {
                  logMessage(LOG_ERR, "USB open error: vendor=%X product=%X",
                             getLittleEndian16(dev->descriptor.idVendor),
                             getLittleEndian16(dev->descriptor.idProduct));
                }

                free(devx);
              } else {
                logSystemError("USB device extension allocate");
              }

              if ((dev = dev->next) == dev0) dev = NULL;
            } while (dev);
          }

          if ((bus = bus->next) == bus0) bus = NULL;
        } while (bus);
      }
    } else {
      errno = -result;
      logSystemError("USB devices find");
    }
  } else {
    errno = -result;
    logSystemError("USB busses find");
  }

  return device;
}
Exemple #6
0
int
usbDisableAutosuspend (UsbDevice *device) {
  errno = ENOSYS;
  logSystemError("USB device autosuspend disable");
  return 0;
}
Exemple #7
0
static int
writeBrailleCells (BrailleDisplay *brl, const unsigned char *cells, size_t count) {
  if (write(brl->data->brailleDevice, cells, count) != -1) return 1;
  logSystemError("write");
  return 0;
}
Exemple #8
0
static int
clearBrailleCells (BrailleDisplay *brl) {
  if (ioctl(brl->data->brailleDevice, METEC_FLAT20_CLEAR_DISPLAY, 0) != -1) return 1;
  logSystemError("ioctl[METEC_FLAT20_CLEAR_DISPLAY]");
  return 0;
}
Exemple #9
0
PcmDevice *
openPcmDevice (int errorLevel, const char *device) {
  PcmDevice *pcm;
  if ((pcm = malloc(sizeof(*pcm)))) {
    int code;

    if (*device) {
      {
	int ok = 0;
	long number;
	char *end;
	const char *component = device;

	number = strtol(component, &end, 0);
	if ((*end && (*end != ':')) || (number < 0) || (number > 0XFF)) {
	  logMessage(errorLevel, "Invalid QSA card number: %s", device);
	} else if (end == component) {
	  logMessage(errorLevel, "Missing QSA card number: %s", device);
	} else {
	  pcm->card = number;

	  if (*end) {
	    component = end + 1;
	    number = strtol(component, &end, 0);
	    if (*end || (number < 0) || (number > 0XFF)) {
	      logMessage(errorLevel, "Invalid QSA device number: %s", device);
	    } else if (end == component) {
	      logMessage(errorLevel, "Missing QSA device number: %s", device);
	    } else {
	      pcm->device = number;
	      ok = 1;
	    }
	  } else {
	    pcm->device = 0;
	    ok = 1;
	  }
	}

	if (!ok) goto openError;
      }

      if ((code = snd_pcm_open(&pcm->handle, pcm->card, pcm->device, SND_PCM_OPEN_PLAYBACK)) < 0) {
	logPcmError(errorLevel, "open", code);
	goto openError;
      }
    } else if ((code = snd_pcm_open_preferred(&pcm->handle, &pcm->card, &pcm->device, SND_PCM_OPEN_PLAYBACK)) < 0) {
      logPcmError(errorLevel, "preferred open", code);
      goto openError;
    }
    logMessage(LOG_DEBUG, "QSA PCM device opened: %d:%d", pcm->card, pcm->device);

    {
      snd_pcm_channel_info_t info;
      info.channel = SND_PCM_CHANNEL_PLAYBACK;
      if ((code = snd_pcm_channel_info(pcm->handle, &info)) >= 0) {
	logMessage(LOG_DEBUG, "QSA PCM Info: Frag=%d-%d Rate=%d-%d Chan=%d-%d",
	           info.min_fragment_size, info.max_fragment_size,
	           info.min_rate, info.max_rate,
	           info.min_voices, info.max_voices);
	memset(&pcm->parameters, 0, sizeof(pcm->parameters));

	pcm->parameters.channel = info.channel;
	pcm->parameters.start_mode = SND_PCM_START_DATA;
	pcm->parameters.stop_mode = SND_PCM_STOP_ROLLOVER;

	switch (pcm->parameters.mode = SND_PCM_MODE_BLOCK) {
	  case SND_PCM_MODE_BLOCK:
	    pcm->parameters.buf.block.frag_size = MIN(MAX(0X400, info.min_fragment_size), info.max_fragment_size);
	    pcm->parameters.buf.block.frags_min = 1;
	    pcm->parameters.buf.block.frags_max = 0X40;
	    break;

	  default:
	    logMessage(LOG_WARNING, "Unsupported QSA PCM mode: %d", pcm->parameters.mode);
	    goto openError;
	}

	pcm->parameters.format.interleave = 1;
	pcm->parameters.format.rate = info.max_rate;
	pcm->parameters.format.voices = MIN(MAX(1, info.min_voices), info.max_voices);
	pcm->parameters.format.format = SND_PCM_SFMT_S16;

	if (reconfigurePcmChannel(pcm, errorLevel)) {
	  if ((code = snd_pcm_channel_prepare(pcm->handle, pcm->parameters.channel)) >= 0) {
	    return pcm;
	  } else {
	    logPcmError(errorLevel, "prepare channel", code);
	  }
	}
      } else {
        logPcmError(errorLevel, "get channel information", code);
      }
    }

  openError:
    free(pcm);
  } else {
    logSystemError("PCM device allocation");
  }

  return NULL;
}
Exemple #10
0
PcmDevice *
openPcmDevice (int errorLevel, const char *device) {
  PcmDevice *pcm;

  if (!pcmAlsaLibrary) {
    if (!(pcmAlsaLibrary = loadSharedObject("libasound.so.2"))) {
      logMessage(LOG_ERR, "Unable to load ALSA PCM library.");
      return NULL;
    }

    PCM_ALSA_LOCATE(strerror);
    PCM_ALSA_LOCATE(pcm_open);
    PCM_ALSA_LOCATE(pcm_close);
    PCM_ALSA_LOCATE(pcm_nonblock);
    PCM_ALSA_LOCATE(pcm_hw_params_malloc);
    PCM_ALSA_LOCATE(pcm_hw_params_any);
    PCM_ALSA_LOCATE(pcm_hw_params_set_access);
    PCM_ALSA_LOCATE(pcm_hw_params_get_channels);
    PCM_ALSA_LOCATE(pcm_hw_params_get_channels_min);
    PCM_ALSA_LOCATE(pcm_hw_params_get_channels_max);
    PCM_ALSA_LOCATE(pcm_hw_params_set_channels_near);
    PCM_ALSA_LOCATE(pcm_hw_params_get_format);
    PCM_ALSA_LOCATE(pcm_hw_params_set_format);
    PCM_ALSA_LOCATE(pcm_hw_params_get_rate);
    PCM_ALSA_LOCATE(pcm_hw_params_get_sbits);
    PCM_ALSA_LOCATE(pcm_hw_params_get_rate_min);
    PCM_ALSA_LOCATE(pcm_hw_params_get_rate_max);
    PCM_ALSA_LOCATE(pcm_hw_params_get_period_size);
    PCM_ALSA_LOCATE(pcm_hw_params_set_rate_near);
    PCM_ALSA_LOCATE(pcm_hw_params_set_buffer_time_near);
    PCM_ALSA_LOCATE(pcm_hw_params_set_period_time_near);
    PCM_ALSA_LOCATE(pcm_hw_params);
    PCM_ALSA_LOCATE(pcm_hw_params_get_sbits);
    PCM_ALSA_LOCATE(pcm_hw_params_free);
    PCM_ALSA_LOCATE(pcm_prepare);
    PCM_ALSA_LOCATE(pcm_writei);
    PCM_ALSA_LOCATE(pcm_drain);
    PCM_ALSA_LOCATE(pcm_drop);
    PCM_ALSA_LOCATE(pcm_resume);
  }

  if ((pcm = malloc(sizeof(*pcm)))) {
    int result;

    if (!*device) device = "default";
    if ((result = pcmAlsa_pcm_open(&pcm->handle, device, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK)) >= 0) {
      pcmAlsa_pcm_nonblock(pcm->handle, 0);

      if ((result = pcmAlsa_pcm_hw_params_malloc(&pcm->hardwareParameters)) >= 0) {
        if ((result = pcmAlsa_pcm_hw_params_any(pcm->handle, pcm->hardwareParameters)) >= 0) {
          if ((result = pcmAlsa_pcm_hw_params_set_access(pcm->handle, pcm->hardwareParameters, SND_PCM_ACCESS_RW_INTERLEAVED)) >= 0) {
            if (configurePcmSampleFormat(pcm, errorLevel)) {
              if (configurePcmSampleRate(pcm, errorLevel)) {
                if (configurePcmChannelCount(pcm, errorLevel)) {
                  pcm->bufferTime = 500000;
                  if ((result = pcmAlsa_pcm_hw_params_set_buffer_time_near(pcm->handle, pcm->hardwareParameters, &pcm->bufferTime, NULL)) >= 0) {
                    pcm->periodTime = pcm->bufferTime / 8;
                    if ((result = pcmAlsa_pcm_hw_params_set_period_time_near(pcm->handle, pcm->hardwareParameters, &pcm->periodTime, NULL)) >= 0) {
                      if ((result = pcmAlsa_pcm_hw_params(pcm->handle, pcm->hardwareParameters)) >= 0) {
                        logMessage(LOG_DEBUG, "ALSA PCM: Chan=%u Rate=%u BufTim=%u PerTim=%u", pcm->channelCount, pcm->sampleRate, pcm->bufferTime, pcm->periodTime);
                        return pcm;
                      } else {
                        logPcmError(errorLevel, "set hardware parameters", result);
                      }
                    } else {
                      logPcmError(errorLevel, "set period time near", result);
                    }
                  } else {
                    logPcmError(errorLevel, "set buffer time near", result);
                  }
                }
              }
            }
          } else {
            logPcmError(errorLevel, "set access", result);
          }
        } else {
          logPcmError(errorLevel, "get hardware parameters", result);
        }

        pcmAlsa_pcm_hw_params_free(pcm->hardwareParameters);
      } else {
        logPcmError(errorLevel, "hardware parameters allocation", result);
      }

      pcmAlsa_pcm_close(pcm->handle);
    } else {
      logPcmError(errorLevel, "open", result);
    }

    free(pcm);
  } else {
    logSystemError("PCM device allocation");
  }

  return NULL;
}
Exemple #11
0
int
createPidFile (const char *path, ProcessIdentifier pid) {
#if defined(GRUB_RUNTIME)
  errno = EROFS;

#else /* create pid file */
  if (!pid) pid = getProcessIdentifier();

  if (path && *path) {
    typedef enum {PFS_ready, PFS_stale, PFS_clash, PFS_error} PidFileState;
    PidFileState state = PFS_error;
    int file = open(path,
                    O_RDWR | O_CREAT,
                    S_IRUSR | S_IWUSR
#ifdef S_IRGRP
                    | S_IRGRP
#endif /* S_IRGRP */
#ifdef S_IROTH
                    | S_IROTH
#endif /* S_IROTH */
                    );

    if (file != -1) {
      int locked = acquireFileLock(file, 1);

      if (locked || (errno == ENOSYS)) {
        char buffer[0X20];
        ssize_t length;

        if ((length = read(file, buffer, sizeof(buffer))) != -1) {
          ProcessIdentifier oldPid;
          char terminator;
          int count;

          if (length == sizeof(buffer)) length -= 1;
          buffer[length] = 0;
          count = sscanf(buffer, "%" SCNpid "%c", &oldPid, &terminator);
          state = PFS_stale;

          if ((count == 1) ||
              ((count == 2) && ((terminator == '\n') || (terminator == '\r')))) {
            if (oldPid == pid) {
              state = PFS_ready;
            } else if (testProcessIdentifier(oldPid)) {
              logMessage(LOG_ERR, "instance already running: PID=%" PRIpid, oldPid);
              state = PFS_clash;
            }
          }
        } else {
          logSystemError("read");
        }

        if (state == PFS_stale) {
          state = PFS_error;

          if (lseek(file, 0, SEEK_SET) != -1) {
            if (ftruncate(file, 0) != -1) {
              length = snprintf(buffer, sizeof(buffer), "%" PRIpid "\n", pid);

              if (write(file, buffer, length) != -1) {
                state = PFS_ready;
              } else {
                logSystemError("write");
              }
            } else {
              logSystemError("ftruncate");
            }
          } else {
            logSystemError("lseek");
          }
        }

        if (locked) releaseFileLock(file);
      }

      close(file);
    } else {
      logMessage(LOG_WARNING, "%s: %s: %s",
                 gettext("cannot open process identifier file"),
                 path, strerror(errno));
    }

    switch (state) {
      case PFS_ready:
        return 1;

      case PFS_clash:
        errno = EEXIST;
        break;

      case PFS_error:
        break;

      default:
        logMessage(LOG_WARNING, "unexpected PID file state: %u", state);
        break;
    }
  }
#endif /* create pid file */

  return 0;
}