ptg10805159
Section 21.5 Source Code 809
53 } else {
54 submit_file(fd, sfd, argv[optind], sbuf.st_size, text);
55 exit(0);
56 }
57 }
58 err_exit(err, "print: can’t contact %s", host);
59 }
60 /*
61 * Send a file to the printer daemon.
62 */
63 void
64 submit_file(int fd, int sockfd, const char *fname, size_t nbytes,
65 int text)
66 {
67 int nr, nw, len;
68 struct passwd *pwd;
69 struct printreq req;
70 struct printresp res;
71 char buf[IOBUFSZ];
72 /*
73 * First build the header.
74 */
75 if ((pwd = getpwuid(geteuid())) == NULL) {
76 strcpy(req.usernm, "unknown");
77 } else {
78 strncpy(req.usernm, pwd->pw_name, USERNM_MAX-1);
79 req.usernm[USERNM_MAX-1]=’\0’;
80 }
[53 – 59] If we areable to connect to the printer spooling daemon, we call
submit_fileto transmit the file we want to print to the daemon. Then we
exit with a value of 0 to indicate success. If we can’t connect to any of the
addresses, we callerr_exitto print an error message and exit with a value of
1 to indicate failure. (AppendixBcontains the source code forerr_exitand
the other error routines.)
[60 – 80] Thesubmit_filefunction sends a print request to the daemon and reads the
response. First, we build theprintreqrequest header.Weusegeteuidto
get the caller’s effective user ID and pass this togetpwuidto look for the user
in the system’s passwordfile. Wecopy the user’s name to the request header
or use the stringunknownif we can’t identify the user.Weusestrncpywhen
copying the name from the passwordfile to avoid writing past the end of the
user name buffer in the request header.Ifthe name is longer than the size of
the buffer,strncpywon’t storeaterminating null byte in the buffer, so we
need to do it ourselves.