chiark / gitweb /
c2c53b8d07eaa8b9a2e092c4ec45faf4c15a4ae7
[sympathy.git] / src / serial.c
1 /*
2  * serial.c:
3  *
4  * Copyright (c) 2008 James McKenzie <james@fishsoup.dhs.org>,
5  * All rights reserved.
6  *
7  */
8
9 static char rcsid[] = "$Id$";
10
11 /*
12  * $Log$
13  * Revision 1.3  2008/02/15 03:32:07  james
14  * *** empty log message ***
15  *
16  * Revision 1.2  2008/02/14 16:21:17  james
17  * *** empty log message ***
18  *
19  * Revision 1.1  2008/02/14 12:51:14  james
20  * *** empty log message ***
21  *
22  * Revision 1.4  2008/02/14 10:39:14  james
23  * *** empty log message ***
24  *
25  * Revision 1.3  2008/02/13 09:12:21  james
26  * *** empty log message ***
27  *
28  * Revision 1.2  2008/02/12 22:36:46  james
29  * *** empty log message ***
30  *
31  * Revision 1.1  2008/02/09 15:47:28  james
32  * *** empty log message ***
33  *
34  * Revision 1.2  2008/02/07 11:11:14  staffcvs
35  * *** empty log message ***
36  *
37  * Revision 1.1  2008/02/07 01:02:52  james
38  * *** empty log message ***
39  *
40  * Revision 1.3  2008/02/06 17:53:28  james
41  * *** empty log message ***
42  *
43  * Revision 1.2  2008/02/04 02:05:06  james
44  * *** empty log message ***
45  *
46  * Revision 1.1  2008/02/04 01:32:39  james
47  * *** empty log message ***
48  *
49  */
50
51 #include "project.h"
52 #include <pwd.h>
53 #include <dirent.h>
54 #include <sys/stat.h>
55
56 #define LOCK_ASCII
57 #undef LOCK_BINARY
58
59 #define NLOCKFILES      10
60
61 typedef struct
62 {
63   char *lockfiles[NLOCKFILES];
64   char *potential_lockfiles[NLOCKFILES];
65   struct timeval last_content_check;
66 } Serial_lock;
67
68 typedef struct
69 {
70   TTY_SIGNATURE;
71   Serial_lock lock;
72   int fd;
73 } Serial;
74
75
76
77 static int
78 chown_uucp (fd)
79      int fd;
80 {
81   static int uuid = -1, ugid;
82   struct passwd *pw;
83
84   if (uuid < 0)
85     {
86       if (pw = getpwnam ("uucp"))
87         {
88           uuid = pw->pw_uid;
89           ugid = pw->pw_gid;
90         }
91       else
92         {
93           return -1;
94         }
95     }
96   return fchown (fd, uuid, ugid);
97 }
98
99 int
100 make_lockfile (char *name)
101 {
102   char buf[1024], tmpfn[1024];
103   char *ptr;
104   int fd;
105   int i;
106
107   strcpy (tmpfn, name);
108
109   ptr = rindex (tmpfn, '/');
110   if (!ptr)
111     return -1;
112
113   ptr++;
114
115   ptr += sprintf (ptr, "LTMP.%d", getpid ());
116   *ptr = 0;
117
118   i = sprintf (buf, "%10d\n", getpid ());
119
120   fd = open (tmpfn, O_WRONLY | O_CREAT | O_TRUNC, 0444);
121   if (fd < 0)
122     {
123       unlink (tmpfn);
124       return -1;
125     }
126
127   write (fd, buf, i);
128   fchmod (fd, 044);
129   if (chown_uucp (fd))
130     {
131       close (fd);
132       unlink (tmpfn);
133       return -1;
134     }
135
136   close (fd);
137
138   if (link (tmpfn, name) < 0)
139     {
140       unlink (tmpfn);
141       return -1;
142     }
143
144   unlink (tmpfn);
145   return 0;
146 }
147
148
149
150 void
151 construct_lock_file_name_by_name (char *ptr)
152 {
153
154   printf ("lock by file %s\n", ptr);
155
156 }
157
158 void
159 construct_lock_file_name_by_device (dev_t dev)
160 {
161
162   printf ("lock by dev %x\n", dev);
163 }
164
165
166 #define DEV "/dev/"
167 int
168 construct_possible_lock_files (char *device)
169 {
170   int nl;
171   struct dirent *de;
172   DIR *d;
173   struct stat dev_stat, ent_stat;
174   char buf[1024];
175
176
177   if (stat (device, &dev_stat))
178     return -1;
179   if (!S_ISCHR (dev_stat.st_mode))
180     return -1;
181
182   construct_lock_file_name_by_device (dev_stat.st_rdev);
183
184   construct_lock_file_name_by_name (device);
185
186   for (d = opendir (DEV); (de = readdir (d));)
187     {
188       strcpy (buf, DEV);
189       strcat (buf, de->d_name);
190
191       if (stat (buf, &ent_stat))
192         continue;
193       if (!S_ISCHR (ent_stat.st_mode))
194         continue;
195       if (ent_stat.st_rdev != dev_stat.st_rdev)
196         continue;
197
198       construct_lock_file_name_by_name (buf);
199
200     }
201   closedir (d);
202
203 }
204
205
206 static void
207 serial_check_lock (Serial * t)
208 {
209 }
210
211
212 static void
213 serial_close (TTY * _t)
214 {
215   Serial *t = (Serial *) _t;
216
217   if (!t)
218     return;
219
220   close (t->fd);
221   free (t);
222 }
223
224
225
226 static int
227 serial_read (TTY * _t, void *buf, int len)
228 {
229   Serial *t = (Serial *) _t;
230   int red, done = 0;
231
232   serial_check_lock (t);
233   if (t->blocked)
234     return 0;
235
236   do
237     {
238
239       red = wrap_read (t->fd, buf, len);
240       if (red < 0)
241         return -1;
242       if (!red)
243         return done;
244
245       buf += red;
246       len -= red;
247       done += red;
248     }
249   while (len);
250
251
252   return done;
253 }
254
255
256 static int
257 ptty_write (TTY * _t, void *buf, int len)
258 {
259   int writ, done = 0;
260   Serial *t = (Serial *) _t;
261
262   serial_check_lock (t);
263   if (t->blocked)
264     return 0;
265
266   do
267     {
268
269       writ = wrap_write (t->fd, buf, len);
270       if (writ < 0)
271         return -1;
272       if (!writ)
273         sleep (1);
274
275       buf += writ;
276       len -= writ;
277       done += writ;
278     }
279   while (len);
280
281
282   return done;
283 }
284
285 TTY *
286 serial_open (char *path)
287 {
288   Serial *t;
289   pid_t child;
290   char name[1024];
291   struct winsize winsize = { 0 };
292   struct termios termios;
293   int fd;
294
295
296   default_termios (&termios);
297
298   fd = open (path, O_RDWR);
299
300   set_nonblocking (fd);
301
302   t = (Serial *) malloc (sizeof (Serial));
303
304   strncpy (t->name, path, sizeof (t->name));
305   t->name[sizeof (t->name) - 1] = 0;
306
307   t->recv = serial_read;
308   //t->xmit = serial_write;
309   t->close = serial_close;
310   t->fd = fd;
311   t->rfd = t->fd;
312   t->wfd = t->fd;
313   t->size.x = VT102_COLS;
314   t->size.y = VT102_ROWS;
315   t->blocked = 0;
316
317   return (TTY *) t;
318 }