File: misc.c

package info (click to toggle)
scheme48 1.8%2Bdfsg-1%2Bdeb7u1
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 14,984 kB
file content (169 lines) | stat: -rw-r--r-- 3,937 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
/* Copyright (c) 1993-2008 by Richard Kelsey and Jonathan Rees.
   See file COPYING. */

#include <stdio.h>
#include <stdlib.h>		/* for getenv(), etc. (POSIX?/ANSI) */
#include <string.h>		/* for strncpy(), etc. (POSIX/ANSI) */
#include <pwd.h>		/* for getpwnam() (POSIX.1) */
#include <unistd.h>		/* for sysconf(), etc.  (POSIX.1/.2)*/
#include <errno.h>
#include <sys/stat.h>
#include <locale.h>		/* ISO C99 */
#include "sysdep.h"
#include "c-mods.h"


/*
   Expanding Unix filenames
   Unix Sucks
   Richard Kelsey Wed Jan 17 21:40:26 EST 1990
   Later modified by others who wish to remain anonymous

   Expands initial ~ and ~/ in string `name', leaving the result in `buffer'.
   `buffer_len' is the length of `buffer'.

   Note: strncpy(x, y, n) copies from y to x.
*/

char *s48_expand_file_name (char *name, char *buffer, int buffer_len)
{
#define USER_NAME_SIZE 256
  char *dir, *p, user_name[USER_NAME_SIZE];
  struct passwd *user_data;
  int dir_len, i;
  int name_len = strlen(name);

  dir = 0;

  if (name[0] == '~') {
    name++; name_len--;

    if (name[0] == '/' || name[0] == 0) {
      dir = getenv("HOME"); }

    else {
      for (i = 0, p = name; i < name_len && *p != '/'; i++, p++)
	if (i > (USER_NAME_SIZE - 2)) {
	  fprintf(stderr,
		  "\ns48_expand_file_name: user name longer than %d characters\n",
		  USER_NAME_SIZE - 3);
	  return(NULL); };
      strncpy(user_name, name, i);
      user_name[i] = 0;
      user_data = getpwnam(user_name);
      if (!user_data) {
	fprintf(stderr, "\ns48_expand_file_name: unknown user \"%s\"\n",
		user_name);
	return(NULL); };
      name_len -= i;
      name = p;
      dir = user_data->pw_dir; } }

  else if (name[0] == '$') {
    name++; name_len--;

    for (i = 0, p = name; i < name_len && *p != '/'; i++, p++)
      if (i > (USER_NAME_SIZE - 2)) {
	fprintf(stderr,
		"\ns48_expand_file_name: environment variable longer than %d characters\n",
		USER_NAME_SIZE - 3);
	return(NULL); };
    strncpy(user_name, name, i);
    user_name[i] = 0;

    name_len -= i;
    name = p;
    dir = getenv(user_name); }

  if (dir) {
    dir_len = strlen(dir);
    if ((name_len + dir_len + 1) > buffer_len) {
      fprintf(stderr, "\ns48_expand_file_name: supplied buffer is too small\n");
      return(NULL); };
    strncpy(buffer, dir, dir_len);
    strncpy(buffer + dir_len, name, name_len);
    buffer[name_len + dir_len] = 0; }

  else {
    if ((name_len + 1) > buffer_len) {
      fprintf(stderr, "\ns48_expand_file_name: supplied buffer is too small\n");
      return(NULL); };
    strncpy(buffer, name, name_len);
    buffer[name_len] = 0; }

  return(buffer);
}

/* test routine
main(argc, argv)
  int argc;
  char *argv[];
{
  char buffer[32];
  s48_expand_file_name(argv[1], buffer, 32);
  printf("%s\n", buffer);
  return(0);
}
*/


/* Driver loop for tail-recursive calls */

long s48_return_value;

long
s48_run_machine(long (*proc) (void))
{
  while (proc != 0)
    proc = (long (*) (void)) (*proc)();
  return s48_return_value;
}

unsigned char *
ps_error_string(long the_errno)
{
  return((unsigned char *)strerror(the_errno));
}

/* Getting the length of a file. */

long
s48_get_file_size(unsigned char *name)
{
  struct stat file_data;
  int status;
  
  if (-1 == stat((char*)name, &file_data) ||
      ! S_ISREG(file_data.st_mode))
    return -1;
  else
    return file_data.st_size;
}

/* encoding of argv */

char*
s48_get_os_string_encoding(void)
{
  static char setlocale_called = PSFALSE;
  char *codeset;
  static char* encoding = NULL;

  /* Mike has no clue what the rationale for needing this is. */
  if (!setlocale_called)
    {
      setlocale(LC_CTYPE, "");
      setlocale_called = PSTRUE;
    }

  if (encoding == NULL)
    {
      codeset = nl_langinfo(CODESET); /* this ain't reentrant */
      encoding = malloc(strlen(codeset) + 1);
      if (encoding == NULL)
	return NULL;
      strcpy(encoding, codeset);
    }

  return encoding;
}