1 /******************************************************************************
2     (c) 2000-2003 Christine Caulfield                 christine.caulfield@googlemail.com
3 
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     any later version.
8 
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13 ******************************************************************************/
14 #include <sys/types.h>
15 #include <sys/stat.h>
16 #include <sys/fcntl.h>
17 #include <sys/utsname.h>
18 #include <string.h>
19 #include <time.h>
20 #include <stdio.h>
21 #include <unistd.h>
22 
23 #include "utils.h"
24 
add_string(unsigned char * packet,int * ptr,const unsigned char * string)25 void add_string(unsigned char *packet, int *ptr,
26 		const unsigned char *string)
27 {
28     int len = strlen((char *)string);
29 
30     packet[(*ptr)++] = len;
31     strcpy((char *)packet + *ptr, (char *)string);
32     *ptr += len;
33 }
34 
get_string(unsigned char * packet,int * ptr,unsigned char * string)35 void get_string(unsigned char *packet, int *ptr,
36 		unsigned char *string)
37 {
38     int len = packet[(*ptr)++];
39 
40     strncpy((char*)string, (char*)packet + *ptr, len);
41     string[len] = '\0';
42     *ptr += len;
43 }
44 
45 #ifdef VERBOSE_DEBUG
chrissie_debuglog(char * fmt,...)46 void chrissie_debuglog(char *fmt, ...)
47 {
48     static time_t starttime = time(NULL);
49     va_list ap;
50 
51     fprintf(stderr, "%5ld: ", time(NULL)-starttime);
52     va_start(ap, fmt);
53     vfprintf(stderr, fmt, ap);
54 }
55 #endif
56 
57 
58 #ifndef HAVE_OPENPTY
chrissie_openpty(int * master,int * slave,char * a,char * b,char * d)59 int chrissie_openpty(int *master, int *slave, char *a, char *b, char *d)
60 {
61     char ptyname[] = "/dev/ptyCP";
62     char c;
63     char *line=NULL;
64     int i;
65     int pty=-1, t;
66     int gotpty=0;
67     struct stat stb;
68 
69     for (c='p'; c <= 'z'; c++)
70     {
71 	line = ptyname;
72 	line[strlen("/dev/pty")] = c;
73 	line[strlen("/dev/ptyC")] = '0';
74 	if (stat(line,&stb) < 0)
75 	    break;
76 	for (i=0; i < 16; i++)
77 	{
78 	    line[strlen("/dev/ptyC")]= "0123456789abcdef"[i];
79 	    if ( (pty=open(line,O_RDWR)) > 0)
80 	    {
81 		gotpty = 1;
82 		break;
83 	    }
84 	}
85 	if (gotpty) break;
86     }
87 
88     if (!gotpty)
89     {
90 	debuglog(("No ptys available for connection"));
91 	return -1;
92     }
93 
94 
95     line[strlen("/dev/")] = 't';
96     if ( (t=open(line,O_RDWR)) < 0)
97     {
98 	debuglog(("Error connecting to physical terminal: %m"));
99 	return -1;
100     }
101     *master = pty;
102     *slave = t;
103     return 0;
104 }
105 #endif
106 
107 /* Expand \ sequences in /etc/issue.net file and add CRs to
108    LFs */
expand_issue(const char * original,int len,char * newstring,int maxlen,const char * servicename)109 int expand_issue(const char *original, int len, char *newstring, int maxlen,
110 		 const char *servicename)
111 {
112     int i,j;
113     char scratch[132];
114     time_t t;
115     struct tm *tm;
116     struct utsname un;
117 
118     uname(&un);
119 
120     j=0;
121     for (i=0; i<len; i++)
122     {
123 	if (j >= maxlen) break;
124 
125 	if (original[i] == '\n')
126 	    newstring[j++] = '\r';;
127 
128 	if (original[i] == '\\' || original[i] == '%')
129 	{
130 	    i++;
131 	    switch (original[i])
132 	    {
133 	    case '\\':
134 	    case '%':
135 		newstring[j++] = original[i];
136 		break;
137 
138 	    case 'b':
139 		strcpy(newstring+j, "9600");
140 		j+=4;
141 		break;
142 
143 	    case 'd':
144 		t = time(NULL);
145 		tm = localtime(&t);
146 		strftime(scratch, sizeof(scratch), "%a %b %d  %Y", tm);
147 		strcpy(newstring+j, scratch);
148 		j+=strlen(scratch);
149 		break;
150 
151 	    case 's':
152 		strcpy(newstring+j, un.sysname);
153 		j+=strlen(un.sysname);
154 		break;
155 
156 	    case 'l':
157 		strcpy(newstring+j, servicename);
158 		j+=strlen(servicename);
159 		break;
160 
161 	    case 'm':
162 		strcpy(newstring+j, un.machine);
163 		j+=strlen(un.machine);
164 		break;
165 
166 	    case 'n':
167 		strcpy(newstring+j, un.nodename);
168 		j+=strlen(un.nodename);
169 		break;
170 
171 #ifdef __GNU_SOURCE
172 	    case 'o':
173 		strcpy(newstring+j, un.domainname);
174 		j+=strlen(un.domainname);
175 		break;
176 #endif
177 	    case 'r':
178 		strcpy(newstring+j, un.release);
179 		j+=strlen(un.release);
180 		break;
181 
182 	    case 't':
183 		t = time(NULL);
184 		tm = localtime(&t);
185 		strftime(scratch, sizeof(scratch), "%H:%M:%S", tm);
186 		strcpy(newstring+j, scratch);
187 		j+=strlen(scratch);
188 		break;
189 
190  /* No, I am not doing number of users logged in... */
191 	    case 'v':
192 		strcpy(newstring+j, un.version);
193 		j+=strlen(un.version);
194 		break;
195 	    }
196 	}
197 	else
198 	{
199 	    newstring[j++] = original[i];
200 	}
201     }
202 
203     return j;
204 }
205