Example #1
0
static void
GiveSystemInfo(void)
{
    int rv;
    char buf[4096];

    rv = syssgi(SGI_SYSID, &buf[0]);
    if (rv > 0) {
	RNG_RandomUpdate(buf, MAXSYSIDSIZE);
    }
#ifdef SGI_RDUBLK
    rv = syssgi(SGI_RDUBLK, getpid(), &buf[0], sizeof(buf));
    if (rv > 0) {
	RNG_RandomUpdate(buf, sizeof(buf));
    }
#endif /* SGI_RDUBLK */
    rv = syssgi(SGI_INVENT, SGI_INV_READ, buf, sizeof(buf));
    if (rv > 0) {
	RNG_RandomUpdate(buf, sizeof(buf));
    }
    rv = sysinfo(SI_MACHINE, buf, sizeof(buf));
    if (rv > 0) {
	RNG_RandomUpdate(buf, rv);
    }
    rv = sysinfo(SI_RELEASE, buf, sizeof(buf));
    if (rv > 0) {
	RNG_RandomUpdate(buf, rv);
    }
    rv = sysinfo(SI_HW_SERIAL, buf, sizeof(buf));
    if (rv > 0) {
	RNG_RandomUpdate(buf, rv);
    }
}
Example #2
0
int
set_job(job *pjob, struct startjob_rtn *sjr)

{
	extern	char	noglobid[];
	char		cvtbuf[20];

	if (pjob->ji_globid == NULL ||
		strcmp(pjob->ji_globid, noglobid) == 0) {
		if (newarraysess() == -1) {
			sprintf(log_buffer, "newarraysess failed %d", errno);
			return (-2);
		}
		sjr->sj_ash = getash();
	}
	else {
		if (sscanf(pjob->ji_globid, "%llx", &sjr->sj_ash) != 1) {
			sprintf(log_buffer, "invalid global id %s",
				pjob->ji_globid);
			return (-2);
		}
		if (syssgi(SGI_JOINARRAYSESS, -1, &sjr->sj_ash) == -1) {
			sprintf(log_buffer, "cannot set ash %llx err %d",
				sjr->sj_ash, errno);
			return (-2);
		}
	}

	if (set_sgi_proj(pjob->ji_wattr[(int)JOB_ATR_euser].at_val.at_str,
		&pjob->ji_wattr[(int)JOB_ATR_account]) < 0) {
		(void)sprintf(log_buffer, "Invalid project id");
		return (-3);
	}
	return (sjr->sj_session = setsid());
}
Example #3
0
// Timer Method Definitions
Timer::Timer()
{
#if defined( IRIX ) || defined( IRIX64 )
	// IRIX Timer Initialization
	__psunsigned_t phys_addr, raddr;
	int poffmask = getpagesize() - 1;
	int counterSize = syssgi(SGI_CYCLECNTR_SIZE);
	
	phys_addr = syssgi(SGI_QUERY_CYCLECNTR, &(cycleval));
	if (phys_addr == ENODEV) {
		Severe( "Sorry, this SGI doesn't support timers." );
	}
	
	raddr = phys_addr & ~poffmask;
	fd = open("/dev/mmem", O_RDONLY);
	
	if (counterSize == 64) {
		iotimer_addr64 =
			(volatile iotimer64_t *)mmap(0, poffmask, PROT_READ,
			MAP_PRIVATE, fd, (off_t)raddr);
		unmapLocation = (void *)iotimer_addr64;
		unmapSize = poffmask;
		iotimer_addr64 = (iotimer64_t *)((__psunsigned_t)iotimer_addr64 +
				(phys_addr & poffmask));
	}
	else if (counterSize == 32) {
		iotimer_addr32 = (volatile iotimer32_t *)mmap(0, poffmask, PROT_READ,
				MAP_PRIVATE, fd,
				(off_t)raddr);
		unmapLocation = (void *)iotimer_addr32;
		unmapSize = poffmask;
		iotimer_addr32 = (iotimer32_t *)((__psunsigned_t)iotimer_addr32 +
				(phys_addr & poffmask));
	}
	else {
		Severe( "Fatal timer init error" );
	}
#elif defined( WIN32 )
	// Windows Timer Initialization
	QueryPerformanceFrequency( &performance_frequency );
	one_over_frequency = 1.0/((double)performance_frequency.QuadPart);
#endif
	time0 = elapsed = 0;
	running = 0;
}
Example #4
0
/**
 * @brief
 *	start_hammer() - Entry point for the unauthoized user hammer routine.  
 *	This function fork()s a child, which then runs the hammer_loop() routine.  
 *	The parent returns immediately.  The child will exit when the hammer_loop is killed.
 *
 * @param[in] secs - time in secs for halting hammer_loop
 *
 * @return	pid_t
 * @retval	-1 on error, 
 * @retval	otherwise the pid of the hammer thread.
 */
pid_t
start_hammer(int secs)
{
	char		*id = "start_hammer";
	pid_t		pid, parent;
	int			rc;

	parent = getpid();  /* PID that will parent the child */

	/*
	 * Fork a new process that will watch for user processes that are not
	 * controlled by mom.  These processes will be killed without mercy.
	 */
	pid = fork();

	if (pid == -1) {
		log_err(errno, id, "cannot fork hammer process.");
		return -1;
	}

	/* If still in original process, return the child's PID to the caller. */
	if (pid != 0)
		return pid;

	/* ======================================================================
	 * This is the child.  Hammer loop starts here.
	 */

#ifdef  SGI_SETPSARGS
	/*
	 * Change the psargs field of this process to a more useful string.
	 * This is a custom modification which is only cosmetic.  Ignore any
	 * error or result codes.
	 */
	(void)syssgi(SGI_SETPSARGS, HAMMER_NAME, strlen(HAMMER_NAME));

#endif  /* SGI_SETPSARGS */

	/* Close un-necessary file descriptors inherited from main mom. */
	(void)close_inherited();

	if (secs)
		sleep(secs);	/* Sleep if requested, then start the hammer loop. */

	rc = hammer_loop(mom_shared, parent);   /* Run hammer loop.  */

	/*
	 * hammer_loop() should not return, except in exceptional circumstances.
	 * It normally calls exit() on its own.
	 */
	exit(rc);

	/* NOTREACHED */
}
Example #5
0
void
_u_sysclock_restart()
{
	__psunsigned_t vbase,  raddr, phys_addr;
	unsigned int pico_per_clk;
	int cycsz;
	int fd;
	int page;
	int poffmask;
	if (!_init_hw_clock_called)
		return;
	if (_rtc_clockaddr != NULL) {
		page	= getpagesize();
		poffmask = page - 1;
		phys_addr = syssgi(SGI_QUERY_CYCLECNTR, &pico_per_clk);
		cycsz	= syssgi(SGI_CYCLECNTR_SIZE);
		raddr	= phys_addr & ~poffmask;
		fd	= open("/dev/mmem", O_RDONLY);
		vbase	= (__psunsigned_t)_rtc_clockaddr & ~poffmask;
		mmap((void *)vbase, page, PROT_READ,
			MAP_PRIVATE | MAP_FIXED, fd, (off_t) raddr);
	}
	return;
}
Example #6
0
int
main(
	int		argc,
	char		**argv)
{
#ifdef __sgi
	xfs_fsop_geom_t	geom;
	char		*uuid_str;
	u_int		status;
#endif
	char		*name;
	int		fd;
	void		*fshanp;
	size_t		fshlen;
	char		buffer[100];

	if (argc != 2) {
		fprintf(stderr, "usage:	%s path\n", argv[0]);
		exit(1);
	}
	Progname = argv[0];
	(void)dm_init_service(&name);

	if (dm_path_to_fshandle(argv[1], &fshanp, &fshlen) != 0) {
		fprintf(stderr, "dm_path_to_fshandle failed, %s\n",
			strerror(errno));
	}
	hantoa(fshanp, fshlen, buffer);

	if ((fd = open(argv[1], O_RDONLY)) < 0) {
		fprintf(stderr, "Open of %s failed, %s\n", argv[1],
			strerror(errno));
		exit(1);
	}

#ifdef __sgi
	syssgi(SGI_XFS_FSOPERATIONS, fd, XFS_FS_GEOMETRY, NULL, &geom);

	uuid_to_string(&geom.uuid, &uuid_str, &status);

	fprintf(stdout, "fshandle %s, uuid %s, %s\n",
		buffer, uuid_str, argv[1]);
#endif
	fprintf(stdout, "fshandle %s, %s\n",
		buffer, argv[1]);
	exit(0);
}
Example #7
0
static size_t GetHighResClock(void *buf, size_t maxbuf)
{
    unsigned phys_addr, raddr, cycleval;
    static volatile unsigned *iotimer_addr = NULL;
    static int tries = 0;
    static int cntr_size;
    int mfd;
    long s0[2];
    struct timeval tv;

#ifndef SGI_CYCLECNTR_SIZE
#define SGI_CYCLECNTR_SIZE      165     /* Size user needs to use to read CC */
#endif

    if (iotimer_addr == NULL) {
	if (tries++ > 1) {
	    /* Don't keep trying if it didn't work */
	    return 0;
	}

	/*
	** For SGI machines we can use the cycle counter, if it has one,
	** to generate some truly random numbers
	*/
	phys_addr = syssgi(SGI_QUERY_CYCLECNTR, &cycleval);
	if (phys_addr) {
	    int pgsz = getpagesize();
	    int pgoffmask = pgsz - 1;

	    raddr = phys_addr & ~pgoffmask;
	    mfd = open("/dev/mmem", O_RDONLY);
	    if (mfd < 0) {
		return 0;
	    }
	    iotimer_addr = (unsigned *)
		mmap(0, pgoffmask, PROT_READ, MAP_PRIVATE, mfd, (int)raddr);
	    if (iotimer_addr == (void*)-1) {
		close(mfd);
		iotimer_addr = NULL;
		return 0;
	    }
	    iotimer_addr = (unsigned*)
		((__psint_t)iotimer_addr | (phys_addr & pgoffmask));
	    /*
	     * The file 'mfd' is purposefully not closed.
	     */
	    cntr_size = syssgi(SGI_CYCLECNTR_SIZE);
	    if (cntr_size < 0) {
		struct utsname utsinfo;

		/* 
		 * We must be executing on a 6.0 or earlier system, since the
		 * SGI_CYCLECNTR_SIZE call is not supported.
		 * 
		 * The only pre-6.1 platforms with 64-bit counters are
		 * IP19 and IP21 (Challenge, PowerChallenge, Onyx).
		 */
		uname(&utsinfo);
		if (!strncmp(utsinfo.machine, "IP19", 4) ||
		    !strncmp(utsinfo.machine, "IP21", 4))
			cntr_size = 64;
		else
			cntr_size = 32;
	    }
	    cntr_size /= 8;	/* Convert from bits to bytes */
	}
    }

    s0[0] = *iotimer_addr;
    if (cntr_size > 4)
	s0[1] = *(iotimer_addr + 1);
    memcpy(buf, (char *)&s0[0], cntr_size);
    return CopyLowBits(buf, maxbuf, &s0, cntr_size);
}
Example #8
0
void
GetNameInfo(void)
{
    int i, found = false;
    char *sp, *sp2;
    time_t tloc;
    struct hostent *hp;
    struct sockaddr_in cin;
#ifdef AIX
    char real_version[_SYS_NMLN];
#endif
#ifdef IRIX
    char real_version[256]; /* see <sys/syssgi.h> */
#endif
#ifdef HAVE_SYSINFO
#ifdef SI_ARCHITECTURE
    long sz;
#endif
#endif

    Debug("GetNameInfo()\n");

    g_vfqname[0] = g_vuqname[0] = '\0';

    if (uname(&g_vsysname) == -1) {
        perror("uname ");
        FatalError("Uname couldn't get kernel name info!!\n");
    }

#ifdef AIX
    snprintf(real_version, _SYS_NMLN, "%.80s.%.80s",
            g_vsysname.version, g_vsysname.release);
    strncpy(g_vsysname.release, real_version, _SYS_NMLN);
#elif defined IRIX
/* This gets us something like `6.5.19m' rather than just `6.5'.  */
    syssgi (SGI_RELEASE_NAME, 256, real_version);
#endif

    for (sp = g_vsysname.sysname; *sp != '\0'; sp++) {
        *sp = ToLower(*sp);
    }

    for (sp = g_vsysname.machine; *sp != '\0'; sp++) {
        *sp = ToLower(*sp);
    }

    for (i = 0; g_classattributes[i][0] != '\0'; i++) {

        if (WildMatch(g_classattributes[i][0],
                    ToLowerStr(g_vsysname.sysname))) {

            if (WildMatch(g_classattributes[i][1], 
                        g_vsysname.machine)) {

                if (WildMatch(g_classattributes[i][2], 
                            g_vsysname.release)) {

                    if (g_underscore_classes) {
                        snprintf(g_vbuff, CF_BUFSIZE, "_%s", g_classtext[i]);
                        AddClassToHeap(g_vbuff);
                    } else {
                        AddClassToHeap(g_classtext[i]);
                    }
                    found = true;
                    g_vsystemhardclass = (enum classes) i;
                    break;
                }
            } else {
                Debug2("Cfengine: I recognize %s but not %s\n",
                        g_vsysname.sysname, g_vsysname.machine);
                    continue;
            }
        }
   }

    if ((sp = malloc(strlen(g_vsysname.nodename)+1)) == NULL) {
        FatalError("malloc failure in initialize()");
    }

    strcpy(sp, g_vsysname.nodename);
    SetDomainName(sp);

    /* Truncate fully qualified name */
    for (sp2=sp; *sp2 != '\0'; sp2++) {
        if (*sp2 == '.') {
            *sp2 = '\0';
            Debug("Truncating fully qualified hostname %s to %s\n",
                    g_vsysname.nodename,sp);
            break;
        }
    }

    g_vdefaultbinserver.name = sp;

    AddClassToHeap(CanonifyName(sp));


    if ((tloc = time((time_t *)NULL)) == -1) {
        printf("Couldn't read system clock\n");
    }

    if (g_verbose || g_debug || g_d2 || g_d3) {
        if (g_underscore_classes) {
            snprintf(g_vbuff, CF_BUFSIZE, "_%s", g_classtext[i]);
        } else {
            snprintf(g_vbuff, CF_BUFSIZE, "%s", g_classtext[i]);
        }

        if (g_iscfengine) {
            printf ("cfng: configuration agent (cfagent) - \n%s\n%s\n\n",
                    VERSION, g_copyright);
        } else {
            printf ("cfng: configuration server (cfservd) - \n%s\n%s\n\n",
                    VERSION, g_copyright);
        }

        printf ("------------------------------------------------------------------------\n\n");
        printf ("Host name is: %s\n", g_vsysname.nodename);
        printf ("Operating System Type is %s\n", g_vsysname.sysname);
        printf ("Operating System Release is %s\n", g_vsysname.release);
        printf ("Architecture = %s\n\n\n", g_vsysname.machine);
        printf ("Using internal soft-class %s for host %s\n\n",
                g_vbuff, g_classtext[g_vsystemhardclass]);
        printf ("The time is now %s\n\n", ctime(&tloc));
        printf ("------------------------------------------------------------------------\n\n");

    }

    sprintf(g_vbuff, "%d_bit", sizeof(long)*8);
    AddClassToHeap(g_vbuff);
    Verbose("Additional hard class defined as: %s\n", CanonifyName(g_vbuff));

    snprintf(g_vbuff, CF_BUFSIZE, "%s_%s", g_vsysname.sysname,
            g_vsysname.release);
    AddClassToHeap(CanonifyName(g_vbuff));

#ifdef IRIX
    /* 
     * Get something like `irix64_6_5_19m' defined as well as
     * `irix64_6_5'.  Just copying the latter into g_vsysname.release
     * wouldn't be backwards-compatible.
     */
    snprintf(g_vbuff, CF_BUFSIZE, "%s_%s", g_vsysname.sysname, real_version);
    AddClassToHeap(CanonifyName(g_vbuff));
#endif

    AddClassToHeap(CanonifyName(g_vsysname.machine));

    Verbose("Additional hard class defined as: %s\n",CanonifyName(g_vbuff));

    snprintf(g_vbuff, CF_BUFSIZE,"%s_%s", g_vsysname.sysname,
            g_vsysname.machine);
    AddClassToHeap(CanonifyName(g_vbuff));

    Verbose("Additional hard class defined as: %s\n",CanonifyName(g_vbuff));

    snprintf(g_vbuff, CF_BUFSIZE, "%s_%s_%s",
            g_vsysname.sysname, g_vsysname.machine, g_vsysname.release);

    AddClassToHeap(CanonifyName(g_vbuff));

    Verbose("Additional hard class defined as: %s\n", CanonifyName(g_vbuff));

#ifdef HAVE_SYSINFO
#ifdef SI_ARCHITECTURE
    sz = sysinfo(SI_ARCHITECTURE, g_vbuff, CF_BUFSIZE);
    if (sz == -1) {
        Verbose("cfagent internal: sysinfo returned -1\n");
    } else {
        AddClassToHeap(CanonifyName(g_vbuff));
        Verbose("Additional hard class defined as: %s\n", g_vbuff);
    }
#endif
#endif

    snprintf(g_vbuff, CF_BUFSIZE, "%s_%s_%s_%s",
            g_vsysname.sysname, g_vsysname.machine, g_vsysname.release,
            g_vsysname.version);

    if (strlen(g_vbuff) < CF_MAXVARSIZE-2) {
        g_varch = strdup(CanonifyName(g_vbuff));
    } else {

        Verbose("cfagent internal: $(arch) overflows CF_MAXVARSIZE! Truncating\n");
        g_varch = strdup(CanonifyName(g_vsysname.sysname));
    }

    snprintf(g_vbuff, CF_BUFSIZE, "%s_%s",
            g_vsysname.sysname, g_vsysname.machine);

    g_varch2 = strdup(CanonifyName(g_vbuff));

    AddClassToHeap(g_varch);

    Verbose("Additional hard class defined as: %s\n", g_varch);

    if (! found) {

        CfLog(cferror,"Cfengine: I don't understand "
                "what architecture this is!","");

    }

    strcpy(g_vbuff, "compiled_on_");
    strcat(g_vbuff, CanonifyName(AUTOCONF_SYSNAME));

    AddClassToHeap(CanonifyName(g_vbuff));

    Verbose("\nGNU autoconf class from compile time: %s\n\n", g_vbuff);

    /* Get IP address from nameserver */
    if ((hp = gethostbyname(g_vsysname.nodename)) == NULL) {
        return;
    } else {
        memset(&cin, 0, sizeof(cin));
        cin.sin_addr.s_addr = ((struct in_addr *)(hp->h_addr))->s_addr;
        Verbose("Address given by nameserver: %s\n", inet_ntoa(cin.sin_addr));
        strcpy(g_vipaddress, inet_ntoa(cin.sin_addr));

        for (i=0; hp->h_aliases[i] != NULL; i++) {
            Debug("Adding alias %s..\n", hp->h_aliases[i]);
            AddClassToHeap(CanonifyName(hp->h_aliases[i]));
        }
    }
}
Example #9
0
/*
 *	_init_hw_clock - initializes the exported clock variables.
 */
void
_init_hw_clock(void)
{
	__psunsigned_t phys_addr, raddr;
	int cycsz;
	int fd;
	int poffmask;
	unsigned int pico_per_clk;
	void *clockaddr;

	if (_init_hw_clock_called != 0)
		return;

	_init_hw_clock_called	= 1;

	/* register event handlers for checkpoint and restart.
	 * These are available at 6.4.
	 */
	if (atcheckpoint && atrestart) {
		if (atcheckpoint(_u_sysclock_checkpoint) < 0) {
			/* checkpoint registration failed,
			 * returns -1, errno = error
			 */
			return;
		}
		if (atrestart(_u_sysclock_restart) < 0) {
			/* restart registration failed,
			 * returns -1, errno = error
			 */
			return;
		}
	}

	/*
 	 * Assume gettimeofday granularity for now. 
	 */
	_fast_cycles_per_sec	= 1000000.; 
	_nowrap_cycles_per_sec	= 1000000.; 

	poffmask	= getpagesize() - 1;
	phys_addr	= syssgi(SGI_QUERY_CYCLECNTR, &pico_per_clk);
	cycsz	= syssgi(SGI_CYCLECNTR_SIZE);
	raddr	= phys_addr & ~poffmask;
	fd	= open("/dev/mmem", O_RDONLY);
	if (fd < 0) {
		/* could not open /dev/mmem !! */
		return;
	}
	clockaddr = mmap(0, poffmask, PROT_READ, MAP_PRIVATE, fd, (off_t)raddr);
	if ((void*)clockaddr == MAP_FAILED) {
		/* no HW clock */
		return;
	}

	clockaddr = (void *)((__psunsigned_t)clockaddr + (phys_addr&poffmask));

	if (cycsz == 64) {
		_rtc_clockaddr	= (long long *)clockaddr;
		_rtc_clockaddr32	= (int *)clockaddr + 1;
		_nowrap_cycles_per_sec	=
			1.0 / ( (double)pico_per_clk * 1.0e-12 );
	}
	else {  /* if (cycsz == 32) */
		_rtc_clockaddr32	= (int *)clockaddr;
	}

	_fast_cycles_per_sec = 1.0 / ( (double)pico_per_clk * 1.0e-12 );
}
Example #10
0
int
main(
	int	argc,
	char	**argv)
{
	xfs_fsop_geom_t	geom;
	struct	fsxattr	fsx;
	struct	dioattr	dio;
	char	*pathname;
	u_int	buflen;
	char	*buf;
	ssize_t	offset;
	ssize_t	count;
	int	fd;
	int	i;

	if (prog = strrchr(argv[0], '/')) {
		*prog++;
	} else {
		prog = argv[0];
	}

	if (argc != 2)
		Usage();
	pathname = argv[1];

	/* Create the file. */

	if ((fd = open(pathname, O_RDWR|O_CREAT|O_EXCL|O_DIRECT, 0600)) < 0) {
		fprintf(stderr,"%s: Cannot open %s, %s\n", prog,
			pathname, strerror(errno));
		exit(1);
	}

	/* Determine the filesystem's realtime partition geometry. */

	if (syssgi(SGI_XFS_FSOPERATIONS, fd, XFS_FS_GEOMETRY, NULL, &geom)) {
		fprintf(stderr,"%s: syssgi(,XFS_FS_GEOMETRY) failed, %s\n",
			prog, strerror(errno));
		exit(1);
	}

	/* Make the file a realtime file. */

	fsx.fsx_xflags = 1; /*XFS_XFLAG_REALTIME*/
	fsx.fsx_extsize = 4 * geom.blocksize * geom.rtextsize;
	if (fcntl(fd, F_FSSETXATTR, &fsx) < 0) {
		fprintf(stderr,"%s: fcntl(,F_FSSETXATTR) failed, %s\n", prog,
			strerror(errno));
		exit(1);
	}

	/* Obtain the direct I/O parameters. */

	if (fcntl(fd, F_DIOINFO, &dio) < 0) {
		fprintf(stderr,"%s: fcntl(,F_DIOINFO) failed,%s\n",
			prog, strerror(errno));
		exit(1);
	}
	fprintf(stdout, "%s: file %s direct io requirements.\n", prog,
		pathname);
	fprintf(stdout, "%7d memory alignment.\n", dio.d_mem);
	fprintf(stdout, "%7d minimum io size.\n", dio.d_miniosz);
	fprintf(stdout, "%7d maximum io size.\n", dio.d_maxiosz);

	if (fcntl(fd, F_FSGETXATTR, &fsx) < 0) {
		fprintf(stderr,"%s: fcntl(,F_FSGETXATTR) failed, %s\n", prog,
			strerror(errno));
		exit(1);
	}
	fprintf(stdout, "%7d realtime extent size.\n", fsx.fsx_extsize);

	/* Malloc and zero a buffer to use for writes. */

	buflen = dio.d_miniosz;
	if ((buf = memalign(dio.d_mem, buflen)) == NULL) {
		fprintf(stderr,"%s: memalign(%d,%d) returned NULL\n",
				prog, dio.d_mem, buflen);
		exit(1);
	}
	memset(buf, '\0', buflen);

	for (i = 0; i < 10; i += 2) {
		offset = i * fsx.fsx_extsize;
		if (lseek(fd, offset, SEEK_SET) < 0) {
			fprintf(stderr, "seek to %d failed, %s\n", offset,
				strerror(errno));
			exit(1);
		}
		if ((count = write(fd, buf, buflen)) < 0) {
			fprintf(stderr, "write of %d bytes failed at offset "
				"%d, , %s\n", buflen, offset, strerror(errno));
			exit(1);
		}
		if (count != buflen) {
			fprintf(stderr, "expected to write %d bytes at offset "
				"%d, actually wrote %d\n", buflen, offset,
				count);
			exit(1);
		}
	}
	exit(0);
}
Example #11
0
Elf32_Addr
elfmap(char *path, int infd, int opts) {

  int numloadseg = 0, i;
  Elf32_Ehdr *pEhdr;
  Elf32_Phdr *pPhdr;
  Elf32_Phdr *pPload=0, *ptr_first_text_page=0, *pPtemp;
  em_environ e;
  void *baseaddr;
  long map_diff;


  if (!infd && !path) {
    error("No file specified.");
    return( _EM_ERROR );
  }

  if (!infd) {
    /* Open file */
    DPRINTF("elfmap: opening file %s, opt = 0x%x\n", path, opts);
    e.state = INITIAL_STATE;

    if ((infd = open(path, O_RDONLY)) == -1) {
      if (!(_EM_SILENT&opts)) perror("elfmap");
      cleanup(&e, 0, 0);
      return(_EM_ERROR);
    }
  } 

  e.state = FILE_OPEN;
  e.infd = infd;
  e.options = opts;

  /* Read and verify Elf Header */
  DPRINTF("elfmap: reading ELF header.\n");
  pEhdr = getEhdr(&e);
  if (e.state != EH_SUCCESS) {
    cleanup(&e, pEhdr, 0);
    return(_EM_ERROR);
  }

  /* Read program header */
  DPRINTF("elfmap: reading program header\n");
  pPhdr = getPhdr(pEhdr, &e);
  if (e.state != PH_SUCCESS) {
    error("Couldn't read Program header in %s.", path);
    cleanup(&e, pEhdr, pPhdr);
    return( _EM_ERROR );
  }

#ifndef OLD_SYSCALL
  if ((pPload = (Elf32_Phdr *)malloc(pEhdr->e_phnum * sizeof(Elf32_Phdr))) == NULL)
    error ("elfmap: cannot malloc for pPload");
  
  for (i = 0; i<pEhdr->e_phnum; i++) {
    if (pPhdr[i].p_type == PT_LOAD) {
	memcpy(&pPload[numloadseg], &pPhdr[i], sizeof(Elf32_Phdr));
	numloadseg++;
    }
  }

  if (numloadseg == 0) {
    error("elfmap: no PT_LOAD segment found in %s.", path);
    cleanup(&e, pEhdr, pPhdr);
    return(_EM_ERROR);
  }
      
  baseaddr = (void *) syssgi(SGI_ELFMAP, e.infd, pPload, numloadseg);
  if ((long)baseaddr < 0) {
    error("elfmap: couldn't map file %s -- error code %d.", path, errno);
    cleanup(&e, pEhdr, pPhdr);
    return(_EM_ERROR);
  } 
  /* success! */
  /* Now we need to find the real ELF header.  This is complicated by the
   * fact that it ain't necessarily at the beginning of the first segment,
   * but rather is at the beginning of the segment which starts at offset
   * 0 in the file.  If no such offset, punt.
   */
  map_diff = (long) baseaddr - (long)pPload->p_vaddr;
  
  pPtemp = pPload;
  for (i = 0; i < numloadseg; i++) {
      if ((ptr_first_text_page == 0) || (pPtemp->p_offset < ptr_first_text_page->p_offset)) {
	 if (pPtemp->p_flags & (PF_X))	/* text segment */
	     ptr_first_text_page = pPtemp;
      }
      pPtemp++;
  }

  baseaddr = (void *)((ptr_first_text_page->p_vaddr) + 
		map_diff - ptr_first_text_page->p_offset);
  free(pPload);
#else
    
  DPRINTF("elfmap: allocating isMapped array\n");
  e.isMapped = (int *) calloc(pEhdr->e_phnum, sizeof(int));
  if (e.isMapped == NULL) {
    cleanup(&e, pEhdr, pPhdr);
    return( _EM_ERROR );
  }
  e.state = ISMAP_ALLOC;

  /* Map the segments */
  DPRINTF("elfmap: mapping segments\n");
  mapSegs(pEhdr, pPhdr, &e);
  if (e.state != MAP_SUCCESS) {
    baseaddr = (void *) _EM_ERROR;
  } else {
    baseaddr = e.retval;
  }
#endif
  cleanup(&e, pEhdr, pPhdr);
  return((Elf32_Addr) baseaddr);
}