- Mitglied seit
- 22 Apr 2007
- Beiträge
- 12,343
- Punkte für Reaktionen
- 1
- Punkte
- 0
Im [THREAD=232493]Thread über steuerbare Steckdosenleisten[/THREAD] kam die Idee auf, [POST=1783099]einen Drucker einzuschalten, wenn ein Druckjob an die Box kommt[/POST].
Hier erstmal ein einfacher Ansatz dazu.
Im Prinzip muss so ein Printserver nicht viel tun. Auf eingehende Verbindungen warten, diese annehmen und die Daten an den Drucker weiter geben.
Das kann man so machen:
Bei AVM gibt es dafür gleich 4 Prozesse, ich weiß nicht, warum die das so kompliziert gemacht haben. Die Optionen sind mit Absicht kompatibel zu denen von AVM gewählt. Man könnte/sollte noch an einigen Stellen auf Fehler prüfen, außerdem geht das Programm nicht von selbst in den Hintergrund, aber das Programm sollte so funktionieren. Ich habe aber keinen USB-Drucker an der Box, um das zu testen.
Vor und nach jedem Druckauftrag wird printserv-job aufgerufen, einmal mit start und einmal mit end als Parameter. Bei Start könnte man den Drucker einschalten und 30 Sekunden warten, oder wie lang auch immer der Drucker braucht. Bei End kann man festhalten, dass der Druckauftrag zu Ende ist, und dafür sorgen, dass der Drucker irgendwann ausgeschaltet wird, wenn keine neuen Aufträge kommen.
Bei AVM wird auch noch eine Datei /var/log/printer_status erstellt. Wenn jemand herausfindet, was dort zu verschiedenen Gelegenheiten drin steht, kann man das auch ergänzen.
Hier erstmal ein einfacher Ansatz dazu.
Im Prinzip muss so ein Printserver nicht viel tun. Auf eingehende Verbindungen warten, diese annehmen und die Daten an den Drucker weiter geben.
Das kann man so machen:
Code:
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
int
main (int argc, char **argv)
{
int opt;
u_short port = 9100;
char const *device = "/dev/usblp0";
char const *logfile = "/dev/stdout";
int fd_listen;
int ret;
int int_val;
struct sockaddr_in sin;
while ((opt = getopt (argc, argv, "d:p:c:h")) != EOF)
switch (opt) {
case 'd':
device = optarg;
break;
case 'p':
port = atoi (optarg);
break;
case 'c':
logfile = optarg;
break;
}
fd_listen = socket (PF_INET, SOCK_STREAM, 0);
int_val = 1;
ret = setsockopt (fd_listen, SOL_SOCKET, SO_REUSEADDR, &int_val, sizeof (int_val));
sin.sin_family = AF_INET;
sin.sin_port = htons (port);
sin.sin_addr.s_addr = INADDR_ANY;
ret = bind (fd_listen, (struct sockaddr *)&sin, sizeof (sin));
ret = listen (fd_listen, 1);
ret = fork ();
if (ret < 0) {
perror ("fork");
exit (1);
}
if (ret > 0)
exit (0);
setsid ();
for (;;) {
int fd_accept, fd_printer;
char buf[0x1000];
fd_accept = accept (fd_listen, NULL, NULL);
ret = system ("printserv-job start");
fd_printer = open (device, O_WRONLY);
while ((ret = read (fd_accept, buf, sizeof (buf))) > 0) {
write (fd_printer, buf, ret);
}
close (fd_printer);
close (fd_accept);
ret = system ("printserv-job end");
}
}
Vor und nach jedem Druckauftrag wird printserv-job aufgerufen, einmal mit start und einmal mit end als Parameter. Bei Start könnte man den Drucker einschalten und 30 Sekunden warten, oder wie lang auch immer der Drucker braucht. Bei End kann man festhalten, dass der Druckauftrag zu Ende ist, und dafür sorgen, dass der Drucker irgendwann ausgeschaltet wird, wenn keine neuen Aufträge kommen.
Bei AVM wird auch noch eine Datei /var/log/printer_status erstellt. Wenn jemand herausfindet, was dort zu verschiedenen Gelegenheiten drin steht, kann man das auch ergänzen.
Zuletzt bearbeitet: