home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #20 / NN_1992_20.iso / spool / comp / os / vms / 14730 < prev    next >
Encoding:
Text File  |  1992-09-08  |  17.1 KB  |  651 lines

  1. Newsgroups: comp.os.vms
  2. Path: sparky!uunet!decwrl!deccrl!news.crl.dec.com!rdg.dec.com!vogon.enet.dec.com!millson
  3. From: millson@vogon.enet.dec.com (Martin "Morgul" Millson)
  4. Subject: Re: Disk quota report facility wanted?
  5. Message-ID: <1992Sep8.081004.15882@rdg.dec.com>
  6. Lines: 638
  7. Sender: news@rdg.dec.com (Mr News)
  8. Reply-To: millson@vogon.enet.dec.com (Martin "Morgul" Millson)
  9. Organization: International Systems Engineering/Reading ,Digital Equipment Corp
  10. References:  <01GO15DW2CPE9EDHKB@RCNVMS.RCN.MASS.EDU>
  11. Date: Tue, 8 Sep 1992 08:10:04 GMT
  12.  
  13.  
  14. I have written some software to report on disk quota's. The following is
  15. the source the cld and actual C code
  16.  
  17. ------ DISKMONITOR.CLD------------
  18. MODULE DISKMON
  19. IDENT "V1.0"
  20. !++
  21. ! Facility:
  22. !   Disk Monitor - Diskmon
  23. ! Abstract:
  24. !   The CLD file for the Disk Monitor
  25. ! Author:
  26. !   Martin Millson
  27. ! Creation Date: 10-JAN-1992
  28. ! Modification History:
  29. !--
  30.  
  31. DEFINE VERB DISKMONITOR
  32.     PARAMETER P1, LABEL=SUBCOMMAND,
  33.                 PROMPT="Command",
  34.                 VALUE(REQUIRED,TYPE=SUBCOMMAND_KEYWORDS)
  35.  
  36. DEFINE TYPE SUBCOMMAND_KEYWORDS
  37.     KEYWORD USAGE,
  38.                 LABEL=USAGE,
  39.                 SYNTAX=USAGE_SYNTAX
  40.     KEYWORD BACKUP_CHECK,
  41.                 LABEL=BACKUP_CHECK,
  42.                 SYNTAX=BACKUP_CHECK_SYNTAX
  43.  
  44.  
  45. DEFINE SYNTAX USAGE_SYNTAX
  46.     IMAGE DISKMON$USAGE.EXE
  47.     PARAMETER P1, LABEL=SUBCOMMAND,
  48.                 VALUE(REQUIRED)
  49.     PARAMETER P2, LABEL=USAGEFILE,
  50.                 PROMPT="Usage File",
  51.                 VALUE(REQUIRED,TYPE=$INFILE)
  52.     QUALIFIER MAILTO,
  53.                 LABEL=MAILTO,
  54.                 NONNEGATABLE,
  55.                 VALUE(REQUIRED)
  56.     QUALIFIER FILES,
  57.             LABEL=FILES,
  58.             NEGATABLE
  59.     QUALIFIER TOTALS,
  60.             LABEL=TOTALS,
  61.             NEGATABLE,
  62.             DEFAULT
  63.     QUALIFIER OUTPUT,
  64.             VALUE(TYPE=$OUTFILE)
  65.             
  66. DEFINE SYNTAX BACKUP_CHECK_SYNTAX
  67.     IMAGE DISKMON$BACKUP_CHECK.EXE
  68.     PARAMETER P1, LABEL=SUBCOMMAND,
  69.                 VALUE(REQUIRED)
  70.     PARAMETER P2, LABEL=DISK,
  71.                 PROMPT="Disk",
  72.                 VALUE(REQUIRED)
  73.     QUALIFIER MAILTO,
  74.                 LABEL=MAILTO,
  75.                 NONNEGATABLE,
  76.                 VALUE(REQUIRED)
  77.     QUALIFIER OUTPUT,
  78.             VALUE(TYPE=$OUTFILE)
  79.  
  80. ---- DISKMON$USAGE.C-------------
  81.  
  82. /*
  83. **++
  84. **  Facility:
  85. **
  86. **    Disk Monitor - Diskmon
  87. **
  88. **  Version: V1.0-0
  89. **
  90. **  Abstract:
  91. **
  92. **    Generates a Report from a disk usage file
  93. **
  94. **
  95. **  Author:
  96. **    Martin Millson,        International Systems Engineering,
  97. **                Reading UK,
  98. **                Digital Equipement Corp.
  99. **
  100. **  Creation Date:  8-JAN-1992
  101. **
  102. **  Modification History:
  103. **--
  104. */
  105.  
  106. /*
  107. **  Include Files
  108. */
  109. #include <stdio.h>
  110. #include <nam.h>
  111. #include <rmsdef.h>
  112. #include <maildef>
  113. #include <ssdef.h>
  114. #include <climsgdef.h>
  115. #include <descrip.h>
  116. #include <usgdef.h>
  117. /*                                        */
  118. /* Defines                                    */
  119. /*                                        */
  120. #define VERSION "V1.0-0"
  121. #define IS_GENERAL_ID  80000000  /* When identifiers are created,        */
  122.                                  /* GENERAL identifiers automatically        */
  123.                                  /* have %x80000000 added to the identifier */
  124.                                  /* value.                    */
  125.                                  /* This differentiates them from        */
  126.                                  /* UIC identifiers.                */
  127. #define NODIR_FILES_UIC    0    /* UIC used for total of files with        */
  128.                 /* directory spec of []                */
  129. #define VMS_UIC        65537    /* UIC used by VMS when init disks        */
  130. #define TRUE 1
  131. #define FALSE 0
  132. /*                                        */
  133. /* Typedefs                                    */
  134. /*                                        */
  135. typedef struct itmlst
  136.     {
  137.         short buffer_length;
  138.         short item_code;
  139.         long buffer_address;
  140.         long return_length_address;
  141.     } ITMLST;
  142.     
  143. struct list
  144. {
  145.     struct list *next;
  146.     unsigned long int uic;
  147.     unsigned long int running_total_used;
  148.     unsigned long int running_total_alloc;
  149.     struct list *top;
  150. };
  151.  
  152.  
  153. void add_to_total(struct list *list_header,
  154.          unsigned long int uic,
  155.          unsigned long int used,
  156.          unsigned long int allocated)
  157. {
  158.  
  159.     struct list *top_of_list;
  160.  
  161.     top_of_list = list_header -> top;
  162.     if (list_header -> uic == uic)
  163.     {
  164.     list_header -> running_total_used += used;
  165.     list_header -> running_total_alloc += allocated;
  166.     }
  167.     else
  168.     {
  169.     if (list_header -> next == NULL)
  170.     {
  171.         list_header -> next = malloc (sizeof(struct list));
  172.         list_header -> next -> uic = uic;
  173.         list_header -> next -> running_total_used = used;
  174.         list_header -> next -> running_total_alloc = allocated;
  175.         list_header -> next -> top = top_of_list;
  176.         list_header -> next -> next = NULL;
  177.     }
  178.     else
  179.     {
  180.         add_to_total(list_header -> next,uic,used,allocated);
  181.     }
  182.     }
  183. }
  184.  
  185. void PutTotals(FILE *output_file,struct list *list_header)
  186. {
  187.  
  188.     struct list *top_of_list;
  189.     unsigned long int grand_total_used  = 0;
  190.     unsigned long int grand_total_alloc  = 0;
  191.     char namebuf[100];           
  192.     unsigned int rights_id  = 0, attrib  = 0;
  193.     int context = 0, status = 0;
  194.     short namlen  = 0;
  195.     char id_string[14];
  196.     char title1[6] = "Owner";
  197.     char title2[3] = "Id";
  198.     char title3[5] = "Used";
  199.     char title4[6] = "Alloc";
  200.     $DESCRIPTOR(nambuf_dsc,namebuf);
  201.     
  202.     top_of_list = list_header -> top;
  203.     fprintf(output_file,"\n");
  204.     fprintf(output_file,"Disk Usage Totals\n");
  205.     fprintf(output_file,"-----------------\n");
  206.     fprintf(output_file,"%-32s\t%-14s\t%-6s\t%-7s\n",
  207.                         title1,
  208.                         title2,
  209.                         title3,
  210.                         title4);
  211.     while(top_of_list != NULL)
  212.     {
  213.         nambuf_dsc.dsc$w_length = sizeof(namebuf)-1;
  214.         status = SYS$IDTOASC(top_of_list -> uic, &namlen, &nambuf_dsc,
  215.                              &rights_id,&attrib,&context);
  216.     switch (status)
  217.     {
  218.         case SS$_NORMAL: namebuf[namlen] = 0; break;
  219.         case SS$_IVIDENT:
  220.         case SS$_NOSUCHID:  {
  221.                     switch (top_of_list -> uic)
  222.                     {
  223.                     case NODIR_FILES_UIC:
  224.                         sprintf(namebuf,"<NO DIRECTORY>");
  225.                         break;
  226.                     case VMS_UIC:
  227.                         sprintf(namebuf,"<VMS>");
  228.                         break;
  229.                     default:
  230.                         sprintf(namebuf,"<NOSUCHID>");
  231.                         break;
  232.                     }
  233.                 }; break;
  234.         case SS$_ACCVIO: 
  235.         case SS$_INSFMEM:
  236.         case RMS$_PRV:
  237.         case SS$_NOIOCHAN:
  238.         default: lib$signal(status); break; 
  239.     }
  240.     if (rights_id >= IS_GENERAL_ID)
  241.     {
  242.         sprintf(id_string,"%x",rights_id);
  243.     }
  244.     else
  245.     {
  246.         sprintf(id_string,"[%o,%o]",(top_of_list -> uic / 65536),
  247.                     (top_of_list -> uic % 65536));
  248.     }
  249.     fprintf(output_file,"%-32s\t%-14s\t%d\t%d \n",
  250.                     namebuf,
  251.                     id_string,
  252.                     top_of_list -> running_total_used,
  253.                     top_of_list -> running_total_alloc);
  254.     grand_total_used += top_of_list -> running_total_used;
  255.     grand_total_alloc += top_of_list -> running_total_alloc;
  256.     top_of_list = top_of_list -> next;
  257.     }
  258.     status = SYS$FINISH_RDB(&context);
  259.     fprintf(output_file,"Grand Total is %d Used Blocks\n",grand_total_used);
  260.     fprintf(output_file,"            is %d Allocated
  261. Blocks\n",grand_total_alloc);
  262. }
  263.  
  264. int GetHeaderRec(FILE *InFp, struct usgdef *HeaderRec)
  265. {
  266.     memset(HeaderRec,NULL,sizeof(struct usgdef));
  267.     fread(HeaderRec,sizeof(struct usgdef),1,InFp);
  268.     return(TRUE);
  269. }
  270.  
  271. int GetFileRec(FILE *InFp, struct usgdef1 *FileRec)
  272. {
  273.     memset(FileRec,NULL,sizeof(struct usgdef1));
  274.     if (fgetc(InFp)==EOF) return (FALSE);
  275.     fread(&(FileRec->usg$l_fileowner),sizeof(char),4,InFp);
  276.     fread(&(FileRec->usg$l_allocated),sizeof(char),4,InFp);
  277.     fread(&(FileRec->usg$l_used),sizeof(char),4,InFp);
  278.     fread(&(FileRec->usg$w_dir_len),sizeof(char),2,InFp);
  279.     fread(&(FileRec->usg$w_spec_len),sizeof(char),2,InFp);
  280.     fread(&(FileRec->usg$t_filespec),sizeof(char),
  281.         FileRec->usg$w_spec_len,InFp);
  282.     return (TRUE);
  283. }
  284.  
  285. PutHeader(FILE *output_file,struct usgdef headerrec)
  286. {
  287.     char timbuf[24];
  288.     unsigned short timlen;
  289.  
  290.     $DESCRIPTOR(TIME_DESC,timbuf);
  291.  
  292.     fprintf(output_file,"\n");    
  293.     fprintf(output_file,"Volume Details\n");    
  294.     fprintf(output_file,"--------------\n");    
  295.     fprintf(output_file,"Volume Set Name : %.12s\tVolume One Name : %.12s\n",
  296.                         headerrec.usg$t_strucname,
  297.                         headerrec.usg$t_volname);
  298.     fprintf(output_file,"Volume Owner    : %.12s\tVolume Format   : %.12s\n",
  299.                         headerrec.usg$t_ownername,
  300.                         headerrec.usg$t_format);
  301.     sys$asctim (
  302.         &timlen, 
  303.         &TIME_DESC, 
  304.         &headerrec.usg$q_time, 
  305.         0);
  306.     timbuf[timlen] = 0;
  307.     fprintf(output_file,"Volume Serial # : %011d\tData Collected  : %s\n",
  308.                         headerrec.usg$l_serialnum,
  309.                         timbuf);
  310. }
  311. PutFile(FILE *output_file,struct usgdef1 filerec)
  312. {
  313.     char namebuf[100];           
  314.     unsigned int rights_id  = 0, attrib  = 0;
  315.     int context = 0, status = 0;
  316.     short namlen  = 0;
  317.     char id_string[14];
  318.     $DESCRIPTOR(nambuf_dsc,namebuf);
  319.     
  320.     nambuf_dsc.dsc$w_length = sizeof(namebuf)-1;
  321.  
  322.     if (filerec.usg$w_dir_len == 2)
  323.     {
  324.     /* Set lost files to no directory files uic                */
  325.     filerec.usg$l_fileowner = NODIR_FILES_UIC;
  326.     }
  327.     
  328.     status = SYS$IDTOASC(filerec.usg$l_fileowner, &namlen, &nambuf_dsc,
  329.                              &rights_id,&attrib,&context);
  330.  
  331.     switch (status)
  332.     {
  333.     case SS$_NORMAL: namebuf[namlen] = 0; break;
  334.     case SS$_IVIDENT:
  335.     case SS$_NOSUCHID:  {
  336.                 switch (filerec.usg$l_fileowner)
  337.                 {
  338.                     case NODIR_FILES_UIC:
  339.                         sprintf(namebuf,"<NO DIRECTORY>");
  340.                         break;
  341.                     case VMS_UIC:
  342.                         sprintf(namebuf,"<VMS>");
  343.                         break;
  344.                     default:
  345.                         sprintf(namebuf,"<NOSUCHID>");
  346.                         break;
  347.                 }
  348.                 }; break;
  349.     case SS$_ACCVIO: 
  350.     case SS$_INSFMEM:
  351.     case RMS$_PRV:
  352.     case SS$_NOIOCHAN:
  353.     default: lib$signal(status); break; 
  354.     }
  355.  
  356.     if (rights_id >= IS_GENERAL_ID)
  357.     {
  358.     sprintf(id_string,"%x",rights_id);
  359.     }
  360.     else
  361.     {
  362.     sprintf(id_string,"[%o,%o]",(filerec.usg$l_fileowner / 65536),
  363.                     (filerec.usg$l_fileowner % 65536));
  364.     }
  365.     fprintf(output_file,"%-32s\t%-14s\t%d\t%d\t%-*.s\n",
  366.                     namebuf,
  367.                     id_string,
  368.                     filerec.usg$l_used,
  369.                     filerec.usg$l_allocated,
  370.                     filerec.usg$w_spec_len,
  371.                     filerec.usg$t_filespec);
  372.     status = SYS$FINISH_RDB(&context);
  373. }
  374.  
  375. int mail_send_message (
  376.             struct dsc$descriptor_s *to_user,
  377.             struct dsc$descriptor_s *subject,
  378.             struct dsc$descriptor_s *file_name)
  379. {
  380.  
  381.     int send_context = 0;
  382.  
  383.     char resultspec[NAM$C_MAXRSS],
  384.      c_to_user[NAM$C_MAXRSS],
  385.      c_subject[NAM$C_MAXRSS],
  386.      c_file_name[NAM$C_MAXRSS];
  387.     long resultspeclen;
  388.     int     status = SS$_NORMAL,
  389.      file_len = 0,
  390.      subject_line_len = 0,
  391.      to_user_len =0;
  392.     ITMLST
  393.     nulllist[] = {
  394.         {0, MAIL$_NOSIGNAL , 0, 0},
  395.         {0,0,0,0} },
  396.     address_itmlst[] = {
  397.         {sizeof(c_to_user), MAIL$_SEND_USERNAME , c_to_user, &to_user_len},
  398.         {0, MAIL$_NOSIGNAL , 0, 0},
  399.         {0,0,0,0}},
  400.     bodypart_itmlst[] = {
  401.         {sizeof(c_file_name), MAIL$_SEND_FILENAME, c_file_name, &file_len},
  402.         {0, MAIL$_NOSIGNAL , 0, 0},
  403.         {0,0,0,0}},
  404.     out_bodypart_itmlst[] = {
  405.         {sizeof(resultspec), MAIL$_SEND_RESULTSPEC, resultspec,
  406.         &resultspeclen},
  407.         {0, MAIL$_NOSIGNAL , 0, 0},
  408.         {0,0,0,0}},
  409.     attribute_itmlst[] = {
  410.         {sizeof(c_to_user), MAIL$_SEND_TO_LINE, c_to_user, &to_user_len},
  411.         {sizeof(c_subject), MAIL$_SEND_SUBJECT,c_subject,&subject_line_len},
  412.         {0, MAIL$_NOSIGNAL , 0, 0},
  413.         {0,0,0,0}};
  414.     
  415.     status = mail$send_begin(&send_context,&nulllist,&nulllist);
  416.     if (status != SS$_NORMAL)
  417.     return (status);
  418.  
  419.     memset(c_to_user,NULL,sizeof(c_to_user));
  420.     sprintf (c_to_user, "%s\0", to_user -> dsc$a_pointer);
  421.     address_itmlst[0].buffer_length = strlen(c_to_user);
  422.     address_itmlst[0].buffer_address = c_to_user;
  423.     
  424.     status = mail$send_add_address(&send_context,&address_itmlst,&nulllist);
  425.     if (status != SS$_NORMAL)
  426.     return (status);
  427.  
  428.  
  429.     attribute_itmlst[0].buffer_length = strlen(c_to_user);
  430.     attribute_itmlst[0].buffer_address = c_to_user;
  431.  
  432.     memset(c_subject,NULL,sizeof(c_subject));
  433.     sprintf (c_subject, "%s\0", subject -> dsc$a_pointer);
  434.     attribute_itmlst[1].buffer_length = strlen(c_subject);
  435.     attribute_itmlst[1].buffer_address = c_subject;
  436.  
  437.     
  438.     status =
  439. mail$send_add_attribute(&send_context,&attribute_itmlst,&nulllist);
  440.     if (status != SS$_NORMAL)
  441.     return (status);
  442.     
  443.     sprintf (c_file_name, "%s\0", file_name -> dsc$a_pointer);
  444.     bodypart_itmlst[0].buffer_length = strlen(c_file_name);
  445.     bodypart_itmlst[0].buffer_address = c_file_name;
  446.     
  447.     status = mail$send_add_bodypart(&send_context,&bodypart_itmlst,
  448.                      &out_bodypart_itmlst);
  449.     if (status != SS$_NORMAL)
  450.     return (status);    
  451.  
  452.     resultspec[resultspeclen] = '\0';
  453.     status = mail$send_message(&send_context,&nulllist,
  454.                      &nulllist);
  455.     if (status != SS$_NORMAL)
  456.     return (status);
  457.     
  458.     status = mail$send_end(&send_context,&nulllist,
  459.                      &nulllist);
  460.     if (status != SS$_NORMAL)
  461.     return (status);
  462.  
  463.     return(status);
  464.  
  465. }
  466.  
  467. int main(void)
  468. {
  469.     struct list *place_in_list;
  470.     FILE *usage_file;
  471.     FILE *output_file;
  472.     unsigned short retlen;
  473.     unsigned long ret_status;
  474.     int m_status;
  475.     int first_title = TRUE;
  476.     int display_totals = TRUE;
  477.     int display_files = FALSE;
  478.     int send_mail = FALSE;
  479.     struct usgdef headerrec;
  480.     struct usgdef1 filerec;
  481.     char title1[6] = "Owner";
  482.     char title2[3] = "Id";
  483.     char title3[5] = "Used";
  484.     char title4[6] = "Alloc";
  485.     char title5[5] = "File";
  486.     
  487.     char output_file_name[NAM$C_MAXRSS];
  488.     char usage_file_name[NAM$C_MAXRSS];
  489.     char mailto_string[NAM$C_MAXRSS];
  490.     char subject_string[NAM$C_MAXRSS];
  491.     char result_time[24];
  492.  
  493.     $DESCRIPTOR(MAIL_DESC,"MAILTO");
  494.     $DESCRIPTOR(USAGE_DESC,"USAGEFILE");
  495.     $DESCRIPTOR(OUTPUT_DESC,"OUTPUT");
  496.     $DESCRIPTOR(FILE_DESC,"FILES");
  497.     $DESCRIPTOR(TOTALS_DESC,"TOTALS");
  498.  
  499.     $DESCRIPTOR(INPUT_FILE_DESC,usage_file_name);
  500.     $DESCRIPTOR(OUTPUT_FILE_DESC,output_file_name);
  501.     $DESCRIPTOR(MAILTO_STRING_DESC,mailto_string);
  502.     $DESCRIPTOR(SUBJECT_STRING_DESC,subject_string);
  503.     
  504.     $DESCRIPTOR(time_desc,result_time);
  505.     
  506.     place_in_list = malloc(sizeof(struct list));
  507.     place_in_list -> uic = 0;
  508.     place_in_list -> running_total_used = 0;
  509.     place_in_list -> running_total_alloc = 0;
  510.     place_in_list -> next = NULL;
  511.     place_in_list -> top  = place_in_list;
  512.  
  513.     /* Input file from ANA/DISK/USAGE */
  514.     
  515.     ret_status = cli$present( &USAGE_DESC );
  516.     if (ret_status == CLI$_PRESENT)
  517.     {
  518.         ret_status = cli$get_value(&USAGE_DESC,
  519.                        &INPUT_FILE_DESC,
  520.                        &retlen);
  521.         usage_file_name[retlen] = '\0';
  522.     }
  523.     else
  524.     sprintf(usage_file_name,"USAGE.DAT");
  525.  
  526.     /* Output file for report */
  527.     
  528.     ret_status = cli$present( &OUTPUT_DESC );
  529.     if (ret_status == CLI$_PRESENT)
  530.     {
  531.         ret_status = cli$get_value(&OUTPUT_DESC,
  532.                        &OUTPUT_FILE_DESC,
  533.                        &retlen);
  534.         output_file_name[retlen] = '\0';
  535.     }
  536.     else
  537.     sprintf(output_file_name,"SYS$OUTPUT");
  538.  
  539.     ret_status = cli$present( &MAIL_DESC );
  540.     if (ret_status == CLI$_PRESENT)
  541.     {
  542.         ret_status = cli$get_value(&MAIL_DESC,
  543.                        &MAILTO_STRING_DESC,
  544.                        &retlen);
  545.         mailto_string[retlen] = '\0';
  546.         send_mail = TRUE;
  547.     }
  548.     else
  549.     send_mail = FALSE;
  550.         
  551.     switch (cli$present(&FILE_DESC))
  552.     {
  553.         case CLI$_PRESENT: display_files = TRUE; break;
  554.         case CLI$_DEFAULTED:
  555.     case CLI$_ABSENT:
  556.         case CLI$_NEGATED: display_files = FALSE; break;
  557.     default: break;
  558.     }
  559.  
  560.     switch (cli$present(&TOTALS_DESC))
  561.     {
  562.     case CLI$_ABSENT:
  563.         case CLI$_DEFAULTED:
  564.         case CLI$_PRESENT: display_totals = TRUE; break;
  565.         case CLI$_NEGATED: display_totals = FALSE; break;
  566.     default: break;
  567.     }
  568.     if ((usage_file = fopen(usage_file_name, "rb")) == NULL)
  569.     {
  570.     perror(usage_file_name);
  571.     return(1);
  572.     }
  573.     if ((output_file = fopen(output_file_name, "w+")) == NULL)
  574.     {
  575.     perror(output_file_name);
  576.     return(1);
  577.     }
  578.     sys$asctim(&retlen, &time_desc, 0, 0);
  579.     result_time[retlen] = 0;    
  580.     fprintf(output_file,"Diskmon Disk Usage %s at %s\n",
  581.                             VERSION,
  582.                             result_time);
  583.     fprintf(output_file,"\n");
  584.     GetHeaderRec(usage_file,&headerrec);
  585.     PutHeader(output_file,headerrec);
  586.     sprintf(subject_string,"Diskmon Disk Usage %s on %.12s at %s",
  587.                             VERSION,
  588.                             headerrec.usg$t_volname,
  589.                             result_time);
  590.     while(GetFileRec(usage_file,&filerec))
  591.     {
  592.     if (display_files)
  593.     {
  594.         /* Display Files                            */
  595.         if (first_title)
  596.         {
  597.         first_title = FALSE;
  598.         fprintf(output_file,"\n");
  599.         fprintf(output_file,"File List\n");
  600.         fprintf(output_file,"---------\n");
  601.         fprintf(output_file,"%-32s\t%-14s\t%-6s\t%-7s\t%-6s\n",
  602.                                 title1,
  603.                                 title2,
  604.                                 title3,
  605.                                 title4,
  606.                                 title5);
  607.         }
  608.         PutFile(output_file,filerec);
  609.     }
  610.     /* Checking for Lost files as then have a directory length of 2 eg  */
  611.     /* file spec is []file.type                        */
  612.     if (filerec.usg$w_dir_len == 2)
  613.     {
  614.         /* Set lost files to no directory files uic                */
  615.         filerec.usg$l_fileowner = NODIR_FILES_UIC;
  616.     }
  617.     add_to_total(place_in_list,
  618.              filerec.usg$l_fileowner,
  619.              filerec.usg$l_used,
  620.              filerec.usg$l_allocated); 
  621.     }
  622.     fclose(usage_file);
  623.     if (display_totals) PutTotals(output_file,place_in_list);
  624.     fclose(output_file);
  625.     if (send_mail)
  626.     {
  627.     if((m_status = mail_send_message(&MAILTO_STRING_DESC,
  628.                      &SUBJECT_STRING_DESC,
  629.                      &OUTPUT_FILE_DESC)) != SS$_NORMAL)
  630.     {
  631.         lib$signal(m_status);
  632.     }
  633.     }
  634.     return;
  635. }
  636.  
  637.  
  638. --
  639. +-----------------------------------------------------------------------+
  640. Martin Millson (Morgul)           | Easynet: vogon::millson
  641. International Systems Engineering | Internet: millson@vogon.enet.dec.com 
  642. Digital Equipment Corporation     | Phone: +44 734 203258
  643. "Out of the Storm rode the black nine"
  644. Disclaimer:
  645. "This is me talking not Digital Equipment Corp."
  646. +-----------------------------------------------------------------------+
  647.