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