alex.c
来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 901 行 · 第 1/2 页
C
901 行
/**************************************************************************//* add_field () adds the string str, to the fields to be searched. *//* Inputs: field_vals - a pointer to the head of a linked list of *//* structures storing all header fields to be *//* searched. *//* str - a string containing the field name to be added to field *//* structure. it is in the format: field{/field} *//* Outputs: field_vals - pointer to head of linked list is returned; *//* this is because the head could have been NULL *//* when first called, and will be changed. *//**************************************************************************/struct fields *add_field (field_vals, str)struct fields *field_vals;char *str;{ int loop, num_fields = 1; char *p1; struct fields *elem; struct fields *current_field; for (loop = 0; str[loop] != '\0'; loop++) { /* Counts the number of */ if (str[loop] == '/') /* fields in 'str'. */ num_fields++; } if ((elem = MAKESTRUCT(fields)) == (struct fields *)NULL) adios (NULLCP, "unable to allocate storage"); if ((elem -> priorities = MAKEARGV (num_fields + 1)) == (char **)NULL) adios (NULLCP, "unable to allocate storage"); for (loop = 0; loop < num_fields; loop++) { /* Parse the fields in 'str'. */ if ((p1 = index(str, '/')) != NULLCP) { /* Split 'str' at '/' and */ *p1 = '\0'; /* store each field in field */ p1++; /* structure. */ } str = trimcpy (str); /* Remove white spaces. */ elem -> priorities[loop] = getcpy (str); str = p1; } elem -> priorities[num_fields] = NULLCP; elem -> next = (struct fields *)NULL; if (field_vals == (struct fields *)NULL) field_vals = elem; else { current_field = field_vals; while (current_field -> next != (struct fields *)NULL) current_field = current_field -> next; current_field -> next = elem; } return (field_vals);}/************************************************************************//* del_field called when the "-nofield str" option is used. *//* Inputs: field_vals - a pointer to the head of a linked list of *//* structures storing header fields to be *//* searched *//* str - the field name to be deleted from the field structure. *//* Outputs: field_vals will be changed. *//* The comparison of 'str' to the list of fields is case insensitive. *//************************************************************************/static void del_field (field_vals, str)struct fields *field_vals;char *str;{ int count = 0; while (field_vals != (struct fields *)NULL) { while (field_vals -> priorities[count] != NULLCP) { if (uleq (field_vals -> priorities[count], str)) field_vals -> priorities[count][0] = '\0'; count++; } count = 0; field_vals = field_vals -> next; }} /***************************************************************************//* del_all_fields is called when the "-nofield all" option is given on the *//* command line. This tells "alex" not to search for any previous header *//* fields given with the "-field header" command. *//* Inputs: field_vals - a pointer to the head of a linked list of *//* structures storing all the header fields to be *//* searched. *//* Outputs: field_vals is changed. *//***************************************************************************/static void del_all_fields (field_vals)struct fields *field_vals;{ int count; while (field_vals != (struct fields *)NULL) { count = 0; while (field_vals -> priorities[count] != NULLCP) field_vals -> priorities[count++][0] = '\0'; field_vals = field_vals -> next; }}/************************************************************************//* read_alias_file stores all the aliases from the alias file into the *//* alias structure. *//* Inputs: alias_lists - a pointer to the head of a linked list of *//* structures storing each line of alias file. *//* file - a string holding the name of the alais file. *//* Outputs: Each structure in the alias_lists linked list will conatin *//* a line from the alias file. *//************************************************************************/struct entry *read_alias_file (alias_lists, file)struct entry *alias_lists;char *file;{ int i, /* General purpose loop counter. */ num_addr; /* Holds the number of addresses in each alias. */ char alias_buf[BUFSIZ], /* Used for reading in each line of file. */ *p1, /* Used for parsing alais lines. */ *alias_line, /* String storing the current line from file. */ *cp, *whole_line; /* Pointer, used for freeing the space allocated */ /* to alias_line, at end of function. */ struct entry *element, *current_alias; FILE *in; if ((in = fopen (file, "r")) == NULLFILE) { cp = concat ("Create alias file \"", file, "\"? ", NULLCP); if (!getanswer (cp)) done (1); free (cp); if ((in = fopen (file, "w+")) == NULLFILE) adios (file, "unable to create"); fputc ('\n', in); rewind(in); } while (fgets (alias_buf, BUFSIZ, in) != NULLCP) { /* Read in a line from */ alias_line = add (alias_buf, NULLCP); /* alias file. *//* If line ends with backslash then it's a continuation line, *//* so read next line and join them. */ while (continuation_line (alias_line)) { if (fgets (alias_buf, BUFSIZ, in) != NULLCP) alias_line = add (alias_buf, alias_line); } if ((element = MAKESTRUCT(entry)) == (struct entry *)NULL) adios (NULLCP, "unable to allocate storage"); whole_line = alias_line;/* If there is not a ':' in line, then store whole line in element -> words. *//* This could be a comment line in the alias file. */ if (*alias_line == ';' || (p1 = index(alias_line, ':')) == NULLCP) { element -> words = getcpy (alias_line); if ((element -> address_list = MAKEARGV (1)) == (char **)NULL) adios (NULLCP, "unable to allocate storage"); element -> address_list[0] = NULLCP; element -> next = (struct entry *)NULL; } else { num_addr = 0; for (i = 0; alias_line[i] != '\0'; i++) { /* Count the number */ if (alias_line[i] == ',') /* of addresses in */ num_addr++; /* alias. */ } num_addr++; *p1 = '\0'; /* Store alias name in element -> words */ p1++; if ((element -> words = (char *)malloc(sizeof(char *) * (strlen(alias_line) + 1))) == NULLCP) adios (NULLCP, "unable to allocate storage"); (void) strcpy (element -> words, alias_line); alias_line = p1; if ((element -> address_list = MAKEARGV(num_addr+1))==(char **)NULL) adios (NULLCP, "unable to allocate storage");/* Parse alias line into separate addresses - split it at ','s */ for (i = 0; i < num_addr; i++) { if ((p1 = index(alias_line, ',')) != NULLCP) { *p1 = '\0'; p1++; } element -> address_list[i] = getcpy (alias_line); alias_line = p1; } element -> address_list[i] = NULLCP; element -> next = (struct entry *)NULL; } if (alias_lists == (struct entry *)NULL) alias_lists = element; else { current_alias = alias_lists; while (current_alias -> next != (struct entry *)NULL) current_alias = current_alias -> next; current_alias -> next = element; } free (whole_line); } (void) fclose (in); return (alias_lists);}/*************************************************************************//* output_aliases writes the alias structure into 'out' *//* Inputs: alias_lists - a pointer to the head of a linked list of *//* structures storing all the info for aliases. *//* out - The output file (can be stdout). *//* width - The maximum width of an alias file line, specified *//* on the command line, or a default of 72. *//* name - the alias name that has been changed. *//* Outputs: out - All of the alias info is output to this file. *//*************************************************************************/static void output_aliases (alias_lists, out, width, name)struct entry *alias_lists;FILE *out;int width;char *name;{ int count = 0, column = 1; while (alias_lists != (struct entry *)NULL) { /* Output the alias name */ (void) fputs (alias_lists -> words, out); /* or comment line. */ if (uleq (alias_lists -> words, name)) { column = strlen (alias_lists -> words) + 1; if (column >= width) { (void) fputs ("\\\n ", out); /* If line over maximum width, */ column = 3; /* new line and indent. */ } } while (alias_lists -> address_list[count] != NULLCP) { if (alias_lists -> address_list[count][0] != '\0') { if (count == 0 && name) /* Only output a ':' if a name */ fputc (':', out); /* is specified. */ if (count != 0) fputc (',', out); if (uleq (alias_lists -> words, name)) { column=column+strlen(alias_lists -> address_list[count])+1; if (column >= width - 1) { (void) fputs ("\\\n ", out); column = strlen(alias_lists -> address_list[count])+2; } } (void) fputs (alias_lists -> address_list[count], out); } count++; } if ((alias_lists -> address_list[0] == NULLCP && alias_lists -> words[0] != '\n') || uleq (alias_lists -> words, name)) fputc ('\n', out); /* If output is stdout, then */ if (out == stdout) /* only 1 alias output. */ alias_lists = (struct entry *)NULL; else /* Else next alias. */ alias_lists = alias_lists -> next; count = 0; }}/*************************************************************************//* get_alias searches the aliases to see if the alias name exists. If it *//* does, then returns a pointer to this alias, otherwise it returns a *//* pointer to a new alias. *//* When looking for an alias name, the search is case insensitive. */ /* Inputs: alias_lists - a pointer to the head of a linked list of *//* structures storing alias info. *//* name - alias name being searched for. *//* replace - flag specifying if alias should be replace if it *//* already exists. *//* global - flag specifying if all occurrences of the alias *//* name should be updated. *//* alias_num - number of occurrences of alias already found. *//* Outputs : alias_lists - the pointer to the head of the linked list *//* is returned - it may have been changed. *//*************************************************************************/struct entry *get_alias (alias_lists, name, replace, global, alias_num)struct entry *alias_lists;char *name;int replace;int global;int alias_num;{ struct entry *ret_alias; struct entry *current_alias; int count = 0; current_alias = alias_lists; if (alias_lists != (struct entry *)(NULL)) { /* Search for alias */ while ((alias_lists != (struct entry *)NULL) && /* name. */ (uleq(trimcpy (alias_lists -> words), name) == 0)) alias_lists = alias_lists -> next; if (alias_lists != (struct entry *)NULL) { /* If it's found return */ if (replace) /* pointer to it. */ while (alias_lists -> address_list[count] != NULLCP) alias_lists -> address_list[count] = NULLCP; strip_spaces (alias_lists); /* Remove white spcs from addresses */ return (alias_lists); } /* Alias name wasn't found : */ } if (global && (alias_num > 0) && name && *name) /* If global flag set, */ return ((struct entry *)NULL); /* and an occurrence of */ /* alias name has been */ /* found, return NULL *//* Make up a new structure for alias, and store alias name in structure. */ if ((ret_alias = MAKESTRUCT(entry)) == (struct entry *)NULL) adios (NULLCP, "unable to allocate storage"); ret_alias -> words = getcpy (name); if ((ret_alias -> address_list = MAKEARGV (1)) == (char **)NULL) adios (NULLCP, "unable to allocate storage"); ret_alias -> address_list[0] = NULLCP; ret_alias -> next = (struct entry *)NULL; if (current_alias == (struct entry *)NULL) alias_lists = ret_alias; else { while (current_alias -> next != (struct entry *)NULL) current_alias = current_alias -> next; current_alias -> next = ret_alias; } return (ret_alias);}/******************************************************************************//* add_alias_entry adds the address str into the appropriate alias structure. *//* Inputs: alias_ent - a pointer to structure storing current alias info. *//* str - address to be added to alias. *//* query - flag specifying if user is asked interactively whether to *//* add an address to the alias. *//* Outputs: alias_ent - the new addresses will be added to the structure. *//******************************************************************************/static void add_alias_entry(alias_ent, str, query)struct entry *alias_ent;char *str;int query;{ int count = 0, reply = OK; while (alias_ent -> address_list[count] != NULL) /* Count the number of */ count++; /* addresses in alias. */ if (query) /* If query set, then */ reply = ask (alias_ent -> words, str); /* query the user. *//* Reallocate the storage space and add the address 'str' to the alias. */ if (reply == OK) { if ((alias_ent -> address_list = (char **)realloc(alias_ent -> address_list, (count + 2) * sizeof (char *))) == (char **)NULL) adios (NULLCP, "unable to allocate storage"); alias_ent -> address_list[count + 1] = NULLCP; alias_ent -> address_list[count] = getcpy (str); }}/***************************************************************************//* ask - this outputs an address on stderr, and asks the user whether s/he *//* wishes to add this address to the alias. *//* Inputs: name - the alias name being appended to. *//* str - the address being appended. *//* Outputs: either OK (0) or NOTOK (-1). *//***************************************************************************/int ask (name, str)char *name;char *str;{ (void) fprintf(stderr, "%s\n", str); (void) fprintf(stderr, "Add this address to alias %s (y/n) ?", name); return (getanswer ("") ? OK : NOTOK);}/***************************************************************************//* compress_alias - if an address exists in the alias more than once, then *//* only include it once. *//* Inputs: new_alias - a pointer to the structure containing new alias. *//* Outputs: new_alias is changed. *//***************************************************************************/static void compress_alias (new_alias)struct entry *new_alias;{ char *str; int count, num_entries = 0, curr; while (new_alias -> address_list[num_entries] != NULLCP) /* Count no of */ num_entries++; /* addresses in */ /* alias. */ for (curr = 1; curr < num_entries - 1; curr++) { str = new_alias -> address_list[curr-1]; /* If address exists */ while (*str == ' ' || *str == '\t') /* more than once then */ str++; /* replace all but 1st */ for (count = curr; count < num_entries; count++) /* with '\0' */ if (uleq (str, new_alias -> address_list[count])) new_alias -> address_list[count][0] = '\0'; }}int continuation_line (str)char *str;{ char *p; p = str + strlen (str) - 1; while (p >= str && isspace (*p)) p--; return (p >= str && *p == '\\' ? 1 : 0);}strip_spaces (alias_list)struct entry *alias_list;{ int i; char *p; if (alias_list != (struct entry *)NULL) { alias_list -> words = trimcpy (alias_list -> words); for (i = 0; alias_list -> address_list[i] != '\0'; i++) { alias_list -> address_list[i] = trimcpy (alias_list -> address_list[i]); while (alias_list -> address_list[i][0] == '\\') { alias_list -> address_list[i]++; alias_list -> address_list[i] = trimcpy (alias_list -> address_list[i]); } if (((p = rindex(alias_list -> address_list[i], '\\')) != NULLCP) && (*(p+1) == '\0')) *p = '\0'; } }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?