/* GIO - GLib Input, Output and Streaming Library
 *
 * Copyright 2004 Ximian Inc.
 * Copyright 2011-2022 systemd contributors
 * Copyright (C) 2018 Endless Mobile, Inc.
 * Copyright 2022 Collabora Ltd.
 *
 * SPDX-License-Identifier: LGPL-2.1-or-later
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General
 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
 *
 * Author: Daniel Drake <drake@endlessm.com>
 */

/*
 * gio-launch-desktop: GDesktopAppInfo helper
 * Executable wrapper to set GIO_LAUNCHED_DESKTOP_FILE_PID
 * There are complications when doing this in a fork()/exec() codepath,
 * and it cannot otherwise be done with posix_spawn().
 * This wrapper is designed to be minimal and lightweight.
 * It does not even link against glib.
 */

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

#if defined(__linux__) && !defined(__BIONIC__)
#include <alloca.h>
#include <errno.h>
#include <stddef.h>
#include <string.h>
#include <syslog.h>
#include <sys/socket.h>
#include <sys/un.h>

#include "gjournal-private.h"
#define GLIB_COMPILATION
#include "gmacros.h" /* For G_STATIC_ASSERT define */
#undef GLIB_COMPILATION

/*
 * write_all:
 * @fd: a file descriptor
 * @vbuf: a buffer
 * @to_write: length of @vbuf
 *
 * Write all bytes from @vbuf to @fd, blocking if necessary.
 *
 * Returns: 0 on success, -1 with errno set on failure
 */
static int
write_all (int fd, const void *vbuf, size_t to_write)
{
  const char *buf = vbuf;

  while (to_write > 0)
    {
      ssize_t count = write (fd, buf, to_write);
      if (count < 0)
        {
          if (errno != EINTR)
            return -1;
        }
      else
        {
          to_write -= count;
          buf += count;
        }
    }

  return 0;
}

/*
 * journal_stream_fd:
 * @identifier: identifier (syslog tag) for logged messages
 * @priority: a priority between `LOG_EMERG` and `LOG_DEBUG` inclusive
 * @level_prefix: if nonzero, journald will interpret prefixes like <0>
 *  as specifying the priority for a line
 *
 * Reimplementation of sd_journal_stream_fd(), to avoid having to link
 * gio-launch-desktop to libsystemd.
 *
 * Note that unlike the libsystemd version, this reports errors by returning
 * -1 with errno set.
 *
 * Returns: a non-negative fd number, or -1 with errno set on error
 */
static int
journal_stream_fd (const char *identifier,
                   int priority,
                   int level_prefix)
{
  union
  {
    struct sockaddr sa;
    struct sockaddr_un un;
  } sa =
  {
    .un.sun_family = AF_UNIX,
    .un.sun_path = "/run/systemd/journal/stdout",
  };
  socklen_t salen;
  char *header;
  int fd;
  size_t l;
  int saved_errno;
  /* Arbitrary large size for the sending buffer, from systemd */
  int large_buffer_size = 8 * 1024 * 1024;

  G_STATIC_ASSERT (LOG_EMERG == 0 && sizeof "Linux ABI defines LOG_EMERG");
  G_STATIC_ASSERT (LOG_DEBUG == 7 && sizeof "Linux ABI defines LOG_DEBUG");

  fd = socket (AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);

  if (fd < 0)
    goto fail;

  salen = offsetof (struct sockaddr_un, sun_path) + strlen (sa.un.sun_path) + 1;

  if (connect (fd, &sa.sa, salen) < 0)
    goto fail;

  if (shutdown (fd, SHUT_RD) < 0)
    goto fail;

  (void) setsockopt (fd, SOL_SOCKET, SO_SNDBUF, &large_buffer_size,
                     (socklen_t) sizeof (large_buffer_size));

  if (identifier == NULL)
    identifier = "";

  if (priority < 0)
    priority = 0;

  if (priority > 7)
    priority = 7;

  l = strlen (identifier);
  header = alloca (l + 1  /* identifier, newline */
                   + 1    /* empty unit ID, newline */
                   + 2    /* priority, newline */
                   + 2    /* level prefix, newline */
                   + 2    /* don't forward to syslog */
                   + 2    /* don't forward to kmsg */
                   + 2    /* don't forward to console */);
  memcpy (header, identifier, l);
  header[l++] = '\n';
  header[l++] = '\n';   /* empty unit ID */
  header[l++] = '0' + priority;
  header[l++] = '\n';
  header[l++] = '0' + !!level_prefix;
  header[l++] = '\n';
  header[l++] = '0';    /* don't forward to syslog */
  header[l++] = '\n';
  header[l++] = '0';    /* don't forward to kmsg */
  header[l++] = '\n';
  header[l++] = '0';    /* don't forward to console */
  header[l++] = '\n';

  if (write_all (fd, header, l) < 0)
    goto fail;

  return fd;

fail:
  saved_errno = errno;

  if (fd >= 0)
    close (fd);

  errno = saved_errno;
  return -1;
}

static void
set_up_journal (const char *argv1)
{
  int stdout_is_journal;
  int stderr_is_journal;
  const char *identifier;
  const char *slash;
  int fd;

  stdout_is_journal = _g_fd_is_journal (STDOUT_FILENO);
  stderr_is_journal = _g_fd_is_journal (STDERR_FILENO);

  if (!stdout_is_journal && !stderr_is_journal)
    return;

  identifier = getenv ("GIO_LAUNCHED_DESKTOP_FILE");

  if (identifier == NULL)
    identifier = argv1;

  slash = strrchr (identifier, '/');

  if (slash != NULL && slash[1] != '\0')
    identifier = slash + 1;

  fd = journal_stream_fd (identifier, LOG_INFO, 0);

  /* Silently ignore failure to open the Journal */
  if (fd < 0)
    return;

  if (stdout_is_journal && dup2 (fd, STDOUT_FILENO) != STDOUT_FILENO)
    fprintf (stderr,
             "gio-launch-desktop[%d]: Unable to redirect \"%s\" to Journal: %s",
             getpid (),
             identifier,
             strerror (errno));

  if (stderr_is_journal && dup2 (fd, STDERR_FILENO) != STDERR_FILENO)
    fprintf (stderr,
             "gio-launch-desktop[%d]: Unable to redirect \"%s\" to Journal: %s",
             getpid (),
             identifier,
             strerror (errno));

  close (fd);
}

#endif

int
main (int argc, char *argv[])
{
  pid_t pid = getpid ();
  char buf[50];
  int r;

  if (argc < 2)
    return -1;

  r = snprintf (buf, sizeof (buf), "GIO_LAUNCHED_DESKTOP_FILE_PID=%ld", (long) pid);
  if (r < 0 || (size_t) r >= sizeof (buf))
    return -1;

  putenv (buf);

#if defined(__linux__) && !defined(__BIONIC__)
  set_up_journal (argv[1]);
#endif

  return execvp (argv[1], argv + 1);
}
