/* * serial.c: * * Copyright (c) 2008 James McKenzie , * All rights reserved. * */ static char rcsid[] = "$Id$"; /* * $Log$ * Revision 1.3 2008/02/15 03:32:07 james * *** empty log message *** * * Revision 1.2 2008/02/14 16:21:17 james * *** empty log message *** * * Revision 1.1 2008/02/14 12:51:14 james * *** empty log message *** * * Revision 1.4 2008/02/14 10:39:14 james * *** empty log message *** * * Revision 1.3 2008/02/13 09:12:21 james * *** empty log message *** * * Revision 1.2 2008/02/12 22:36:46 james * *** empty log message *** * * Revision 1.1 2008/02/09 15:47:28 james * *** empty log message *** * * Revision 1.2 2008/02/07 11:11:14 staffcvs * *** empty log message *** * * Revision 1.1 2008/02/07 01:02:52 james * *** empty log message *** * * Revision 1.3 2008/02/06 17:53:28 james * *** empty log message *** * * Revision 1.2 2008/02/04 02:05:06 james * *** empty log message *** * * Revision 1.1 2008/02/04 01:32:39 james * *** empty log message *** * */ #include "project.h" #include #include #include #define LOCK_ASCII #undef LOCK_BINARY #define NLOCKFILES 10 typedef struct { char *lockfiles[NLOCKFILES]; char *potential_lockfiles[NLOCKFILES]; struct timeval last_content_check; } Serial_lock; typedef struct { TTY_SIGNATURE; Serial_lock lock; int fd; } Serial; static int chown_uucp (fd) int fd; { static int uuid = -1, ugid; struct passwd *pw; if (uuid < 0) { if (pw = getpwnam ("uucp")) { uuid = pw->pw_uid; ugid = pw->pw_gid; } else { return -1; } } return fchown (fd, uuid, ugid); } int make_lockfile (char *name) { char buf[1024], tmpfn[1024]; char *ptr; int fd; int i; strcpy (tmpfn, name); ptr = rindex (tmpfn, '/'); if (!ptr) return -1; ptr++; ptr += sprintf (ptr, "LTMP.%d", getpid ()); *ptr = 0; i = sprintf (buf, "%10d\n", getpid ()); fd = open (tmpfn, O_WRONLY | O_CREAT | O_TRUNC, 0444); if (fd < 0) { unlink (tmpfn); return -1; } write (fd, buf, i); fchmod (fd, 044); if (chown_uucp (fd)) { close (fd); unlink (tmpfn); return -1; } close (fd); if (link (tmpfn, name) < 0) { unlink (tmpfn); return -1; } unlink (tmpfn); return 0; } void construct_lock_file_name_by_name (char *ptr) { printf ("lock by file %s\n", ptr); } void construct_lock_file_name_by_device (dev_t dev) { printf ("lock by dev %x\n", dev); } #define DEV "/dev/" int construct_possible_lock_files (char *device) { int nl; struct dirent *de; DIR *d; struct stat dev_stat, ent_stat; char buf[1024]; if (stat (device, &dev_stat)) return -1; if (!S_ISCHR (dev_stat.st_mode)) return -1; construct_lock_file_name_by_device (dev_stat.st_rdev); construct_lock_file_name_by_name (device); for (d = opendir (DEV); (de = readdir (d));) { strcpy (buf, DEV); strcat (buf, de->d_name); if (stat (buf, &ent_stat)) continue; if (!S_ISCHR (ent_stat.st_mode)) continue; if (ent_stat.st_rdev != dev_stat.st_rdev) continue; construct_lock_file_name_by_name (buf); } closedir (d); } static void serial_check_lock (Serial * t) { } static void serial_close (TTY * _t) { Serial *t = (Serial *) _t; if (!t) return; close (t->fd); free (t); } static int serial_read (TTY * _t, void *buf, int len) { Serial *t = (Serial *) _t; int red, done = 0; serial_check_lock (t); if (t->blocked) return 0; do { red = wrap_read (t->fd, buf, len); if (red < 0) return -1; if (!red) return done; buf += red; len -= red; done += red; } while (len); return done; } static int ptty_write (TTY * _t, void *buf, int len) { int writ, done = 0; Serial *t = (Serial *) _t; serial_check_lock (t); if (t->blocked) return 0; do { writ = wrap_write (t->fd, buf, len); if (writ < 0) return -1; if (!writ) sleep (1); buf += writ; len -= writ; done += writ; } while (len); return done; } TTY * serial_open (char *path) { Serial *t; pid_t child; char name[1024]; struct winsize winsize = { 0 }; struct termios termios; int fd; default_termios (&termios); fd = open (path, O_RDWR); set_nonblocking (fd); t = (Serial *) malloc (sizeof (Serial)); strncpy (t->name, path, sizeof (t->name)); t->name[sizeof (t->name) - 1] = 0; t->recv = serial_read; //t->xmit = serial_write; t->close = serial_close; t->fd = fd; t->rfd = t->fd; t->wfd = t->fd; t->size.x = VT102_COLS; t->size.y = VT102_ROWS; t->blocked = 0; return (TTY *) t; }