Deleted Added
full compact
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 ---