./print blah.pcl yields I don't know how to convert from file type pcl to pcl. conversion_path returns a list of programs. But there's no way to distinguish 'no path exists' from 'no conversion necessary'. 20020904 Clear up the permission structure. One uid to control the device, one to control the queue directory. Queue directory can be setgid; then you can add your own files to it, delete your own files from it, but not delete anyone else's files. Possible security problem with this model: Someone could hardlink the password file into the spool directory; it would then be printed. But since printd has low permissions, and can't read the password file, it will fail to print the password file, and in general can only print world-readable files. But there's a secondary security problem: Since printd must read the spooled files, they must be world-readable. But then other people can read them out of the spool. Solution: Spool dir is not world-readable; only group readable. New problem: How to get spool info? Answer1: printq runs setgid and reads spool dir. Answer 2: printd maintains a world-readable data file. 20020904 printd could have a pluggable priority mechanism. Instead of selecting the olds spool file, it could give certain users priority, or keep a dynamic priority table based on how much printing each user had done, so that nobody could hog the printer. 20020904 print's use of 'file' should be more configurable. The format conversion table should be separate from the printd conversion. (print's configuration should be per-user in a .printrc or some such.) Anyone who asks for more 'print' features should be snubbed. The universal answer is 'you can write your own print spooler; all it has to do is copy a file into the spool directory.' ---------------------------------------------------------------- 20020904 queue file should record filenames. or perhaps some arbitrary tage supplied by the user print command. This might (for example) include a page count. Is there some way for the daemon to learn how much was printed? Maybe printlp can report how many bytes it has written so far and printq could include this in the queue report. 20020928 printlp could report a byte count; that might be good enough. ---------------------------------------------------------------- 20020904 Move the fakespool somewhere real. 20020904 Write docs. 20020904 Have 'print' detach from stdin as soon as possible and finish in the background? Then 'acroread' might not wait around until conversion was complete. 20020904 Write 'printrm'. 20020905 There is no printrm yet, but when there is, it will be too hard to use, because printq does not produce any brief, useful identifier that lets you identify jobs. Suggestion: printq can hash the available job information and come up with a short identifier. What about hash collisions? Maybe the identifier should be chosen at the time the job is placed in the spool. ---------------------------------------------------------------- 20020905 Fix the race conditions. Race condition 1: # It seems there is a race condition here. # printd #1 reads the queue and finds that it is empty. # The someone prints a document, which writes a new queue item # and starts printd #2. printd #2 exits because printd #1 is # still running. Then printd #1 exits because the queue was empty. # Now the document is never printed. Race condition 2: print A B C; then while 'print' is converting B, printlp has finished sending A and exits; then printd scans the queue and sees nothing and exits. These may be manifestations of the same thing. For #1, Rocco suggests two semaphores. See 20020815 note in PROJECTS file for details. Maybe this will solve #2 also. 20020815 Rocco Caputo suggests a second semaphore. The protocol is: Try to lock queue semaphore; exit if you can't. Lock device semaphore and wait until you can. Spool all the files to the device. When you think you are printing the last file, release the queue semaphore When you finish printing that file, exit, releasing the device semaphore. Maybe s/printing/about to print/? Otherwise, you might be in the midst of printing the last file; someone spools another file; the new printd exits; you exit. There still seems to be a race condition. Holding the queue semaphore means you promise to take responsibility for anything in the queue. That means that you must rescan the spool *after* you release the semaphore; if you scan the spool first, someone could spool a new job after the scan and before the release, and you have violated the contract. But if you release and then scan, that's OK. Some other printd might come along and grab the queue semaphore, but there's no problem, because you are still holding the device semaphore and will continue to do so. The other printd needs to rescan the queue after it gets the device semaphore, since you might have printed some of the jobs it thought it was responsible for. So the protocol is: 1. Lock queue semaphore; exit if you can't. 2. Lock device semaphore; wait until it is locked. 3. Scan queue. If it's empty, go to 6. 4. Print all printable jobs in the queue 5. Go back to 3. 6. Unlock the queue semaphore 7. Scan the queue one final time and print any jobs you find 8. Exit, releasing the device semaphore ---------------------------------------------------------------- 20020905 Security: Possible Attacks 1. Link someone else's unreadable file into the spool, and have it printed 2. Read the (readable) copy of someone's unreadable file out of the spool 3. Unlink someone else's print job from the spool 4. Rename a print job in the spool, cheating the priority system 5. Quota evasion by depositing files in the spool which will be ignored by printd. Format conversions whould be done in a protected subdirectory of /tmp, not in the spool. One problem that *does not* need to be solved: Don't need to worry much about the spooler picking a spool file name that is already in use. The only way that can realistically happen is if someone has deliberately inserted a spool file with a tampered name. In that case, they deserve to have it overwritten, and we don't care if it is. Exception: If the spool directory is on a network filesystem, two different machines that both share it might try to spool a file with the same name at the same time. Solution: Incorporate the hostname in the spool file. See what maildir format does. In fact, you might like to adopt a maildir-like structure for the spool. Does the spool dir owner need to be different from the device owner? ---------------------------------------------------------------- 20020905 Some shared code file defining the exit codes from printlp, instead of the convention you have now. 20020905 It would be nice if printq could display more information. What is possible here? For example, can we get the original filename into the printq output? Better idea: Have 'print' take a '-j' option that lets the user specify an arbitrary job identifier tag; if omitted, it defaults to the filename. -J can generate a tag at random. 20020905 Yesterday you wanted to get a hardcopy of the Postscript output of a2ps. So you did 'print -ptxt file.ps'. Then you did 'print file.ps' to see the results of the same file. This is a success! With the standard 'magic input filter' approach, you would have had to hack on the PS file to make it look like non-PS to the filter.