/* * tiny-lpd.c - a tiny printer daemon. Runs in the background, and * sends any files queued in its spool directory to the printer. */ #include /* standard I/O routines. */ #include /* various type definitions. */ #include /* general SysV IPC structures */ #include /* semaphore functions and structs. */ #include /* access(), etc. */ #include /* malloc(), etc. */ #include /* strlen(), etc. */ #include /* opendir(), DIR, struct dirent, etc. */ #include "tiny-lp-common.h" /* common tiny spooler definitions/functions. */ /* * function: print_file. send a given file to the printer for printing. * intput: file path. * output: none. */ void print_file(char* file_path) { /* in a real printer daemon, here would come all the nasty */ /* tasks of communicating with the printer using a postscript */ /* driver or some other interface..... */ /* perhaps you'd like to try implementing this yourself? */ printf("tiny-lpd: 'printed' file '%s'\n", file_path); } /* * function: main. perform the whole operation. * intput: none. * output: messages regarding success or failure of operations. */ void main(int argc, char* argv[]) { int sem_set_id; /* ID of the semaphore set. */ DIR* spool_dir; /* spool directory contents struct. */ struct dirent* dir_entry; /* one entry of spool directory. */ char file_source[MAX_PATH]; /* path to file we operate on. */ char file_target[MAX_PATH]; /* path to file after copying to 'out'. */ int found; /* was a file found in the dir. scan? */ /* create the semaphore set for the tiny spooling system. */ sem_set_id = sem_set_get("tiny-lpd", 1); if (sem_set_id == -1) { fprintf(stderr, "tiny-lpd: Error initializing. aborting.\n"); exit(1); } /* perform a loop of waiting on the 'counter' semaphore, */ /* and handling one file at a time. */ while (1) { /* wait until at least one file is found in the spool area. */ sem_wait_counter(sem_set_id); /* lock the mutex semaphore, to assure exclusive access to */ /* the common spool directory. */ sem_wait_mutex(sem_set_id); spool_dir = opendir(SPOOL_DIR_COMMON); if (!spool_dir) { fprintf(stderr, "%s: Failed opening directory '%s': ", argv[0], SPOOL_DIR_COMMON); perror(""); fprintf(stderr, "%s: aborting.\n", argv[0]); exit(1); } /* start reading the directory's contents. */ found = 0; while ( (dir_entry = readdir(spool_dir)) != NULL) { /* skip the '.' and '..' entries. */ if (strcmp(dir_entry->d_name, ".") == 0) continue; if (strcmp(dir_entry->d_name, "..") == 0) continue; /* we found a file. */ found = 1; /* move file to 'out' spool sub-directory. */ sprintf(file_source, "%s/%s", SPOOL_DIR_COMMON, dir_entry->d_name); sprintf(file_target, "%s/%s", SPOOL_DIR_OUT, dir_entry->d_name); if (rename(file_source, file_target) == -1) { fprintf(stderr, "%s: cannot move file '%s/%s' to '%s':\n", argv[0], SPOOL_DIR_COMMON, dir_entry->d_name, SPOOL_DIR_OUT); perror(""); fprintf(stderr, "%s: aborting.\n", argv[0]); exit(1); } /* free the mutex semaphore. */ sem_signal_mutex(sem_set_id); /* finally, print the file, and remove it. */ print_file(file_target); unlink(file_target); } if (!found) { /* no file. maybe another tiny-lpd process grabed it? */ /* free the mutex semaphore. */ sem_signal_mutex(sem_set_id); } } /* NOT REACHED */ }