/* zipbar.c for surf-mail */ /* by Marshall Plann */ /* compiled fine in TC++ */ /* 12/91 */ #include #include #include #include #define PRINTER_PORT "lpt1" #define ESC 27 #define LONG 255 #define SHORT 7 #define SPACE 0 #define K1 7 /* width of a space */ #define K2 4 /* width of a bar */ void write_bars(); void bar_code(); int code_digit(); unsigned char digit_bits[] = { 24, 3, 5, 6, 9, 10, 12, 17, 18, 20 }; main(argc, argv) int argc; char *argv[]; { int printer; /* file to write to */ char string[256]; /* first parameter is the zip code or else exit */ if (argc < 2) { printf("Usage: %s zipcode\n" argv[0]); exit(-1); } /* open the printer port */ if ((printer = open(PRINTER_PORT, O_WRONLY)) == -1) { printf("Error opening %s\n", PRINTER_PORT); exit(1); } strcpy(string, argv[1]); bar_code(printer, string); /* print the bar code */ write(printer, "\n", 1); /* print a new line */ close(printer); return 0; } void bar_code(printer, str) int printer; char str[]; { char out_str[256]; int i; int digit; int count = 0; int sum = 0; int len = strlen(str); /* add leading bar */ count += code_end(&(out_str[count])); /* go through the string and create codes for digits */ for (i = 0; i < len; i++) { if (isdigit(str[i])) { /* character is a digit */ digit = str[i] - '0'; sum += digit; /* accumulate for checksum */ if (count > 128) { /* dump every 128 bytes or so to the printer */ out_str[count++] = '\0'; write_bars(printer, out_str, count); count = 0; } /* end if */ /* code the next digit */ count += code_digit(digit, &(out_str[count])); } /* end if */ } /* end for */ /* generate the checksum */ if (sum > 0) { count += code_digit((10 - (sum % 10)) % 10, &(out_str[count])); } /* add trailing bar */ count += code_end(&(out_str[count])); out_str[count++] = '\0'; write_bars(printer, out_str, count); } void write_bars(printer, str, count) int printer; char str[]; int count; { char out_str[64]; int num = 0; out_str[num++] = ESC; out_str[num++] = '2'; out_str[num++] = count; out_str[num++] = 0; out_str[num] = '\0'; write(printer, out_str, num); /* prepare printer for data */ write(printer, str, count); /* write data to printer */ } int code_digit(digit, str) int digit; char str[]; { int i, j, k; for (i = 4, k = 0; i >= 0; i--) { /* use digit_bits as a template for the bar codes. If a bit is on then add a long bar. add a short bar otherwise. */ if ((digit_bits[digit] >> i) & 1) { for (j = 0; j < K2; str[k++] = LONG, j++); } else { for (j = 0; j < K2; str[k++] = SHORT, j++); } for (j = 0; j < K1; str[k++] = SPACE, j++); } return k; /* number of bytes added */ } /* adds beginning or trailing bar */ int code_end(str) char str[]; { int j, k = 0; for (j = 0; j < K2; str[k++] = LONG, j++); for (j = 0; j < K1; str[k++] = SPACE, j++); return k; /* number of bytes added */ }