#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include "utils.h"
#include "nedit_malloc.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <pwd.h>
#include <X11/Intrinsic.h>
#ifdef HAVE_DEBUG_H
#include "../debug.h"
#endif
#define DEFAULT_NEDIT_HOME ".xnedit"
static char* plainFileNames[
N_FILE_TYPES] = {
"nedit.rc",
"autoload.nm",
"nedit.history",
"search.history",
""};
static void buildFilePath(
char* fullPath,
const char* dir,
const char* file);
static Boolean isDir(
const char* file);
static Boolean isRegFile(
const char* file);
const char* GetCurrentDir(
void)
{
static char curdir[
MAXPATHLEN];
if (!getcwd(curdir, (
size_t)
MAXPATHLEN)) {
perror(
"xnedit: getcwd() fails");
strcpy(curdir,
".");
}
return (curdir);
}
const char* GetHomeDir(
void)
{
const char *ptr;
static char homedir[
MAXPATHLEN]=
"";
struct passwd *passwdEntry;
size_t len;
if (*homedir) {
return homedir;
}
ptr=getenv(
"HOME");
if (!ptr) {
passwdEntry = getpwuid(getuid());
if (passwdEntry && *(passwdEntry->pw_dir)) {
ptr= passwdEntry->pw_dir;
}
else {
perror(
"xnedit: getpwuid() failed ");
exit(
EXIT_FAILURE);
}
}
strncpy(homedir, ptr,
sizeof(homedir)-
1);
homedir[
sizeof(homedir)-
1]=
'\0';
len=strlen(homedir);
if (len>
1 && homedir[len-
1]==
'/') {
homedir[len-
1]=
'\0';
}
return homedir;
}
const char
*GetUserName(
void)
{
#ifdef VMS
return cuserid(
NULL);
#else
const struct passwd *passwdEntry;
static char *userName=
NULL;
if (userName)
return userName;
passwdEntry = getpwuid(getuid());
if (!passwdEntry) {
perror(
"xnedit: getpwuid() failed - reverting to $USER");
return getenv(
"USER");
}
else {
userName=malloc(strlen(passwdEntry->pw_name)+
1);
strcpy(userName, passwdEntry->pw_name);
return userName;
}
#endif
}
const char
*GetNameOfHost(
void)
{
static char hostname[
MAXNODENAMELEN+
1];
static int hostnameFound = False;
if (!hostnameFound) {
#ifdef VMS
int syi_status;
struct dsc$descriptor_s *hostnameDesc;
unsigned long int syiItemCode =
SYI$
_NODENAME;
unsigned long int unused =
0;
unsigned short int hostnameLen =
MAXNODENAMELEN+
1;
hostnameDesc = NulStrWrtDesc(hostname,
MAXNODENAMELEN+
1);
syi_status = lib$getsyi(&syiItemCode, &unused, hostnameDesc, &hostnameLen,
0,
0);
if (syi_status !=
SS$
_NORMAL) {
fprintf(stderr,
"nedit: Error return from lib$getsyi: %d", syi_status);
strcpy(hostname,
"VMS");
}
else
hostname[hostnameLen] =
'\0';
FreeStrDesc(hostnameDesc);
#else
struct utsname nameStruct;
int rc = uname(&nameStruct);
if (rc<
0) {
perror(
"xnedit: uname() failed ");
exit(
EXIT_FAILURE);
}
strcpy(hostname, nameStruct.nodename);
#endif
hostnameFound = True;
}
return hostname;
}
char
*PrependHome(
const char *filename,
char *buf,
size_t buflen)
{
const char *homedir;
size_t home_len, file_len;
homedir=GetHomeDir();
home_len=strlen(homedir);
file_len=strlen(filename);
if ( (home_len+
1+file_len)>=buflen ) {
buf[
0]=
'\0';
}
else {
strcpy(buf, homedir);
strcat(buf,
"/");
strcat(buf, filename);
}
return buf;
}
int Min(
int i1,
int i2)
{
return i1 <= i2 ? i1 : i2;
}
const char* GetRCFileName(
int type)
{
static char rcFiles[
N_FILE_TYPES][
MAXPATHLEN +
1];
static int namesDetermined = False;
if (!namesDetermined)
{
char* nedit_home;
int i;
if ((nedit_home = getenv(
"XNEDIT_HOME")) ==
NULL)
{
char defaultNEditHome[
MAXPATHLEN +
1];
buildFilePath(defaultNEditHome, GetHomeDir(),
DEFAULT_NEDIT_HOME);
if (!isDir(defaultNEditHome))
{
if (mkdir(defaultNEditHome,
0777) !=
0)
{
perror(
"xnedit: Error while creating rc file directory"
" $HOME/" DEFAULT_NEDIT_HOME "\n"
" (Make sure all parent directories exist.)");
return NULL;
}
}
for (i =
0; i <
N_FILE_TYPES; i++)
{
buildFilePath(rcFiles[i], defaultNEditHome, plainFileNames[i]);
}
}
else
{
#ifndef VMS
if (!isDir(nedit_home))
{
if (mkdir(nedit_home,
0777) !=
0)
{
perror(
"xnedit: Error while creating rc file directory $XNEDIT_HOME\n"
"xnedit: (Make sure all parent directories exist.)");
return NULL;
}
}
#endif
for (i =
0; i <
N_FILE_TYPES; i++)
{
buildFilePath(rcFiles[i], nedit_home, plainFileNames[i]);
}
}
namesDetermined = True;
}
return rcFiles[type];
}
static void buildFilePath(
char* fullPath,
const char* dir,
const char* file)
{
if ((
MAXPATHLEN) < strlen(dir) + strlen(file) +
2)
{
fprintf(stderr,
"xnedit: rc file path too long for %s.\n", file);
exit(
EXIT_FAILURE);
}
strcpy(fullPath, dir);
#ifdef VMS
strcat(fullPath,
":");
#else
strcat(fullPath,
"/");
#endif
strcat(fullPath, file);
}
static Boolean isDir(
const char* file)
{
struct stat attribute;
return ((stat(file, &attribute) ==
0) &&
S_ISDIR(attribute.st_mode));
}
static Boolean isRegFile(
const char* file)
{
struct stat attribute;
return ((stat(file, &attribute) ==
0) &&
S_ISREG(attribute.st_mode));
}
void Push(Stack* stack,
const void* value)
{
stackObject* pushee;
if (
NULL == value) {
fprintf(stderr,
"xnedit: Internal error: NULL was pushed.\n");
return;
}
if (
NULL == stack) {
fprintf(stderr,
"xnedit: Internal error: push() called with NULL stack.\n");
return;
}
pushee = (stackObject*) NEditMalloc(
sizeof(stackObject));
pushee->value = (
void*) value;
pushee->next = stack->top;
stack->top = pushee;
(stack->size)++;
return;
}
void* Pop(Stack* stack)
{
stackObject* popee;
void* value;
if (
NULL == stack) {
fprintf(stderr,
"xnedit: Internal error: pop() called with NULL stack.\n");
return NULL;
}
if (
NULL == stack->top) {
return NULL;
}
popee = stack->top;
stack->top = popee->next;
(stack->size)--;
value = popee->value;
NEditFree((
char*) popee);
return value;
}