📄 mkentry.c
字号:
return;}/* * output_info - output the ---info--- section(s) * * Read the needed information from stdin, and write the info section. * If multiple info files exist, multiple info sections will be written. */voidoutput_info(output, oname) FILE *output; /* entry's output file stream */ char *oname; /* name of the output file */{ char infoname[MAX_FILE_LEN+1]; /* filename buffer */ char yorn[1+1]; /* y or n answer */ char *uuname; /* name to uuencode as */ FILE *infile; /* info file stream */ /* * prompt the user for info information */ printf("\nInfo files should be used only to supplement your entry.\n"); printf("For example, info files may provide sample input or detailed\n"); printf("information about your entry. Because they are supplemental,\n"); printf("the entry should not require them to exist.\n\n"); /* * while there is another info file to save, uuencode it */ printf("Do you have a info file to include (enter y or n)? "); while (get_line(yorn, 1+1, 0) <= 0 || !(yorn[0]=='y' || yorn[0]=='n')) { printf("\nplease answer y or n: "); } while (yorn[0] == 'y') { /* read the filename */ printf("\nEnter the info filename: "); while (get_line(infoname, MAX_FILE_LEN+1, 0) <= 0) { printf("\nInfo filename too long, please re-enter: "); } /* compute the basename of the info filename */ /* remove the trailing newline */ uuname = &infoname[strlen(infoname)-1]; *uuname = '\0'; /* avoid rindex/shrrchr compat issues, do it by hand */ for (--uuname; uuname > infoname; --uuname) { if (*uuname == '/') { ++uuname; break; } } /* attempt to open the info file */ infile = fopen(infoname, "r"); if (infile == NULL) { fprintf(stderr, "\n%s: cannot open info file: %s: ", program, infoname); perror(""); continue; } /* * write the start of the section */ fprintf(output, "---info---\n"); check_io(output, oname, EOF_NOT_OK); /* uuencode the info file */ uuencode(output, oname, infile, infoname, UUINFO_MODE, uuname); printf("\nDo you have another info file to include (enter y or n)? "); while (get_line(yorn, 1+1, 0) <= 0 || !(yorn[0]=='y' || yorn[0]=='n')) { printf("\nplease answer y or n: "); } }; return;}/* * output_build - output the ---build--- section * * Read the needed information from stdin, and write the build section. */voidoutput_build(output, oname, build, bname) FILE *output; /* entry's output file stream */ char *oname; /* name of the output file */ FILE *build; /* open build file stream */ char *bname; /* name of the build file */{ /* * write the start of the section */ fprintf(output, "---build---\n"); check_io(output, oname, EOF_NOT_OK); /* * uuencode the program file */ uuencode(output, oname, build, bname, UUBUILD_MODE, UUBUILD_NAME); return;}/* * output_program - output the ---program--- section * * Read the needed information form stdin, and write the program section. */voidoutput_program(output, oname, prog, pname) FILE *output; /* entry's output file stream */ char *oname; /* name of the output file */ FILE *prog; /* open program stream */ char *pname; /* name of program file */{ /* * write the start of the section */ fprintf(output, "---program---\n"); check_io(output, oname, EOF_NOT_OK); /* * uuencode the program file */ uuencode(output, oname, prog, pname, UUPROG_MODE, UUPROG_NAME); return;}/* * output_end - output the ---end--- section * * Read the needed information form stdin, and write the 'end section'. */voidoutput_end(output, oname) FILE *output; /* entry's output file stream */ char *oname; /* name of the output file */{ /* * write the final section terminator */ fprintf(output, "---end---\n"); check_io(output, oname, EOF_NOT_OK); return;}/* * get_line - get an answer from stdin * * This function will flush stdout, in case a prompt is pending, and * read in the answer. * * This function returns 0 if the line is too long, of the length of the * line (including the newline) of the line was ok. This function does * not return if ERROR or EOF. */intget_line(buf, siz, maxcol) char *buf; /* input buffer */ int siz; /* length of input, including the newline */ int maxcol; /* max col allowed, 0 => disable check */{ int length; /* the length of the input line */ /* flush terminal output */ fflush(stdout); /* read the line */ if (fgets(buf, siz+1, stdin) == NULL) { /* report the problem */ check_io(stdin, "stdin", EOF_NOT_OK); } /* look for the newline */ length = strlen(buf); if (buf[length-1] != '\n') { int eatchar; /* the char being eaten */ /* no newline found, line must be too long, eat the rest of the line */ do { eatchar = fgetc(stdin); } while (eatchar != EOF && eatchar != '\n'); check_io(stdin, "stdin", EOF_NOT_OK); /* report the situation */ return 0; } /* watch for long lines, if needed */ if (maxcol > 0 && (length > maxcol || col_len(buf) > maxcol)) { /* report the situation */ return 0; } /* return length */ return length;}/* * output_till_dot - output a set of lines until '.' by itself is read * * This routine will read a set of lines until (but not including) * a single line with '.' is read. The format of the output is: * * leader:\tfirst line * \tnext line * \tnext line * ... * * This routine will not return if I/O error or EOF. */voidoutput_till_dot(output, oname, leader) FILE *output; /* entry's output file stream */ char *oname; /* name of the output file */ char *leader; /* the lead text for the first line */{ char buf[BUFSIZ+1]; /* input buffer */ int count; /* lines read */ int done=FALSE; /* TRUE => finished reading input */ /* instruct the user on how to input */ printf("\nTo end input, enter a line with a single period.\n"); /* read lines until '.' or EOF */ count = 0; while (!done) { /* issue the prompt */ printf("%s\t", (count>0) ? "" : leader); fflush(stdout); /* get the line */ if (get_line(buf, BUFSIZ, MAX_COL-9) <= 0) { printf("\nline too long, please re-enter:\n\t"); continue; } /* note if '.' was read */ if (strcmp(buf, ".\n") == 0) { done = TRUE; } /* write line if we read something */ if (!done) { fprintf(output, "%s\t%s", (count++>0) ? "" : leader, buf); check_io(output, oname, EOF_NOT_OK); } } /* if no lines read, at least output something */ if (count <= 0) { fprintf(output, "%s\t.\n", leader); check_io(output, oname, EOF_NOT_OK); } return;}/* * col_len - determine the highest that a string would reach * * Given a string, this routine returns that a string would reach * if the string were printed at column 1. Tab stops are assumed * to start at 9, 17, 25, 33, ... */intcol_len(string) char *string; /* the string to examine */{ int col; /* current column */ char *p; /* current char */ /* scan the string */ for (col=0, p=string; *p != '\0' && *p != '\n'; ++p) { /* note the column shift */ col = (*p=='\t') ? 1+((col+8)/8*8) : col+1; } if (*p == '\n') { --col; } /* return the highest column */ return col;}/* * check_io - check for EOF or I/O error on a stream * * Does not return if EOF or I/O error. */voidcheck_io(stream, name, eof_ok) FILE *stream; /* the stream to check */ char *name; /* the name of this stream */ int eof_ok; /* EOF_OK or EOF_NOT_OK */{ /* test for I/O error */ if (ferror(stream)) { fprintf(stderr, "%s: error on %s: ", program, name); perror(""); exit(1); /* test for EOF */ } else if (eof_ok == EOF_NOT_OK && feof(stream)) { fprintf(stderr, "%s: EOF on %s\n", program, name); exit(1); } return;}/* * uuencode - uuencode a file * * Perform the uuencoding process identical to the process performed * by the uuencode(1) utility. * * This routine implements the algorithm described in the uuencode(5) * 4.3BSD Reno man page. */voiduuencode(output, oname, infile, iname, umode, uname) FILE *output; /* output file stream */ char *oname; /* output filename */ FILE *infile; /* input file stream */ char *iname; /* input filename */ int umode; /* the mode to put on the uuencode file */ char *uname; /* name to put on the uuencode file */{ char buf[UUENCODE_LEN+1]; /* the uuencode buffer */ int read_len; /* actual number of chars read */ int val; /* 6 bit chunk from buf */ char filler='\0'; /* filler uuencode pad text */ char *p; /* * output the initial uuencode header */ fprintf(output, "begin %o %s\n", umode, uname); check_io(output, oname, EOF_NOT_OK); /* * clear out the input buffer */ for (p=buf; p < &buf[sizeof(buf)/sizeof(buf[0])]; ++p) { *p = '\0'; } /* * We will process UUENCODE_LEN chars at a time, forming * a single output line each time. */ while ((read_len=fread(buf,sizeof(buf[0]),UUENCODE_LEN,infile)) > 0) { /* * the first character is the length character */ fputc(UUENCODE(read_len), output); check_io(output, oname, EOF_NOT_OK); /* * We will convert 24 bits at a time. Thus we will convert * 3 sets of 8 bits into 4 sets of uuencoded 6 bits. */ for (p=buf; read_len>0; read_len-=3, p+=3) { /* bits 0 to 5 */ val = (p[0]>>2)&0x3f; fputc(UUENCODE(val), output); check_io(output, oname, EOF_NOT_OK); /* bits 6 to 11 */ val = ((p[0]<<4)&0x30) | ((p[1]>>4)&0x0f); fputc(UUENCODE(val), output); check_io(output, oname, EOF_NOT_OK); /* bits 12 to 17 */ val = ((p[1]<<2)&0x3c) | ((p[2]>>6)&0x03); fputc(UUENCODE(val), output); check_io(output, oname, EOF_NOT_OK); /* bits 18 to 23 */ val = p[2]&0x3f; fputc(UUENCODE(val), output); check_io(output, oname, EOF_NOT_OK); } /* end of UUENCODE_LEN line */ fputc('\n', output); check_io(output, oname, EOF_NOT_OK); /* * clear out the input buffer (don't depend on bzero() or memset()) */ for (p=buf; p < &buf[sizeof(buf)/sizeof(buf[0])]; ++p) { *p = '\0'; } } /* check the last read on the input file */ check_io(infile, iname, EOF_OK); /* write end of uuencode file */ fprintf(output, "%c\nend\n", UUENCODE(filler)); check_io(output, oname, EOF_NOT_OK);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -