--- /dev/null
+#include <stdlib.h>
+#include <stdio.h>
+#include <wchar.h>
+#include <wctype.h>
+#include <locale.h>
+
+wchar_t *exclude[] = {
+ L"a",
+ L"an",
+ L"the",
+ L"in",
+ L"to",
+ L"from",
+ L"of",
+ L"and",
+ L"or",
+ NULL
+};
+
+wchar_t *seps = L"-.?!";
+wchar_t *nonseps = L"\'";
+
+void capitalize(wchar_t *str)
+{
+ wchar_t *p, *p2, **ce;
+ int f;
+
+ p = str;
+ f = 1;
+ while(1) {
+ while(!iswalnum(*p)) {
+ if(*p == L'\0')
+ return;
+ if(wcschr(seps, *p) != NULL)
+ f = 1;
+ p++;
+ }
+ p2 = p;
+ while(iswalnum(*p) || (wcschr(nonseps, *p) != NULL)) {
+ *p = towlower(*p);
+ p++;
+ }
+ if(f) {
+ *p2 = towupper(*p2);
+ f = 0;
+ } else {
+ for(ce = exclude; *ce != NULL; ce++) {
+ if(!wcsncmp(*ce, p2, p - p2) && ((*ce)[p - p2] == L'\0'))
+ break;
+ }
+ if(*ce == NULL)
+ *p2 = towupper(*p2);
+ }
+ }
+}
+
+int main(int argc, char **argv)
+{
+ int i;
+ wchar_t buf[256];
+
+ setlocale(LC_ALL, "");
+ if(argc > 1) {
+ for(i = 1; i < argc; i++) {
+ mbstowcs(buf, argv[i], sizeof(buf) / sizeof(*buf));
+ capitalize(buf);
+ fputws(buf, stdout);
+ fputwc(L'\n', stdout);
+ }
+ } else {
+ while(1) {
+ if(fgetws(buf, sizeof(buf) / sizeof(*buf), stdin) == NULL) {
+ if(feof(stdin))
+ break;
+ perror("reading input");
+ return(1);
+ }
+ capitalize(buf);
+ fputws(buf, stdout);
+ }
+ }
+ return(0);
+}
+
+/*
+ * Local Variables:
+ * compile-command: "gcc -Wall -g -o capitalize capitalize.c"
+ * End:
+ */
--- /dev/null
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <termios.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <sys/poll.h>
+#include <sys/select.h>
+#include <signal.h>
+#include <syslog.h>
+
+#define MODEM_DEV "/dev/modem"
+#define PIDFILE "/var/run/cidd.pid"
+#define PORT 5001
+
+int mdm, sock;
+int ibuflen = 0;
+unsigned char ibuf[1024];
+unsigned char tmpbuf[1024];
+fd_set cfds;
+int isdaemon;
+
+void write2(int fd, unsigned char *buf, int len)
+{
+ int ret;
+
+ while(len)
+ {
+ ret = write(fd, buf, len);
+ if(ret < 0)
+ {
+ perror("write");
+ exit(1);
+ }
+ buf += ret;
+ len -= ret;
+ }
+}
+
+void sendcmd(unsigned char *cmd)
+{
+ unsigned char *lbuf;
+
+ lbuf = strcpy(malloc(strlen(cmd) + 3), cmd);
+ strcat(lbuf, "\r\n");
+ write2(mdm, lbuf, strlen(cmd) + 2);
+ free(lbuf);
+}
+
+unsigned char *getline(int block)
+{
+ int i;
+ unsigned char *p;
+ int ret, len;
+ static unsigned char retbuf[1024];
+ struct pollfd pf;
+
+ while(1)
+ {
+ while((p = memchr(ibuf, '\r', ibuflen)) != NULL)
+ {
+ memcpy(retbuf, ibuf, len = (p - ibuf));
+ retbuf[len] = 0;
+ memmove(ibuf, p + 1, ibuflen -= (len + 1));
+ for(p = retbuf; *p; p++)
+ {
+ while(*p == '\n')
+ memmove(p, p + 1, len--);
+ }
+ if(len && (memcmp(retbuf, "AT", 2)))
+ return(retbuf);
+ }
+ if(!block)
+ {
+ pf.fd = mdm;
+ pf.events = POLLIN;
+ pf.revents = 0;
+ if(poll(&pf, 1, 0) == 0)
+ return(NULL);
+ }
+ ret = read(mdm, ibuf + ibuflen, 1024 - ibuflen);
+ if(ret < 0)
+ {
+ perror("read");
+ exit(1);
+ }
+ ibuflen += ret;
+ }
+}
+
+void broadcast(unsigned char *buf, ...)
+{
+ int i;
+ va_list args;
+
+ va_start(args, buf);
+ vsprintf(tmpbuf, buf, args);
+ va_end(args);
+ strcat(tmpbuf, "\n");
+ for(i = 0; i < FD_SETSIZE; i++)
+ {
+ if(FD_ISSET(i, &cfds) && (i != mdm) && (i != sock))
+ write2(i, tmpbuf, strlen(tmpbuf));
+ }
+}
+
+void initmodem(void)
+{
+ sendcmd("ATZ");
+ if(strcmp(getline(1), "OK"))
+ {
+ if(isdaemon)
+ syslog(LOG_CRIT, "Could not reset modem");
+ else
+ fprintf(stderr, "Could not reset modem\n");
+ exit(1);
+ }
+ sendcmd("AT#CID=1");
+ if(strcmp(getline(1), "OK"))
+ {
+ if(isdaemon)
+ syslog(LOG_CRIT, "Could not activate called ID\n");
+ else
+ fprintf(stderr, "Could not activate caller ID\n");
+ exit(1);
+ }
+}
+
+void sighandler(int sig)
+{
+ if(sig == SIGHUP)
+ {
+ initmodem();
+ }
+}
+
+int main(int argc, unsigned char **argv)
+{
+ int i;
+ unsigned char *p;
+ int nsock;
+ int ret;
+ struct sockaddr_in name;
+ struct termios tio;
+ fd_set rfds;
+ FILE *pidst;
+
+ isdaemon = 0;
+ if((mdm = open(MODEM_DEV, O_RDWR)) < 0)
+ {
+ perror(MODEM_DEV);
+ return(1);
+ }
+ if(tcgetattr(mdm, &tio) < 0)
+ {
+ perror("tcgetattr");
+ return(1);
+ }
+ cfmakeraw(&tio);
+ cfsetispeed(&tio, B0);
+ cfsetospeed(&tio, B38400);
+ if(tcsetattr(mdm, TCSANOW, &tio) < 0)
+ {
+ perror("tcsetattr");
+ return(1);
+ }
+ if((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0)
+ {
+ perror("socket");
+ return(1);
+ }
+ name.sin_family = AF_INET;
+ name.sin_port = htons(PORT);
+ name.sin_addr.s_addr = 0;
+ if(bind(sock, (struct sockaddr *)&name, sizeof(name)) < 0)
+ {
+ perror("bind");
+ return(1);
+ }
+ if(listen(sock, 16) < 0)
+ {
+ perror("listen");
+ return(1);
+ }
+ initmodem();
+ signal(SIGHUP, sighandler);
+ if((pidst = fopen(PIDFILE, "w")) == NULL)
+ {
+ perror("open " PIDFILE);
+ exit(1);
+ }
+ daemon(0, 0);
+ fprintf(pidst, "%i\n", getpid());
+ fclose(pidst);
+ openlog("cidd", LOG_PID, LOG_DAEMON);
+ isdaemon = 1;
+ FD_ZERO(&cfds);
+ FD_SET(mdm, &cfds);
+ FD_SET(sock, &cfds);
+ while(1)
+ {
+ rfds = cfds;
+ ret = select(FD_SETSIZE, &rfds, NULL, NULL, NULL);
+ if((ret < 0) && (errno != EINTR))
+ {
+ syslog(LOG_CRIT, "select return %m");
+ return(1);
+ }
+ if(ret > 0)
+ {
+ for(i = 0; i < FD_SETSIZE; i++)
+ {
+ if(FD_ISSET(i, &rfds))
+ {
+ if(i == mdm)
+ {
+ while((p = getline(0)) != NULL)
+ {
+ if(!strcmp(p, "RING"))
+ broadcast("R");
+ if(!memcmp(p, "NMBR = ", 7))
+ {
+ p += 7;
+ broadcast("N%s", p);
+ }
+ }
+ } else if(i == sock) {
+ if((nsock = accept(sock, NULL, 0)) >= 0)
+ FD_SET(nsock, &cfds);
+ } else {
+ if(read(i, tmpbuf, 1024) == 0)
+ {
+ FD_CLR(i, &cfds);
+ close(i);
+ }
+ }
+ }
+ }
+ }
+ }
+}
--- /dev/null
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/ptrace.h>
+#include <errno.h>
+
+unsigned char buf[1024];
+
+int main(int argc, unsigned char **argv)
+{
+ pid_t pid;
+ unsigned long addr1, addr2;
+ int buf;
+
+ if(argc < 4)
+ {
+ fprintf(stderr, "Not enough args\n");
+ return(1);
+ }
+ pid = strtol(argv[1], NULL, 0);
+ addr1 = (unsigned long)strtoll(argv[2], NULL, 0);
+ addr2 = (unsigned long)strtoll(argv[3], NULL, 0);
+ if(ptrace(PTRACE_ATTACH, pid, NULL, NULL))
+ {
+ perror("PTRACE_ATTACH");
+ return(1);
+ }
+ for(; addr1 < addr2; addr1 += sizeof(int))
+ {
+ errno = 0;
+ if(((buf = ptrace(PTRACE_PEEKDATA, pid, (void *)addr1, NULL)) == -1) && errno)
+ {
+ perror("PTRACE_PEEKDATA");
+ if(ptrace(PTRACE_DETACH, pid, NULL, NULL))
+ perror("PTRACE_DETACH");
+ return(1);
+ }
+ if(write(1, &buf, sizeof(buf)) != 4)
+ {
+ perror("write");
+ if(ptrace(PTRACE_DETACH, pid, NULL, NULL))
+ perror("PTRACE_DETACH");
+ return(1);
+ }
+ }
+ if(ptrace(PTRACE_DETACH, pid, NULL, NULL))
+ {
+ perror("PTRACE_DETACH");
+ return(1);
+ }
+ return(0);
+}