Files
Arquivotheca.AIX-4.1.3/bldenv/pkgtools/media_list.c
seta75D d6fe8fe829 Init
2021-10-11 22:19:34 -03:00

1694 lines
61 KiB
C

static char sccsid[] = "@(#)99 1.16 src/bldenv/pkgtools/media_list.c, pkgtools, bos412, GOLDA411a 3/2/94 11:40:41";
/*
* COMPONENT_NAME: PKGTOOLS
*
* FUNCTIONS: append_mlevel_list
* append_peresl_list
* append_ptf_list
* append_req_list
* check_malloc_return
* create_index_list
* create_mlevel_list
* create_peresl_list
* create_ptf_list
* create_req_list
* find_in_mlevel_list
* find_in_peresl_list
* find_in_ptf_list
* find_in_req_list
* find_more_prereq_ptfs
* find_peresl_ptfs
* get_next_index_line
* get_next_mlevel_info
* get_next_peresl_info
* get_next_ptf_info
* get_next_req_info
* help
* is_a_valid_ptf
* main
* mlevel_list_empty
* output_ptfs
* peresl_list_empty
* print_out_cyclic_ptfs
* print_out_ptf
* ptf_list_empty
* remove_coreqs_and_ifreqs
* remove_ptf_from_ptf_list
* remove_ptf_from_req_list
* report_ptfs_not_found
* req_list_empty
* restore_current_posn
* rewind_index_list
* rewind_mlevel_list
* rewind_peresl_list
* rewind_ptf_list
* rewind_req_list
* save_current_posn
* store_server_and_req
*
* ORIGINS: 27
*
*
* (C) COPYRIGHT International Business Machines Corp. 1991,1993
* All Rights Reserved
* Licensed Materials - Property of IBM
* US Government Users Restricted Rights - Use, duplication or
* disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
*
* Syntax:
* media_list [-s dirname_ship] [-p dirname_prod]
* [-b dirname_build] [-v] [-t] [-e] [-h] [-?] [-x]
* [-p] [-o out_filename ] [-r peresl_filename]
* [-u maintlevel_filename] -l mif_ccss_list_filename
* where:
* -s dirname_ship - path to mif directory on
* 'ship' server.
* -p dirname_prod - path to mif directory on
* 'production' server.
* -b dirname_build - path to mif directory on
* 'build' server.
* -v verbose option - prints extra infomation
* on the prereqs found
* -l mif_ccss_list_filename filename containing list
* of mif/ccss files to package.
* (for example filename 3.2_gold:
* u123456
* u333333
* u444444)
* -o outfilename - path & filename for ordered list
* of prereqs. sysout used if
* -o is not given. If rc!=0 no
* data is output to this file.
* This is the order that the
* ptf's could be stacked on a
* tape without ever needing to
* rewind the device on a install
* all option. (example output
* file /tmp/order.list:
* u444444
* u123456
* u333333 ).
* -r peresl_file - Problem resolution file.
* -u maintlevel_file - File containing all ptfs in specified
* maintenance level plus all ptfs in any earlier
* maintenance levels. These ptfs are excluded from
* final output.
* -e - exclude requisites; only ptfs from -l file
* are printed out (in nice order)
* -t - duplicate PTF's are allowed on different
* servers.
* -x - exclude supersedes; only prereqs, coreqs and
* ifreqs ptf_filenames are printed out.
* -n - do NOT include preventive supersedes.
* -h | -? options to list usage message and exit
*/
/* Include section */
#include <stdio.h>
#include <fcntl.h>
/* Set up name of index files */
#define INDEX "index"
/*********************/
/* Data declarations */
/*********************/
/* Set up an array of index file lines */
/* *index_line will essentially become index_line[num_lines] by using malloc */
/* Index file line */
typedef struct {
char *lpp1,
*ptf1,
*req_type,
*lpp2,
*ptf2;
} index_line_t;
/* Array of lines */ /* index list type */
typedef struct {
index_line_t *index_line;
int num_lines,
cur_line;
} index_list_t;
/******************************************/
/* ptf_list structure */
/* */
/* ---------- ----------- */
/* | ptf1 | | ptf2 | */
/* | |--> | |----||| */
/* |req_list| | req_list| */
/* ----|----- -----|----- */
/* V V */
/* ---------- ----------- */
/* | ptf1's | | ptf2's | */
/* | req's | | req's | */
/* ---------- ----------- */
/******************************************/
/* Requisite list structure (linked list) */
/* req_info node */
struct req_info {
char *req_ptf; /* the req ptf for this node */
char *req_type; /* relationship for this ptf */
struct req_info *next_req; /* pointer to next req in list */
};
typedef struct req_info req_info_t; /* req info type */
/* req_list_type (linked list of req_info nodes) */
typedef struct {
req_info_t *start,
*current,
*last;
} req_list_t;
/* ptf list structure (linked list) */
struct ptf_info { /* ptf info node */
char *ptf; /* ptf for this node */
char *server; /* Server this ptf is found on */
char *parent_ptf; /* ptf which prereqs this ptf */
char *req_type; /* Relationship from parent ptf */
req_list_t *req_list; /* List of requisites for this ptf */
struct ptf_info *next_ptf; /* Pointer to next ptf in list */
};
/* ptf info type */
typedef struct ptf_info ptf_info_t;
/* ptf list type (linked list of ptf_info nodes) */
typedef struct {
ptf_info_t *start,
*current,
*last;
} ptf_list_t;
/* peresl list structure (linked list) */
struct peresl_info { /* peresl info node */
char *bad_ptf; /* ptf for this node */
req_list_t *req_list; /* List of fixes for this ptf */
struct peresl_info *next_peresl;/* Pointer to next peresl in list */
};
/* peresl info type */
typedef struct peresl_info peresl_info_t;
/* peresl list type (linked list of peresl_info nodes) */
typedef struct {
peresl_info_t *start,
*current,
*last;
} peresl_list_t;
/* maintlevel list structure (linked list) */
struct mlevel_info { /* mlevel info node */
char *ptf; /* maintlevel ptf for this node */
struct mlevel_info *next_mlevel;/* Pointer to next ptf in list */
};
/* mlevel info type */
typedef struct mlevel_info mlevel_info_t;
/* mlevel list type (linked list of mlevel_info nodes) */
typedef struct {
mlevel_info_t *start,
*current,
*last;
} mlevel_list_t;
/*************************/
/* Function declarations */
/*************************/
void find_more_prereq_ptfs(index_list_t *index_list, char *server,
ptf_list_t *ptf_list );
int store_server_and_req(ptf_info_t *ptf_info, char *server,
char *req_ptf, char *req_type);
void report_ptfs_not_found(ptf_list_t *ptf_list);
void remove_coreqs_and_ifreqs(ptf_list_t *ptf_list);
void output_ptfs(FILE *out_file, ptf_list_t *ptf_list);
void print_out_ptf(FILE *out_file, ptf_info_t *ptf_info);
void remove_ptf_from_ptf_list(ptf_list_t *ptf_list,char *ptf_to_remove);
void remove_ptf_from_req_list(req_list_t *req_list,char *ptf_to_remove);
void print_out_cyclic_ptfs(ptf_list_t *ptf_list);
index_list_t *create_index_list(char *server_dir);
void rewind_index_list(index_list_t *index_list);
index_line_t *get_next_index_line(index_list_t *index_list);
ptf_list_t *create_ptf_list();
void append_ptf_list(ptf_list_t *ptf_list, char *new_ptf,
char *new_server, char *new_parent_ptf, char *new_req_type);
ptf_info_t *find_in_ptf_list(ptf_list_t *ptf_list, char *chk_ptf);
void rewind_ptf_list(ptf_list_t *ptf_list);
ptf_info_t *get_next_ptf_info(ptf_list_t *ptf_list);
int ptf_list_empty(ptf_list_t *ptf_list);
req_list_t *create_req_list();
void append_req_list(req_list_t *req_list, char *new_req_ptf,
char *new_req_type);
req_info_t *find_in_req_list(req_list_t *req_list, char *chk_req_ptf);
void rewind_req_list(req_list_t *req_list);
req_info_t *get_next_req_info(req_list_t *req_list);
int req_list_empty(req_list_t *req_list);
void save_current_posn(ptf_list_t *ptf_list,req_list_t *req_list);
void restore_current_posn(ptf_list_t *ptf_list,req_list_t *req_list);
void check_malloc_return(char *ptr);
int is_a_valid_ptf(char *ptf);
void help();
peresl_list_t *create_peresl_list(char *peresl_file);
void append_peresl_list(peresl_list_t *peresl_list, char *bad_ptf,
char *new_peresl_ptf);
peresl_info_t *find_in_peresl_list(peresl_list_t *peresl_list, char *chk_ptf);
void rewind_peresl_list(peresl_list_t *peresl_list);
peresl_info_t *get_next_peresl_info(peresl_list_t *peresl_list);
int peresl_list_empty(peresl_list_t *peresl_list);
void find_peresl_ptfs(peresl_info_t *peresl_list, ptf_list_t *ptf_list );
mlevel_list_t *create_mlevel_list(char *mlevel_file);
void append_mlevel_list(mlevel_list_t *mlevel_list, char *ptf);
int find_in_mlevel_list(char *ptf);
mlevel_info_t *get_next_mlevel_info(mlevel_list_t *mlevel_list);
void rewind_mlevel_list(mlevel_list_t *mlevel_list);
int mlevel_list_empty(mlevel_list_t *mlevel_list);
/************************/
/* Initialize variables */
/************************/
int verbose = FALSE;
int exclude_mode = FALSE;
int exclude_supersede_mode = FALSE;
int exclude_preventative_mode = FALSE;
char build_server[] = "build server";
char prod_server[] = "production server";
char ship_server[] = "ship server";
char no_where[] = "no where";
char input_file[] = "input file";
char usurper[] = "prvsup";
char super[] = "supersede";
char peresl[] = "pe-resl";
char *dir_build = NULL;
char *dir_prod = NULL;
char *dir_ship = NULL;
char *peresl_file = NULL;
char *mlevel_file = NULL;
char *out_name = NULL;
char *ptf_name = NULL;
int return_code = 0;
int loop_finished;
int coreq_loop_finished;
int duplicate_ptf = FALSE;
/** var's to save ptrs **/
ptf_info_t *save_ptf_list_current;
req_info_t *save_req_list_current;
mlevel_list_t *mlevel_list;
/****************/
/* Main program */
/****************/
main(int argc, char *argv[]) {
/* Files */
FILE *out_file;
FILE *ptf_file;
/* Index lists that include ptfs found in each directory */
index_list_t *build_list, *prod_list, *ship_list;
/* ptf list of all ptfs found */
ptf_list_t *ptf_list;
peresl_list_t *peresl_list;
/* getopt variables */
extern char *optarg;
extern int optind;
int c;
/* Misc. var's */
int err_code = 0;
char ptf_param[100];
char *period_ptr;
char *slash_ptr;
int ptfs_found;
/* Parse the command line */
while((c = getopt(argc , argv, "h?xtevnl:o:b:p:r:s:u:")) != EOF)
switch(c) {
case 'h': help();
case '?': if(strcmp(argv[optind - 1],"-?") == 0)
help(); /* '-?' was actually entered */
else
err_code = 1; /* an illegal option was entered */
break;
case 'v': verbose = TRUE;break;
case 'e': exclude_mode = TRUE;break;
case 'x': exclude_supersede_mode = TRUE;break;
case 'l': ptf_name = optarg;break;
case 'o': out_name = optarg;break;
case 'b': dir_build = optarg;break;
case 'p': dir_prod = optarg;break;
case 'r': peresl_file = optarg;break;
case 's': dir_ship = optarg;break;
case 't': duplicate_ptf = TRUE; break;
case 'n': exclude_preventative_mode = TRUE;break;
case 'u': mlevel_file = optarg;break;
default : err_code=1;
}
/********************/
/* Validate options */
/********************/
/* Check for at least one server */
if((dir_build == NULL)&&(dir_prod == NULL)&&(dir_ship == NULL)) {
printf("media_list: at least one server parameter is required\n");
err_code = 1;
}
/* Check ptf's in the -l input file */
if(ptf_name == NULL) {
printf("media_list: -l ptf file_name parameter is required\n");
err_code = 1;
} else {
ptf_file = fopen(ptf_name, "r");
if(ptf_file == NULL) {
printf("media_list: can't open ptf_filename: %s\n",ptf_name);
err_code = 1;
} else {
/* read ptfs from the ptf_file and add to ptf_list */
ptf_list=create_ptf_list();
ptfs_found=FALSE;
while(fscanf(ptf_file,"%s",ptf_param) != EOF) {
ptfs_found=TRUE;
/* strip off path if supplied */
if((slash_ptr = strrchr(ptf_param,'/')) != NULL)
strcpy(ptf_param, (char *) slash_ptr + 1);
/* strip off '.ptf' if supplied */
if((period_ptr = strrchr(ptf_param,'.')) != NULL)
if(strcmp(period_ptr, ".ptf") == 0)
*period_ptr = '\0';
/* check if comply with ptf format */
if(!is_a_valid_ptf(ptf_param)) {
printf("media_list: %s is not a valid ptf.\n",ptf_param);
printf(" Valid ptf names must be 7 characters in\n");
printf(" length with the last 5 numeric.\n");
err_code = 1;
} else {
/* append to ptf list if not already there */
if(find_in_ptf_list(ptf_list, ptf_param) == NULL) {
append_ptf_list(ptf_list,ptf_param,no_where,input_file,"none");
/* print out extra info if verbose mode */
if(verbose)
printf("%s read from ptf input file\n",ptf_param);
} else {
printf("media_list:warning: input ptf %s",ptf_param);
printf(" specified twice\n");
}
}
}
if(!ptfs_found) {
printf("media_list: input ptf_file must contain a ptf\n");
err_code = 1;
}
}
fclose(ptf_file);
}
/* Verify that the output file is accessible */
if(out_name == NULL)
out_file=stdout;
else {
out_file = fopen(out_name, "w");
if(out_file == NULL) {
printf("media_list: can't open output: %s\n",out_name);
err_code = 1;
}
}
/* Give help and exit if an error was found */
if(err_code != 0)
help();
/* For each server given, create index file lists */
if(dir_build != NULL)
build_list = create_index_list(dir_build);
if(dir_prod != NULL)
prod_list = create_index_list(dir_prod);
if(dir_ship != NULL)
ship_list = create_index_list(dir_ship);
if(peresl_file != NULL)
peresl_list = create_peresl_list(peresl_file);
mlevel_list = create_mlevel_list(mlevel_file);
/* Loop through the index lists adding prerequisite ptfs */
/* to the ptf_list until a pass is made in which no more */
/* prerequisite ptfs are found. 'loop_finished' */
/* will stay TRUE if no prereqs are added during a pass. */
loop_finished=FALSE;
while(!loop_finished) {
loop_finished=TRUE;
if(dir_build != NULL)
find_more_prereq_ptfs(build_list,build_server,ptf_list);
if(dir_prod != NULL)
find_more_prereq_ptfs(prod_list,prod_server,ptf_list);
if(dir_ship != NULL)
find_more_prereq_ptfs(ship_list,ship_server,ptf_list);
if(peresl_file != NULL)
find_peresl_ptfs(peresl_list,ptf_list);
}
/* Check for and report any errors with ptfs that weren't found */
report_ptfs_not_found(ptf_list);
/* Remove coreqs and ifreqs from the requisite lists */
remove_coreqs_and_ifreqs(ptf_list);
/* Output the list of ptfs in the correct order for the tape */
output_ptfs(out_file, ptf_list);
/* For each server given, free index file lists */
if(dir_build != NULL)
free(build_list);
if(dir_prod != NULL)
free(prod_list);
if(dir_ship != NULL)
free(ship_list);
/* Clean up and exit */
sync();
return(return_code);
} /* End of Main */
/*********************************************************************/
/* index list and adds prereq ptfs it finds to the ptf_list. */
/* It sets loop_finished=FALSE if any new prereq ptfs were */
/* added to the ptf list. */
/*********************************************************************/
/* */
/* ---------- ---------- ----------- */
/* | ptf1 | | ptf1 | | ptf2 | */
/* |server: | |server: | |server: | */
/* | nowhere|----||| | cur ser|--> | nowhere |----||| */
/* |parent: | |parent: | |parent: | */
/* | in_file| | in_file| | ptf1 | */
/* |req: | |req: | |req: | */
/* | none | | none | | coreq | */
/* |req_list| |req_list| | req_list| */
/* ----|----- becomes ----|----- -----|----- */
/* = V = */
/* = ---------- = */
/* | ptf2 | */
/* | coreq | */
/* ----|----- */
/* = */
/* = */
/* */
/* where the index line is lpp:ptf1:coreq:lpp:ptf2 */
/*********************************************************************/
void find_more_prereq_ptfs(index_list_t *index_list,
char *server,
ptf_list_t *ptf_list ) {
index_line_t *cur_line;
ptf_info_t *ptf_info;
ptf_info_t *loc_in_ptf_list;
int addFlag;
/* For each line in the index file */
rewind_index_list(index_list);
while((cur_line = get_next_index_line(index_list)) != NULL) {
/* Add the prereq ptf to the ptf list if the ptf on the left */
/* (ptf1) is in the list, and its prereq on the right (ptf2) */
/* is not in the list and it is actually a valid ptf */
if((ptf_info = find_in_ptf_list(ptf_list, cur_line->ptf1)) != NULL) {
/* store the server and the requisite found for this ptf */
addFlag=store_server_and_req(ptf_info,server,cur_line->ptf2,cur_line->req_type);
if (addFlag) {
if(is_a_valid_ptf(cur_line->ptf2)) {
if (find_in_ptf_list(ptf_list, cur_line->ptf2) == NULL) {
append_ptf_list(ptf_list, cur_line->ptf2, no_where,
cur_line->ptf1, cur_line->req_type);
loop_finished = FALSE;
}
};
}
else
/* If exclude_supersede mode is required and the req_type in the */
/* index line is "supersede", change the first character of the */
/* ptf2's req_type to 's' when ptf2 has already been in the ptf list */
if ((exclude_supersede_mode) && ( *(cur_line->req_type) == 's' )){
if ((loc_in_ptf_list = find_in_ptf_list(ptf_list, cur_line->ptf2)) != NULL)
*(loc_in_ptf_list->req_type) = 's' ;
};
}
else {
/* If -n was not specified and ptf1 supersedes a ptf in the list,*/
/* add it to the list. -- preventative supersedes -- */
if(((! exclude_preventative_mode) && ( *(cur_line->req_type) == 's')) &&
(ptf_info = find_in_ptf_list(ptf_list, cur_line->ptf2)) != NULL) {
if(is_a_valid_ptf(cur_line->ptf1)) {
append_ptf_list(ptf_list, cur_line->ptf1, no_where,
cur_line->ptf2, usurper);
loop_finished = FALSE;
}
}
};
};
}; /* end of find_more_prereq_ptfs */
/*********************************************************************/
/* store_server_and_req: This function stores the server that the */
/* given ptf was found on and also stores the requisite that */
/* that was found. */
/*********************************************************************/
int store_server_and_req(ptf_info_t *ptf_info,
char *server,
char *req_ptf,
char *req_type){
int addFlag = 0;
/* Check if ptf has already been found */
if(strcmp(ptf_info->server,no_where)== 0) {
ptf_info->server = server;
addFlag = 1;
if(verbose)
printf("%s found on %s\n", ptf_info->ptf, server);
}
else
/* check if found already on a different server */
if(strcmp(ptf_info->server,server) != 0) {
if ( !duplicate_ptf ) {
printf("media_list: %s was found on both the %s and %s\n",
ptf_info->ptf, ptf_info->server, server);
return_code = 1;
}
else
if (strcmp(server,build_server)==0) {
ptf_info->server = server;
addFlag = 1;
}
}
else
addFlag = 1;
/* if requisite ptf is in the maintlevel list, ignore it */
if(find_in_mlevel_list(req_ptf))
addFlag = 0;
if(addFlag) {
if (strcmp(req_type, super) == 0)
addFlag = 0;
else {
/* append requisite information if not already in requisite list*/
if((is_a_valid_ptf(req_ptf))&&
(find_in_req_list(ptf_info->req_list,req_ptf) == NULL)&&
((strcmp(req_type, "prereq") == 0) &&
(strcmp(ptf_info->ptf, req_ptf) != 0))){
append_req_list(ptf_info->req_list,req_ptf,req_type);
if(verbose)
printf("%s is a %s of %s\n", req_ptf, req_type, ptf_info->ptf);
}
}
}
return (addFlag);
} /* end of store_server_and_req */
/*********************************************************************/
/* report_ptfs_not_found: This function reads through the ptf_list */
/* checking for and reporting any ptfs were not found anywhere */
/* in the index files. The program is exited if errors found. */
/*********************************************************************/
void report_ptfs_not_found(ptf_list_t *ptf_list) {
ptf_info_t *cur_info;
/* for each ptf */
rewind_ptf_list(ptf_list);
while((cur_info = get_next_ptf_info(ptf_list)) != NULL) {
/* check that the ptf was found somewhere */
if(strcmp(cur_info->server, no_where) == 0) {
/* check if ptf is from the input file */
if(strcmp(cur_info->parent_ptf, input_file) == 0) {
return_code=99;
printf("media_list: ERROR: %s from stack list file ",cur_info->ptf);
printf("was not found in index files\n");
} else {
if (strcmp(cur_info->req_type, "supersede") == 0) {
printf("media_list: WARNING: %s ( superseded PTF of %s ) ",
cur_info->ptf, cur_info->parent_ptf);
}
else {
printf("media_list: WARNING: %s ( %s PTF of %s ) ",cur_info->ptf,
cur_info->req_type, cur_info->parent_ptf);
}
printf("was not found in index files\n");
}
}
}
if(return_code != 0) {
printf("\nmedia_list: process terminated\n\n");
exit(return_code);
}
} /* end of report_pts_not_found */
/*********************************************************************/
/* remove_coreqs_and_ifreqs: remove all coreqs and ifreqs found */
/* in the respective req_lists. */
/*********************************************************************/
void remove_coreqs_and_ifreqs(ptf_list_t *ptf_list) {
ptf_info_t *ptf_info;
req_info_t *prev_req_info;
req_info_t *req_info;
/* For each ptf in the ptf list */
rewind_ptf_list(ptf_list);
while((ptf_info = get_next_ptf_info(ptf_list)) != NULL) {
/* for each requisite of the ptf */
prev_req_info = NULL;
rewind_req_list(ptf_info->req_list);
while((req_info=get_next_req_info(ptf_info->req_list)) != NULL) {
/* check if it's a coreq or ifreq */
if((strcmp(req_info->req_type, "coreq") == 0) ||
(strcmp(req_info->req_type, "ifreq") == 0)) {
/* remove the coreq or ifreq */
if(ptf_info->req_list->start == req_info)
ptf_info->req_list->start = req_info->next_req;
else
prev_req_info->next_req = req_info->next_req;
if(ptf_info->req_list->last == req_info)
ptf_info->req_list->last = prev_req_info;
} else
prev_req_info = req_info;
}
}
} /* end of remove_coreqs_and_ifreqs */
/*********************************************************************/
/* output_ptfs: read through ptf_list printing out in a nice order */
/* for a future install (i.e. a ptf is printed out only after */
/* all of its requisites have been printed) */
/*********************************************************************/
void output_ptfs(FILE *out_file,
ptf_list_t *ptf_list) {
ptf_info_t *ptf_info;
req_info_t *prev_req_info;
req_info_t *req_info;
int ptf_outputted;
/* While ptfs are left to be outputted */
while(!ptf_list_empty(ptf_list)) {
ptf_outputted=FALSE;
/* For each ptf */
/* Print out ptf if all of its requisites are already printed */
rewind_ptf_list(ptf_list);
while((ptf_info = get_next_ptf_info(ptf_list)) != NULL) {
if(req_list_empty(ptf_info->req_list)) {
ptf_outputted=TRUE;
print_out_ptf(out_file,ptf_info);
save_current_posn(ptf_list,ptf_info->req_list);
remove_ptf_from_ptf_list(ptf_list, ptf_info->ptf);
restore_current_posn(ptf_list,ptf_info->req_list);
}
}
/* If no ptfs were outputted during a pass, every ptf must */
/* at least one requisite remaining. Thus, there must be a */
/* cycle among the relationships in these remaining ptfs */
if(!ptf_outputted) {
print_out_cyclic_ptfs(ptf_list);
exit(1);
}
}
} /* end of output_ptfs */
/*********************************************************************/
/* print_out_ptf: print out the given ptf to the output file with */
/* full file path. Only print input file ptfs if -e exclude */
/* mode is activated. */
/*********************************************************************/
void print_out_ptf(FILE *out_file, ptf_info_t *ptf_info) {
char *dir_out;
char *possible_slash;
if((exclude_mode)&&(strcmp(ptf_info->parent_ptf,input_file) != 0))
/* do not print */ ;
else {
/* If the first character of the ptf's req_type is 's', it indicates */
/* that this ptf is a supersede of some ptf. Cases of this ptf's */
/* req_type: */
/* "supersede": this ptf is a supersede of its parent. */
/* "sfreq", */
/* "soreq", */
/* "srereq": this ptf is a ifreq, coreq or prereq of its parent */
/* respectively, but a supersede of another ptf in the */
/* list. */
if ((exclude_supersede_mode) && ( *(ptf_info->req_type) == 's' ))
/* do not print */;
else{
if(strcmp(ptf_info->server, no_where) != 0) {
if(strcmp(ptf_info->server,build_server) == 0)
dir_out = dir_build;
else
if(strcmp(ptf_info->server,prod_server) == 0)
dir_out = dir_prod;
else
dir_out = dir_ship;
if(dir_out[strlen(dir_out) - 1] == '/')
possible_slash = "";
else
possible_slash = "/";
fprintf(out_file,"%s%s%s.ptf\n", dir_out, possible_slash, ptf_info->ptf);
}
}
}
} /* end of print_out_ptf */
/*********************************************************************/
/* remove_ptf_from_ptf_list: remove the given ptf from the ptf_list.*/
/*********************************************************************/
void remove_ptf_from_ptf_list(ptf_list_t *ptf_list, char *ptf_to_remove) {
ptf_info_t *prev_ptf_info;
ptf_info_t *ptf_info;
/* For each ptf */
prev_ptf_info = NULL;
rewind_ptf_list(ptf_list);
while((ptf_info = get_next_ptf_info(ptf_list)) != NULL) {
/* If this the ptf_info is the ptf that is to be removed */
if(strcmp(ptf_info->ptf,ptf_to_remove) == 0) {
/* Remove ptf_info from ptf_list */
if(ptf_list->start == ptf_info)
ptf_list->start = ptf_info->next_ptf;
else
prev_ptf_info->next_ptf = ptf_info->next_ptf;
if(ptf_list->last == ptf_info)
ptf_list->last = prev_ptf_info;
} else {
/* Remove the ptf from this ptf's list of requisites */
prev_ptf_info = ptf_info;
remove_ptf_from_req_list(ptf_info->req_list, ptf_to_remove);
}
}
} /* end of remove_ptf_from_ptf_list */
/*********************************************************************/
/* remove_ptf_from_req_list: remove the given ptf from the req_list.*/
/*********************************************************************/
void remove_ptf_from_req_list(req_list_t *req_list, char *ptf_to_remove) {
req_info_t *prev_req_info;
req_info_t *req_info;
/* For each ptf */
prev_req_info = NULL;
rewind_req_list(req_list);
while((req_info = get_next_req_info(req_list)) != NULL) {
/* if this the ptf_into is the ptf that is to be removed */
if(strcmp(req_info->req_ptf, ptf_to_remove) == 0) {
/* remove req_info from req_list */
if(req_list->start == req_info)
req_list->start = req_info->next_req;
else
prev_req_info->next_req = req_info->next_req;
if(req_list->last == req_info)
req_list->last = prev_req_info;
} else
prev_req_info = req_info;
}
} /* end of remove_ptf_from_req_list */
/*********************************************************************/
/* print_out_cyclic_ptfs: print out all relationships remaining */
/* in the ptf_list. The invalid cycle is contained somewhere */
/* among these remaining ptfs. */
/*********************************************************************/
void print_out_cyclic_ptfs(ptf_list_t *ptf_list) {
ptf_info_t *ptf_info;
req_info_t *req_info;
printf("\nmedia_list: circular dependencies found in index files\n");
printf("media_list: cycle is contained in ptfs printed below\n");
rewind_ptf_list(ptf_list);
while((ptf_info = get_next_ptf_info(ptf_list)) != NULL) {
printf("\n%s requisites:\n",ptf_info->ptf);
rewind_req_list(ptf_info->req_list);
while((req_info=get_next_req_info(ptf_info->req_list)) != NULL)
printf(" %s is a %s\n",req_info->req_ptf,req_info->req_type);
}
} /* end of print_out_cyclic_ptfs */
/*********************************************************************/
/* create_index_list: this function reads the given index file */
/* and returns a pointer to the index list containing an */
/* array of index lines read from the index file. */
/*********************************************************************/
index_list_t *create_index_list(char *server_dir) {
/* Index file var's */
index_list_t *index_list;
int in_fd;
char *in_name;
int in_length;
/* String pointers */
char *file_buf;
char *cur_char_ptr;
char *cur_line_ptr;
/* Counters and index */
int line_count;
int colon_count;
int i;
/* Set up in_name (the index file name) */
in_name = (char *) malloc(strlen(server_dir)+strlen(INDEX)+2);
check_malloc_return(in_name);
strcpy(in_name,server_dir);
if(in_name[strlen(in_name) - 1] != '/') /* append '/' if needed */
strcat(in_name,"/");
strcat(in_name,INDEX);
/* Open index file, read it into memory, and close it */
in_fd = open(in_name, O_RDONLY);
if(in_fd == -1) {
printf("media_list: can't open: %s\n",in_name);
exit(1);
}
in_length = lseek(in_fd, 0, SEEK_END); /* get length of file */
lseek(in_fd, 0, SEEK_SET); /* reset pointer to start of file */
file_buf = (char *) malloc(in_length+1); /* +1 to have room for */
check_malloc_return(file_buf); /* end of string */
read(in_fd, file_buf, in_length); /* read file into memory */
file_buf[in_length] = '\0'; /* put on end of string */
close(in_fd);
/* Check format of index file (four colons on each line) and count */
/* the number of lines for subsequent array allocation */
line_count=colon_count=0;
cur_line_ptr=file_buf;
for( i=0; i < in_length ; i++) {
cur_char_ptr = file_buf + i;
switch(*cur_char_ptr) {
case ':' : colon_count++; break;
case '\n':
if(colon_count != 4) {
*cur_char_ptr='\0';
printf("media_list: index file %s has bad data\n",in_name);
printf("line %d: '%s'\n",line_count+1, cur_line_ptr);
printf("media_list: process terminated\n");
exit(1);
}
line_count++;
colon_count=0;
cur_line_ptr=cur_char_ptr + 1;
}
}
/* Allocate space for index_list */
index_list = (index_list_t *) malloc(sizeof(index_list_t));
check_malloc_return(index_list);
/* Allocate space for index_line array */
index_list->index_line =
(index_line_t *) malloc(line_count * sizeof(index_line_t)+1);
check_malloc_return(index_list->index_line); /* +1 above ^^ */
/* so malloc won't bomb if line_count is zero (empty file) */
/* Set the array of index line pointers to point to the ptfs, lpps, */
/* and req_type read into memory from the index file. Replace */
/* colons and newlines with '\0' to separate the data. The format */
/* of an index line is 'lpp1:ptf1:req_type:lpp2:ptf2\n' */
for( i=0; i < line_count ; i++) {
if(i==0)
index_list->index_line[i].lpp1 = strtok(file_buf,":\n");
else
index_list->index_line[i].lpp1 = strtok(NULL,":\n");
index_list->index_line[i].ptf1 = strtok(NULL,":\n");
index_list->index_line[i].req_type = strtok(NULL,":\n");
index_list->index_line[i].lpp2 = strtok(NULL,":\n");
index_list->index_line[i].ptf2 = strtok(NULL,":\n");
/* check that req_type is valid */
if((strcmp(index_list->index_line[i].req_type,"coreq") != 0) &&
(strcmp(index_list->index_line[i].req_type,"prereq") != 0) &&
(strcmp(index_list->index_line[i].req_type,"ifreq") != 0) &&
(strcmp(index_list->index_line[i].req_type,"pe-resl") != 0) &&
(strcmp(index_list->index_line[i].req_type,"supersede") != 0) ) {
printf("media_list: index file %s has bad req type\n",in_name);
printf("line %d: invalid type of '%s'\n",i+1,
index_list->index_line[i].req_type);
printf("media_list: process terminated\n");
exit(1);
}
}
index_list->num_lines = line_count;
index_list->cur_line = 0;
return(index_list);
} /* end of create index_list */
/*********************************************************************/
/* rewind_index_list: set pointer to beginning of index list */
/*********************************************************************/
void rewind_index_list(index_list_t *index_list) {
index_list->cur_line = 0;
}
/*********************************************************************/
/* get_next_index_line: return a pointer to the next line in index */
/* list; return NULL when at end of list */
/*********************************************************************/
index_line_t *get_next_index_line(index_list_t *index_list) {
index_line_t *return_ptr;
if(index_list->cur_line == index_list->num_lines)
return_ptr = NULL;
else
return_ptr = &index_list->index_line[index_list->cur_line++];
return(return_ptr);
}
/*********************************************************************/
/* create_ptf_list: this function creates and returns an empty */
/* ptf_list (linked list) */
/*********************************************************************/
ptf_list_t *create_ptf_list() {
ptf_list_t *ptf_list;
ptf_list = (ptf_list_t *) malloc(sizeof(ptf_list_t));
check_malloc_return(ptf_list);
ptf_list->start = NULL;
ptf_list->last = NULL;
ptf_list->current = NULL;
return(ptf_list);
}
/*********************************************************************/
/* append_ptf_list: This function appends the given ptf and its */
/* info to the given ptf linked list */
/*********************************************************************/
void append_ptf_list(ptf_list_t *ptf_list,
char *new_ptf,
char *new_server,
char *new_parent_ptf,
char *new_req_type) {
ptf_info_t *new_ptf_info;
/* Allocate memory space for new info */
new_ptf_info = (ptf_info_t *) malloc(sizeof(ptf_info_t));
check_malloc_return(new_ptf_info);
new_ptf_info->ptf = (char *) malloc(strlen(new_ptf)+1);
check_malloc_return(new_ptf_info->ptf);
new_ptf_info->parent_ptf = (char *) malloc(strlen(new_parent_ptf)+1);
check_malloc_return(new_ptf_info->parent_ptf);
new_ptf_info->req_type = (char *) malloc(strlen(new_req_type)+1);
check_malloc_return(new_ptf_info->req_type);
/* Set pointers to point to new info */
strcpy(new_ptf_info->ptf,new_ptf);
new_ptf_info->server = new_server;
strcpy(new_ptf_info->parent_ptf,new_parent_ptf);
strcpy(new_ptf_info->req_type,new_req_type);
new_ptf_info->req_list = create_req_list();
/* Append to the beginning of list ( in final printout, */
/* ptfs should appear closer to their requisites if ptfs are */
/* added to the beginning rather than the end of the list ) */
new_ptf_info->next_ptf = ptf_list->start;
if(ptf_list_empty(ptf_list)) {
ptf_list->start = new_ptf_info;
ptf_list->last = new_ptf_info;
} else {
ptf_list->start = new_ptf_info;
}
} /* end of append_ptf_list */
/*********************************************************************/
/* find_in_ptf_list: This function checks whether the given ptf is */
/* in the given ptf linked list. It returns either the ptf_node*/
/* if found and otherwise NULL. */
/*********************************************************************/
ptf_info_t *find_in_ptf_list(ptf_list_t *ptf_list,
char *chk_ptf) {
int found;
ptf_info_t *cur_info;
found=FALSE;
rewind_ptf_list(ptf_list);
while((!found)&&((cur_info = get_next_ptf_info(ptf_list)) != NULL))
if(strcmp(cur_info->ptf, chk_ptf) == 0)
found=TRUE;
return(cur_info);
} /* end of find_in_ptf_list */
/*********************************************************************/
/* rewind_ptf_list: set pointer to beginning of ptf list */
/*********************************************************************/
void rewind_ptf_list(ptf_list_t *ptf_list) {
ptf_list->current = ptf_list->start;
}
/*********************************************************************/
/* get_next_ptf_info: return next info in ptf list; return NULL */
/* at end of list */
/*********************************************************************/
ptf_info_t *get_next_ptf_info(ptf_list_t *ptf_list) {
ptf_info_t *return_ptr;
return_ptr = ptf_list->current;
if(ptf_list->current != NULL)
ptf_list->current = ptf_list->current->next_ptf;
return(return_ptr);
} /* end of get_next_ptf_info */
/*********************************************************************/
/* ptf_list_empty: returns TRUE if empty, FALSE if not */
/*********************************************************************/
int ptf_list_empty(ptf_list_t *ptf_list) {
if(ptf_list->start == NULL)
return(TRUE);
else
return(FALSE);
}
/*********************************************************************/
/* create_req_list: this function creates and returns an empty */
/* requisite list (linked list) */
/*********************************************************************/
req_list_t *create_req_list() {
req_list_t *req_list;
req_list = (req_list_t *) malloc(sizeof(req_list_t));
check_malloc_return(req_list);
req_list->start = NULL;
req_list->last = NULL;
req_list->current = NULL;
return(req_list);
}
/*********************************************************************/
/* append_req_list: This function appends the given req and the */
/* requisite type to the given requisite linked list */
/*********************************************************************/
void append_req_list(req_list_t *req_list, char *new_req_ptf,
char *new_req_type) {
req_info_t *new_req_info;
/* Allocate memory space for new info */
new_req_info = (req_info_t *) malloc(sizeof(req_info_t));
check_malloc_return(new_req_info);
new_req_info->req_ptf = (char *) malloc(strlen(new_req_ptf)+1);
check_malloc_return(new_req_info->req_ptf);
new_req_info->req_type = (char *) malloc(strlen(new_req_type)+1);
check_malloc_return(new_req_info->req_type);
/* Set pointers to point to new info */
strcpy(new_req_info->req_ptf,new_req_ptf);
strcpy(new_req_info->req_type,new_req_type);
new_req_info->next_req = NULL;
/* append to end of list */
if(req_list_empty(req_list)) {
req_list->start = new_req_info;
req_list->last = new_req_info;
} else {
req_list->last->next_req = new_req_info;
req_list->last = new_req_info;
}
} /* end of append_req_list */
/*********************************************************************/
/* find_in_req_list: This function checks whether the given req is */
/* in the given req linked list. It returns either the req_node*/
/* if found and otherwise NULL. */
/*********************************************************************/
req_info_t *find_in_req_list(req_list_t *req_list,
char *chk_req_ptf) {
int found;
req_info_t *cur_info;
found=FALSE;
rewind_req_list(req_list);
while((!found)&&((cur_info = get_next_req_info(req_list)) != NULL))
if(strcmp(cur_info->req_ptf, chk_req_ptf) == 0)
found=TRUE;
return(cur_info);
} /* end of find_in_req_list */
/*********************************************************************/
/* rewind_req_list: set pointer to beginning of req list */
/*********************************************************************/
void rewind_req_list(req_list_t *req_list) {
req_list->current = req_list->start;
} /* end of rewind_req_list */
/*********************************************************************/
/* get_next_req_info: return next info in req list; return NULL */
/* at end of list */
/*********************************************************************/
req_info_t *get_next_req_info(req_list_t *req_list) {
req_info_t *return_ptr;
return_ptr = req_list->current;
if(req_list->current != NULL)
req_list->current = req_list->current->next_req;
return(return_ptr);
} /* end of get_next_req_info */
/*********************************************************************/
/* req_list_empty: returns TRUE if empty, FALSE if not */
/*********************************************************************/
int req_list_empty(req_list_t *req_list) {
if(req_list->start == NULL)
return(TRUE);
else
return(FALSE);
}
/*********************************************************************/
/* create_peresl_list: this function reads the given peresl file */
/* and returns a pointer to the peresl list containing an */
/* array of peresl PTFs read from the peresl file. */
/*********************************************************************/
peresl_list_t *create_peresl_list(char *peresl_file) {
/* Index file var's */
peresl_list_t *peresl_list;
peresl_info_t *peresl_info;
int in_fd;
int in_length;
/* String pointers */
char *file_buf;
char *cur_line_ptr;
char *cur_char_ptr;
char *next_line;
char *bad_ptf;
char *resolve;
char *apar;
/* Counters and index */
int line_count;
int i;
/* Open peresl file, read it into memory, and close it */
in_fd = open(peresl_file, O_RDONLY);
if(in_fd == -1) {
printf("media_list: can't open: %s\n",peresl_file);
exit(1);
}
in_length = lseek(in_fd, 0, SEEK_END); /* get length of file */
lseek(in_fd, 0, SEEK_SET); /* reset pointer to start of file */
file_buf = (char *) malloc(in_length+1); /* +1 to have room for */
check_malloc_return(file_buf); /* end of string */
read(in_fd, file_buf, in_length); /* read file into memory */
file_buf[in_length] = '\0'; /* put on end of string */
close(in_fd);
/* Read the peresl and save in lists. There may be header info */
/* and blank lines, so ignore anything that looks junky. */
/* Use only those lines with an apar "IX something". */
/* Format is: */
/* Bad_ptf Defect/apar Fixing_ptf release */
/* */
/* U407891 69648 U411113 bos320 */
/* U412495 IX32661 U412817 R320 */
/* U410648 76093 unfixed unknown */
/* Allocate space for peresl_list */
peresl_list = (peresl_list_t *) malloc(sizeof(peresl_list_t));
check_malloc_return(peresl_list);
peresl_list->start = NULL;
peresl_list->last = NULL;
peresl_list->current = NULL;
line_count=0;
cur_line_ptr=file_buf;
for( i=0; i < in_length ; i++) {
cur_char_ptr = file_buf + i;
if (*cur_char_ptr != '\n')
continue;
*cur_char_ptr = '\0';
bad_ptf = strtok(cur_line_ptr," \t");
cur_line_ptr = cur_char_ptr + 1;
if (! bad_ptf)
continue;
if (*bad_ptf != 'U')
continue;
if (! is_a_valid_ptf(bad_ptf))
continue;
apar = strtok(NULL," \t");
if (! apar)
continue;
if ((*apar != 'I') && (*apar != 'i'))
continue;
apar++;
if ((*apar != 'X') && (*apar != 'x'))
continue;
resolve = strtok(NULL," \t");
if (! resolve)
continue;
/* Ignore if Fix same as the bad ptf */
if (strcmp(resolve, bad_ptf) == 0)
continue;
if (strcmp(resolve, "unfixed") != 0) {
if (*resolve != 'U')
continue;
if (! is_a_valid_ptf(resolve))
continue;
}
if (peresl_info = find_in_peresl_list(peresl_list, bad_ptf)) {
if (find_in_req_list(peresl_info->req_list,resolve) == NULL) {
append_req_list(peresl_info->req_list, resolve, peresl);
}
}
else {
append_peresl_list(peresl_list, bad_ptf, resolve);
}
}
return(peresl_list);
} /* end of create peresl_list */
/*********************************************************************/
/* index list and adds peresl ptfs it finds to the ptf_list. */
/* It sets loop_finished=FALSE if any new peresl ptfs were */
/* added to the ptf list. */
/*********************************************************************/
void find_peresl_ptfs(peresl_info_t *peresl_list,
ptf_list_t *ptf_list ) {
peresl_info_t *cur_line;
req_info_t *cur_req;
ptf_info_t *ptf_info;
/* For each line in the peresl file */
rewind_peresl_list(peresl_list);
while((cur_line = get_next_peresl_info(peresl_list)) != NULL) {
/* Add the resolving ptf to the ptf list if the ptf on the left */
/* (ptf1) is in the list, and its resolver on the right (ptf2) */
/* is not in the list and it is actually a valid ptf */
if((ptf_info = find_in_ptf_list(ptf_list, cur_line->bad_ptf)) != NULL) {
/* For each resolving ptf in the peresl file */
rewind_req_list(cur_line->req_list);
while((cur_req = get_next_req_info(cur_line->req_list)) != NULL) {
if (find_in_ptf_list(ptf_list, cur_req->req_ptf) == NULL) {
if (strcmp(cur_req->req_ptf, "unfixed") == 0) {
printf("media_list: WARNING: unfixed pe-resl for %s\n",cur_line->bad_ptf);
*cur_req->req_ptf = 'U'; /* Telling once is enough. */
}
if (is_a_valid_ptf(cur_req->req_ptf)) {
append_ptf_list(ptf_list, cur_req->req_ptf, no_where,
cur_line->bad_ptf, peresl);
if(verbose)
printf("%s is a pe-resl of %s\n", cur_req->req_ptf, cur_line->bad_ptf);
loop_finished = FALSE;
}
}
}
}
}
} /* end of find_peresl_ptfs */
/*********************************************************************/
/* peresl_list_empty: returns TRUE if empty, FALSE if not */
/*********************************************************************/
int peresl_list_empty(peresl_list_t *peresl_list) {
if(peresl_list->start == NULL)
return(TRUE);
else
return(FALSE);
}
/*********************************************************************/
/* append_peresl_list: This function appends the given ptf and its */
/* info to the given peresl linked list */
/*********************************************************************/
void append_peresl_list(peresl_list_t *peresl_list,
char *new_ptf,
char *new_peresl_ptf) {
peresl_info_t *new_peresl_info;
/* Allocate memory space for new info */
new_peresl_info = (peresl_info_t *) malloc(sizeof(peresl_info_t));
check_malloc_return(new_peresl_info);
new_peresl_info->bad_ptf = (char *) malloc(strlen(new_ptf)+1);
check_malloc_return(new_peresl_info->bad_ptf);
/* Set pointers to point to new info */
strcpy(new_peresl_info->bad_ptf,new_ptf);
new_peresl_info->req_list = create_req_list();
append_req_list(new_peresl_info->req_list,new_peresl_ptf, peresl);
new_peresl_info->next_peresl = peresl_list->start;
if(peresl_list_empty(peresl_list)) {
peresl_list->start = new_peresl_info;
peresl_list->last = new_peresl_info;
} else {
peresl_list->start = new_peresl_info;
}
} /* end of append_peresl_list */
/*********************************************************************/
/* find_in_peresl_list: This function checks whether the given ptf */
/* is in the given peresl linked list. It returns either the */
/* peresl pointer if found or otherwise NULL. */
/*********************************************************************/
peresl_info_t *find_in_peresl_list(peresl_list_t *peresl_list,
char *chk_ptf) {
int found;
peresl_info_t *cur_info;
found=FALSE;
rewind_peresl_list(peresl_list);
while((!found)&&((cur_info = get_next_peresl_info(peresl_list)) != NULL))
if(strcmp(cur_info->bad_ptf, chk_ptf) == 0)
found=TRUE;
return(cur_info);
} /* end of find_in_peresl_list */
/*********************************************************************/
/* rewind_peresl_list: set pointer to beginning of peresl list */
/*********************************************************************/
void rewind_peresl_list(peresl_list_t *peresl_list) {
peresl_list->current = peresl_list->start;
} /* end of rewind_peresl_list */
/*********************************************************************/
/* get_next_peresl_info: return next info in peresl list; */
/* return NULL at end of list */
/*********************************************************************/
peresl_info_t *get_next_peresl_info(peresl_list_t *peresl_list) {
peresl_info_t *return_ptr;
return_ptr = peresl_list->current;
if(peresl_list->current != NULL)
peresl_list->current = peresl_list->current->next_peresl;
return(return_ptr);
} /* end of get_next_peresl_info */
/*********************************************************************/
/* mlevel_list_empty: returns TRUE if empty, FALSE if not */
/*********************************************************************/
int mlevel_list_empty(mlevel_list_t *mlevel_list) {
if(mlevel_list->start == NULL)
return(TRUE);
else
return(FALSE);
}
/*********************************************************************/
/* create_mlevel_list: this function reads the given mlevel file */
/* and returns a pointer to the mlevel list containing an */
/* array of mlevel PTFs read from the mlevel file. */
/* If no mlevel file was specified, this function simply */
/* creates an empty mlevel list. */
/*********************************************************************/
mlevel_list_t *create_mlevel_list(char *mlevel_file) {
/* Input file var's */
mlevel_info_t *mlevel_info;
int in_fd;
int in_length;
/* String pointers */
char *file_buf;
char *cur_line_ptr;
char *cur_char_ptr;
char *ptf;
/* Counter */
int i;
/* Allocate space for mlevel_list */
mlevel_list = (mlevel_list_t *) malloc(sizeof(mlevel_list_t));
check_malloc_return(mlevel_list);
mlevel_list->start = NULL;
mlevel_list->last = NULL;
mlevel_list->current = NULL;
/* If a put level was not specified, return empty mlevel list */
if(mlevel_file == NULL)
return(mlevel_list);
/* Open mlevel file, read it into memory, and close it */
in_fd = open(mlevel_file, O_RDONLY);
if(in_fd == -1) {
printf("media_list: can't open: %s\n",mlevel_file);
exit(1);
}
in_length = lseek(in_fd, 0, SEEK_END); /* get length of file */
lseek(in_fd, 0, SEEK_SET); /* reset pointer to start of file */
file_buf = (char *) malloc(in_length+1); /* +1 to have room for */
check_malloc_return(file_buf); /* end of string */
read(in_fd, file_buf, in_length); /* read file into memory */
file_buf[in_length] = '\0'; /* put on end of string */
close(in_fd);
/* Read the mlevel file and save in a list. */
cur_line_ptr=file_buf;
for( i=0; i < in_length ; i++) {
cur_char_ptr = file_buf + i;
if (*cur_char_ptr != '\n')
continue;
*cur_char_ptr = '\0';
ptf = strtok(cur_line_ptr," \t");
cur_line_ptr = cur_char_ptr + 1;
if (! ptf)
continue;
if (*ptf != 'U')
continue;
if (! is_a_valid_ptf(ptf))
continue;
append_mlevel_list(mlevel_list, ptf);
}
return(mlevel_list);
} /* end of create mlevel_list */
/*********************************************************************/
/* append_mlevel_list: This function appends the given ptf */
/* to the given mlevel linked list */
/*********************************************************************/
void append_mlevel_list(mlevel_list_t *mlevel_list,
char *new_ptf) {
mlevel_info_t *new_mlevel_info;
/* Allocate memory space for new info */
new_mlevel_info = (mlevel_info_t *) malloc(sizeof(mlevel_info_t));
check_malloc_return(new_mlevel_info);
new_mlevel_info->ptf = (char *) malloc(strlen(new_ptf)+1);
check_malloc_return(new_mlevel_info->ptf);
/* Set pointers to point to new info */
strcpy(new_mlevel_info->ptf,new_ptf);
new_mlevel_info->next_mlevel = mlevel_list->start;
if(mlevel_list_empty(mlevel_list)) {
mlevel_list->start = new_mlevel_info;
mlevel_list->last = new_mlevel_info;
} else {
mlevel_list->start = new_mlevel_info;
}
} /* end of append_mlevel_list */
/*********************************************************************/
/* find_in_mlevel_list: This function checks whether the given ptf */
/* is in the maintlevel linked list. */
/*********************************************************************/
int find_in_mlevel_list(char *chk_ptf) {
int found;
mlevel_info_t *cur_info;
found=FALSE;
rewind_mlevel_list(mlevel_list);
while((!found)&&((cur_info = get_next_mlevel_info(mlevel_list)) != NULL))
if(strcmp(cur_info->ptf, chk_ptf) == 0)
found=TRUE;
return(found);
} /* end of find_in_mlevel_list */
/*********************************************************************/
/* get_next_mlevel_info: return next info in mlevel list; */
/* return NULL at end of list */
/*********************************************************************/
mlevel_info_t *get_next_mlevel_info(mlevel_list_t *mlevel_list) {
mlevel_info_t *return_ptr;
return_ptr = mlevel_list->current;
if(mlevel_list->current != NULL)
mlevel_list->current = mlevel_list->current->next_mlevel;
return(return_ptr);
} /* end of get_next_mlevel_info */
/*********************************************************************/
/* rewind_mlevel_list: set pointer to beginning of mlevel list */
/*********************************************************************/
void rewind_mlevel_list(mlevel_list_t *mlevel_list) {
mlevel_list->current = mlevel_list->start;
} /* end of rewind_mlevel_list */
/*********************************************************************/
/* save_current_posn: save current position in linked lists */
/*********************************************************************/
void save_current_posn(ptf_list_t *ptf_list,
req_list_t *req_list) {
save_ptf_list_current = ptf_list->current;
save_req_list_current = req_list->current;
}
/*********************************************************************/
/* restore_current_posn: restore saved position in linked lists */
/*********************************************************************/
void restore_current_posn(ptf_list_t *ptf_list,req_list_t *req_list) {
ptf_list->current = save_ptf_list_current;
req_list->current = save_req_list_current;
}
/*********************************************************************/
/* check_malloc_return: exit out if malloc failed ( ptr = null ) */
/*********************************************************************/
void check_malloc_return(char *ptr) {
if (ptr == NULL) {
printf("media_list: malloc was unable to allocate memory\n");
printf("media_list: program terminated\n");
exit(1);
}
}
/*********************************************************************/
/* is_a_valid_ptf: checks if last 5 chars are digits */
/* returns TRUE or FALSE */
/*********************************************************************/
int is_a_valid_ptf(char *ptf) {
if(strspn(ptf + strlen(ptf) - 5, "1234567890") == 5)
return(TRUE);
else
return(FALSE);
}
/*********************************************************************/
/* help: print syntax and exit */
/*********************************************************************/
void help() {
printf("\n");
printf("%s\n",sccsid);
printf("Usage\n");
printf("media_list [-s dirname_ship] [-p dirname_prod]\n");
printf(" [-b dirname_build] [-v] [-e] [-x] [-t] [-n] [-h] [-?]\n");
printf(" [-r peresl_filename ]\n");
printf(" [-o out_filename ] -l mif_ccss_list_filename\n");
printf(" where: \n");
printf(" dirname_ship - path to mif directory on 'ship' server.\n");
printf(" dirname_prod - path to mif directory on 'production' server.\n");
printf(" dirname_build - path to mif directory on 'build' server.\n");
printf(" -v verbose option - prints extra info\n");
printf(" -l mif_ccss_list_filename - contains list\n");
printf(" of mif/ccss files to package.\n");
printf(" -o outfilename - path & filename for ordered \n");
printf(" list of prereqs.\n");
printf(" -r peresl_filename - path & filename of PTF error \n");
printf(" resolution file.\n");
printf(" -e - exclude requisites\n");
printf(" -x - exclude supersedes\n");
printf(" -t - duplicate PTF's allowed on different servers.\n");
printf(" -n - no preventative supersedes\n");
printf(" -h | -? options to list usage message\n");
printf("\n");
exit(1);
} /* end of help function */
/* END OF PROGRAM */