printjob.c (94032) | printjob.c (94036) |
---|---|
1/* 2 * Copyright (c) 1983, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 29 unchanged lines hidden (view full) --- 38 The Regents of the University of California. All rights reserved.\n"; 39#endif /* not lint */ 40 41#ifndef lint 42/* 43static char sccsid[] = "@(#)printjob.c 8.7 (Berkeley) 5/10/95"; 44*/ 45static const char rcsid[] = | 1/* 2 * Copyright (c) 1983, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 29 unchanged lines hidden (view full) --- 38 The Regents of the University of California. All rights reserved.\n"; 39#endif /* not lint */ 40 41#ifndef lint 42/* 43static char sccsid[] = "@(#)printjob.c 8.7 (Berkeley) 5/10/95"; 44*/ 45static const char rcsid[] = |
46 "$FreeBSD: head/usr.sbin/lpr/lpd/printjob.c 94032 2002-04-07 05:37:27Z gad $"; | 46 "$FreeBSD: head/usr.sbin/lpr/lpd/printjob.c 94036 2002-04-07 07:48:32Z gad $"; |
47#endif /* not lint */ 48 49 50/* 51 * printjob -- print jobs in the queue. 52 * 53 * NOTE: the lock file is used to pass information to lpq and lprm. 54 * it does not need to be removed because file locks are dynamic. --- 911 unchanged lines hidden (view full) --- 966 967/* 968 * Send a data file to the remote machine and spool it. 969 * Return positive if we should try resending. 970 */ 971static int 972sendfile(struct printer *pp, int type, char *file, char format) 973{ | 47#endif /* not lint */ 48 49 50/* 51 * printjob -- print jobs in the queue. 52 * 53 * NOTE: the lock file is used to pass information to lpq and lprm. 54 * it does not need to be removed because file locks are dynamic. --- 911 unchanged lines hidden (view full) --- 966 967/* 968 * Send a data file to the remote machine and spool it. 969 * Return positive if we should try resending. 970 */ 971static int 972sendfile(struct printer *pp, int type, char *file, char format) 973{ |
974 register int f, i, amt; | 974 int i, amt; |
975 struct stat stb; 976 char *av[15], *filtcmd; 977 char buf[BUFSIZ], opt_c[4], opt_h[4], opt_n[4]; | 975 struct stat stb; 976 char *av[15], *filtcmd; 977 char buf[BUFSIZ], opt_c[4], opt_h[4], opt_n[4]; |
978 int filtstat, narg, resp, sizerr, statrc; | 978 int filtstat, narg, resp, sfd, sfres, sizerr, statrc; |
979 980 statrc = lstat(file, &stb); 981 if (statrc < 0) { 982 syslog(LOG_ERR, "%s: error from lstat(%s): %m", 983 pp->printer, file); | 979 980 statrc = lstat(file, &stb); 981 if (statrc < 0) { 982 syslog(LOG_ERR, "%s: error from lstat(%s): %m", 983 pp->printer, file); |
984 return(ERROR); | 984 return (ERROR); |
985 } | 985 } |
986 f = open(file, O_RDONLY); 987 if (f < 0) { | 986 sfd = open(file, O_RDONLY); 987 if (sfd < 0) { |
988 syslog(LOG_ERR, "%s: error from open(%s,O_RDONLY): %m", 989 pp->printer, file); | 988 syslog(LOG_ERR, "%s: error from open(%s,O_RDONLY): %m", 989 pp->printer, file); |
990 return(ERROR); | 990 return (ERROR); |
991 } 992 /* 993 * Check to see if data file is a symbolic link. If so, it should 994 * still point to the same file or someone is trying to print something 995 * he shouldn't. 996 */ | 991 } 992 /* 993 * Check to see if data file is a symbolic link. If so, it should 994 * still point to the same file or someone is trying to print something 995 * he shouldn't. 996 */ |
997 if ((stb.st_mode & S_IFMT) == S_IFLNK && fstat(f, &stb) == 0 && 998 (stb.st_dev != fdev || stb.st_ino != fino)) 999 return(ACCESS); | 997 if ((stb.st_mode & S_IFMT) == S_IFLNK && fstat(sfd, &stb) == 0 && 998 (stb.st_dev != fdev || stb.st_ino != fino)) { 999 close(sfd); 1000 return (ACCESS); 1001 } |
1000 1001 /* Everything seems OK for reading the file, now to send it */ 1002 filtcmd = NULL; 1003 sizerr = 0; 1004 tfd = -1; 1005 if (type == '\3') { 1006 /* 1007 * Type == 3 means this is a datafile, not a control file. --- 52 unchanged lines hidden (view full) --- 1060 * that we send the remote host the file-size before we 1061 * start to send any of the data. 1062 */ 1063 strcpy(tfile, TFILENAME); 1064 tfd = mkstemp(tfile); 1065 if (tfd == -1) { 1066 syslog(LOG_ERR, "%s: mkstemp(%s): %m", pp->printer, 1067 TFILENAME); | 1002 1003 /* Everything seems OK for reading the file, now to send it */ 1004 filtcmd = NULL; 1005 sizerr = 0; 1006 tfd = -1; 1007 if (type == '\3') { 1008 /* 1009 * Type == 3 means this is a datafile, not a control file. --- 52 unchanged lines hidden (view full) --- 1062 * that we send the remote host the file-size before we 1063 * start to send any of the data. 1064 */ 1065 strcpy(tfile, TFILENAME); 1066 tfd = mkstemp(tfile); 1067 if (tfd == -1) { 1068 syslog(LOG_ERR, "%s: mkstemp(%s): %m", pp->printer, 1069 TFILENAME); |
1068 return (ERROR); | 1070 sfres = ERROR; 1071 goto return_sfres; |
1069 } | 1072 } |
1070 filtstat = execfilter(pp, filtcmd, av, f, tfd); | 1073 filtstat = execfilter(pp, filtcmd, av, sfd, tfd); |
1071 1072 /* process the return-code from the filter */ 1073 switch (filtstat) { 1074 case 0: 1075 break; 1076 case 1: | 1074 1075 /* process the return-code from the filter */ 1076 switch (filtstat) { 1077 case 0: 1078 break; 1079 case 1: |
1077 unlink(tfile); 1078 return (REPRINT); | 1080 sfres = REPRINT; 1081 goto return_sfres; |
1079 case 2: | 1082 case 2: |
1080 unlink(tfile); 1081 return (ERROR); | 1083 sfres = ERROR; 1084 goto return_sfres; |
1082 default: 1083 syslog(LOG_WARNING, 1084 "%s: filter '%c' exited (retcode=%d)", 1085 pp->printer, format, filtstat); | 1085 default: 1086 syslog(LOG_WARNING, 1087 "%s: filter '%c' exited (retcode=%d)", 1088 pp->printer, format, filtstat); |
1086 unlink(tfile); 1087 return (FILTERERR); | 1089 sfres = FILTERERR; 1090 goto return_sfres; |
1088 } 1089 statrc = fstat(tfd, &stb); /* to find size of tfile */ 1090 if (statrc < 0) { 1091 syslog(LOG_ERR, 1092 "%s: error processing 'if', fstat(%s): %m", 1093 pp->printer, tfile); | 1091 } 1092 statrc = fstat(tfd, &stb); /* to find size of tfile */ 1093 if (statrc < 0) { 1094 syslog(LOG_ERR, 1095 "%s: error processing 'if', fstat(%s): %m", 1096 pp->printer, tfile); |
1094 return (ERROR); | 1097 sfres = ERROR; 1098 goto return_sfres; |
1095 } | 1099 } |
1096 f = tfd; 1097 lseek(f,0,SEEK_SET); | 1100 close(sfd); 1101 sfd = tfd; 1102 lseek(sfd, 0, SEEK_SET); |
1098 } 1099 1100 (void) sprintf(buf, "%c%qd %s\n", type, stb.st_size, file); 1101 amt = strlen(buf); 1102 for (i = 0; ; i++) { 1103 if (write(pfd, buf, amt) != amt || 1104 (resp = response(pp)) < 0 || resp == '\1') { | 1103 } 1104 1105 (void) sprintf(buf, "%c%qd %s\n", type, stb.st_size, file); 1106 amt = strlen(buf); 1107 for (i = 0; ; i++) { 1108 if (write(pfd, buf, amt) != amt || 1109 (resp = response(pp)) < 0 || resp == '\1') { |
1105 (void) close(f); 1106 if (tfd != -1 && type == '\3') { 1107 tfd = -1; 1108 unlink(tfile); 1109 } 1110 return(REPRINT); | 1110 sfres = REPRINT; 1111 goto return_sfres; |
1111 } else if (resp == '\0') 1112 break; 1113 if (i == 0) 1114 pstatus(pp, 1115 "no space on remote; waiting for queue to drain"); 1116 if (i == 10) 1117 syslog(LOG_ALERT, "%s: can't send to %s; queue full", 1118 pp->printer, pp->remote_host); 1119 sleep(5 * 60); 1120 } 1121 if (i) 1122 pstatus(pp, "sending to %s", pp->remote_host); 1123 if (type == '\3') 1124 trstat_init(pp, file, job_dfcnt); 1125 for (i = 0; i < stb.st_size; i += BUFSIZ) { 1126 amt = BUFSIZ; 1127 if (i + amt > stb.st_size) 1128 amt = stb.st_size - i; | 1112 } else if (resp == '\0') 1113 break; 1114 if (i == 0) 1115 pstatus(pp, 1116 "no space on remote; waiting for queue to drain"); 1117 if (i == 10) 1118 syslog(LOG_ALERT, "%s: can't send to %s; queue full", 1119 pp->printer, pp->remote_host); 1120 sleep(5 * 60); 1121 } 1122 if (i) 1123 pstatus(pp, "sending to %s", pp->remote_host); 1124 if (type == '\3') 1125 trstat_init(pp, file, job_dfcnt); 1126 for (i = 0; i < stb.st_size; i += BUFSIZ) { 1127 amt = BUFSIZ; 1128 if (i + amt > stb.st_size) 1129 amt = stb.st_size - i; |
1129 if (sizerr == 0 && read(f, buf, amt) != amt) | 1130 if (sizerr == 0 && read(sfd, buf, amt) != amt) |
1130 sizerr = 1; 1131 if (write(pfd, buf, amt) != amt) { | 1131 sizerr = 1; 1132 if (write(pfd, buf, amt) != amt) { |
1132 (void) close(f); 1133 if (tfd != -1 && type == '\3') { 1134 tfd = -1; 1135 unlink(tfile); 1136 } 1137 return(REPRINT); | 1133 sfres = REPRINT; 1134 goto return_sfres; |
1138 } 1139 } 1140 | 1135 } 1136 } 1137 |
1141 (void) close(f); 1142 if (tfd != -1 && type == '\3') { 1143 tfd = -1; 1144 unlink(tfile); 1145 } | |
1146 if (sizerr) { 1147 syslog(LOG_INFO, "%s: %s: changed size", pp->printer, file); 1148 /* tell recvjob to ignore this file */ 1149 (void) write(pfd, "\1", 1); | 1138 if (sizerr) { 1139 syslog(LOG_INFO, "%s: %s: changed size", pp->printer, file); 1140 /* tell recvjob to ignore this file */ 1141 (void) write(pfd, "\1", 1); |
1150 return(ERROR); | 1142 sfres = ERROR; 1143 goto return_sfres; |
1151 } 1152 if (write(pfd, "", 1) != 1 || response(pp)) { | 1144 } 1145 if (write(pfd, "", 1) != 1 || response(pp)) { |
1153 return(REPRINT); | 1146 sfres = REPRINT; 1147 goto return_sfres; |
1154 } 1155 if (type == '\3') 1156 trstat_write(pp, TR_SENDING, stb.st_size, logname, 1157 pp->remote_host, origin_host); | 1148 } 1149 if (type == '\3') 1150 trstat_write(pp, TR_SENDING, stb.st_size, logname, 1151 pp->remote_host, origin_host); |
1158 return(OK); | 1152 sfres = OK; 1153 1154return_sfres: 1155 (void)close(sfd); 1156 if (tfd != -1) { 1157 /* 1158 * If tfd is set, then it is the same value as sfd, and 1159 * therefore it is already closed at this point. All 1160 * we need to do is remove the temporary file. 1161 */ 1162 tfd = -1; 1163 unlink(tfile); 1164 } 1165 return (sfres); |
1159} 1160 1161/* 1162 * This routine is called to execute one of the filters as was | 1166} 1167 1168/* 1169 * This routine is called to execute one of the filters as was |
1163 * specified in a printcap entry. | 1170 * specified in a printcap entry. While the child-process will read 1171 * all of 'infd', it is up to the caller to close that file descriptor 1172 * in the parent process. |
1164 */ 1165static int 1166execfilter(struct printer *pp, char *f_cmd, char *f_av[], int infd, int outfd) 1167{ 1168 int errfd, fpid, wpid; 1169 FILE *errfp; 1170 union wait status; /* XXX */ 1171 char buf[BUFSIZ], *slash; 1172 1173 fpid = dofork(pp, DORETURN); 1174 if (fpid != 0) { 1175 /* 1176 * This is the parent process, which just waits for the child 1177 * to complete and then returns the result. Note that it is 1178 * the child process which reads the input stream. 1179 */ | 1173 */ 1174static int 1175execfilter(struct printer *pp, char *f_cmd, char *f_av[], int infd, int outfd) 1176{ 1177 int errfd, fpid, wpid; 1178 FILE *errfp; 1179 union wait status; /* XXX */ 1180 char buf[BUFSIZ], *slash; 1181 1182 fpid = dofork(pp, DORETURN); 1183 if (fpid != 0) { 1184 /* 1185 * This is the parent process, which just waits for the child 1186 * to complete and then returns the result. Note that it is 1187 * the child process which reads the input stream. 1188 */ |
1180 (void) close(infd); | |
1181 if (fpid < 0) 1182 status.w_retcode = 100; 1183 else { 1184 while ((wpid = wait((int *)&status)) > 0 && 1185 wpid != fpid) 1186 ; 1187 if (wpid < 0) { 1188 status.w_retcode = 100; --- 661 unchanged lines hidden --- | 1189 if (fpid < 0) 1190 status.w_retcode = 100; 1191 else { 1192 while ((wpid = wait((int *)&status)) > 0 && 1193 wpid != fpid) 1194 ; 1195 if (wpid < 0) { 1196 status.w_retcode = 100; --- 661 unchanged lines hidden --- |