Mailing Lists: Apple Mailing Lists

Image of Mac OS face in stamp
 
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Finding my $DISPLAY programatically.



I think I found a solution to this using suggestions from those who replied (see below).

I know some of you may find it annoying that I don't want to use ssh for this but I have several hundred SCO UNIX systems throughout the UK installed over the last sixteen years, each ranging from 3 to 100 users and only the recent ones are accessible by broadband.

The Macs are used as work stations, they're imaged, the IP address is set-up then they're installed on site. If one breaks (two or three die and need re-imaging each month) we image another and send it out as a user swap item. We need static IP addresses as the IP address tells the server which room and site you're in so that printers can be assigned by location and private data can be hidden if the screen is defined as one that the public can see rather than a back-office screen.

The Macs don't know the users or their passwords on the server, when fired up for the first time they download the menu from the server which defines the remote commands to run via rexec for various parts of the system and all that it required is a user name and password.

I've cobbled together some code below that when compiled will return the DISPLAY as required from a remote host.

This code works for my situation and hasn't had much testing, and I need to tidy it up. It doesn't work for the root user and probably won't work if you have multiple network cards or multiple IP addresses. It also only works on IPv4 but then I don't know if X11 will take an IPv6 IP address in DISPLAY.

Thanks for your help everybody. Regards, Rob.

Compile using: gcc xdpyspec.m -framework CoreFoundation -framework Foundation -o xdpyspec

// xdpyspec.m
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/sysctl.h>
#include <Foundation/Foundation.h>

#define L_IPAddress (16)  // IPv4

typedef struct kinfo_proc kinfo_proc;

static void usage (void);
static void processArgs (int argc, char **argv);
static char *getIPAddress (void);
static int strcntchr (const char *, char);
static int doProcessing (int argc, char **argv);
static pid_t findXquartz (void);
static bool getScreenForPID (pid_t pid, int *screen);

static char *programName;

int main (int argc, char **argv)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
int r;

   r = doProcessing (argc, argv);

   [pool release];
   return (r);
}

static int doProcessing (int argc, char **argv)
{
char *p;
int   screen = 0;
pid_t pid;

   processArgs (argc, argv);

   if ((pid = findXquartz ()) == 0)
      {
      fprintf (stderr, "Failed to locate Xquartz process\n");
      return (1);
      }

   if ((p = getIPAddress ()) == (char *) 0L)
      return (1);

   getScreenForPID (pid, &screen);

   printf ("%s:%d.0\n", p, screen);

   return (0);
}

static char *getIPAddress ()
{
static char buffer [L_IPAddress + 1];
NSArray *a;
int      i;
const char *p;

   // Add our own IP Address.
   a = [[NSHost currentHost] addresses];
   for (i = 0; i < [a count]; i ++)
      {
      if ((p = [[a objectAtIndex:i] cString]) == (const char *) 0L)
         continue;

      if (strcmp (p, "127.0.0.1") == 0)
         continue;

      if (strchr (p, ':'))
         continue;

      if (strcntchr (p, '.') == 3)
         {
         strcpy (buffer, p);
         return (buffer);
         }
      }
   return ((char *) 0L);
}


static pid_t findXquartz () { pid_t pid = 0; kinfo_proc *procs = (kinfo_proc *) 0L; size_t count = 0; size_t i; uid_t uid;

   uid = getuid ();

   if (GetBSDProcessList (&procs, &count) != 0)
      return (0);

   for (i = 0; i < count; i ++)
      {

// Compare the process name and don't get confused if another user
// is running the same process (check uid).
if (strcmp (procs [i].kp_proc.p_comm, "Xquartz") == 0 &&
procs [i].kp_eproc.e_pcred.p_ruid == uid)
{
pid = procs [i].kp_proc.p_pid;
break;
}
}


   free (procs);
   return (pid);
}

//  GetBSDProcessList() (c)Apple from Apple Example Code
//  See http://developer.apple.com/qa/qa2001/qa1123.html
int GetBSDProcessList (kinfo_proc **procList, size_t *procCount)
{
int               err;
kinfo_proc       *result;
bool              done;
static const int  name [] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0 };
size_t            length;

   *procCount = 0;

   result = NULL;
   done = false;
   do {
      // Call sysctl with a NULL buffer.
      length = 0;
      if ((err = sysctl ((int *) name,
                         (sizeof (name) / sizeof (*name)) - 1,
                         NULL, &length,
                         NULL, 0)) == -1)
         err = errno;

      // Allocate an appropriately sized buffer based on the results
      // from the previous call.
      if (err == 0)
         if ((result = malloc (length)) == NULL)
            err = ENOMEM;

      // Call sysctl again with the new buffer.  If we get an ENOMEM
      // error, toss away our buffer and start again.
      if (err == 0)
         {
         if ((err = sysctl ((int *) name,
                            (sizeof (name) / sizeof (*name)) - 1,
                            result,
                            &length,
                            NULL, 0)) == -1)
            err = errno;

         if (err == 0)
            done = true;
         else if (err == ENOMEM)
            {
            free (result);
            result = NULL;
            err = 0;
            }
         }

      } while (err == 0 && ! done);

   // Clean up and establish post conditions.
   if (err != 0 && result != NULL)
      {
      free (result);
      result = NULL;
      }

   *procList = result;
   if (err == 0)
      *procCount = length / sizeof (kinfo_proc);

   return (err);
}

static bool getScreenForPID (pid_t pid, int *screen)
{
char buffer [128];
char field [128];
FILE *fp;
pid_t xpid;
char *p;
int   scrn;
bool  r = 0;

  if ((fp = popen ("lsof", "r")) == (FILE *) 0L)
      return (0);

   while (fgets (buffer, 127, fp))
      {
      if (sscanf (buffer, "%*s %d\n", &xpid) != 1 || xpid != pid)
         continue;

      if (sscanf (buffer, "%*s %*s %*s %*s %s\n", field) != 1)
         continue;

      if (strcmp (field, "IPv4") != 0)
         continue;

      if ((p = strrchr (buffer, ':')) == (char *) 0L)
         continue;

      p ++;

      scrn = atoi (p);

      if (scrn >= 6000)
         {
         *screen = scrn - 6000;
         r = 1;
         }
      }

   fclose (fp);
   return (r);
}


static int strcntchr (const char *str, char c) { int count = 0; const char *p = str;

   while (*p)
      if (*p ++ == c)
         count ++;

   return (count);
}

static void processArgs (int argc, char **argv)
{
int i;
char *p;

   // Sort out the program name.
   programName = argv [0];
   if ((p = strrchr (programName, '/')))
      programName = p + 1;

#ifdef __Never
   for (i = 1 ; i < argc ; i ++)
      if (argv [i][0] == '-')
         switch (argv [i][1])
            {
            case
            }
#endif
}

static void usage ()
{
   fprintf (stderr, "usage: %s \n", programName);
   exit (1);
}

_______________________________________________
Do not post admin requests to the list. They will be ignored.
X11-users mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/x11-users/email@hidden

This email sent to email@hidden
References: 
 >Finding my $DISPLAY programatically. (From: Robert Tillyard <email@hidden>)



Visit the Apple Store online or at retail locations.
1-800-MY-APPLE

Contact Apple | Terms of Use | Privacy Policy

Copyright © 2007 Apple Inc. All rights reserved.