mirror of
https://github.com/libssh2/libssh2.git
synced 2025-04-19 02:24:04 +03:00
565 lines
14 KiB
C
565 lines
14 KiB
C
/* Copyright (C) The libssh2 project and its contributors.
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <ctype.h>
|
|
#include <errno.h>
|
|
|
|
#include <starlet.h>
|
|
#include <lib$routines.h>
|
|
#include <ssdef.h>
|
|
#include <descrip.h>
|
|
#include <rms.h>
|
|
|
|
typedef struct manl {
|
|
struct manl *next;
|
|
char *filename;
|
|
} man, *manPtr;
|
|
|
|
typedef struct pf_fabnam {
|
|
struct FAB dfab;
|
|
struct RAB drab;
|
|
struct namldef dnam;
|
|
char expanded_filename[NAM$C_MAXRSS + 1];
|
|
} pfn, *pfnPtr;
|
|
|
|
/*----------------------------------------------------------*/
|
|
|
|
fpcopy(char *output, char *input, int len)
|
|
{
|
|
char *is, *os;
|
|
int i;
|
|
|
|
if(len) {
|
|
for(is = input, os = output, i = 0; i < len; ++i, ++is, ++os) {
|
|
*os = *is;
|
|
}
|
|
*os = 0;
|
|
}
|
|
else {
|
|
output[0] = 0;
|
|
}
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------*/
|
|
/* give part of ilename in partname. See code for proper
|
|
value of i ( 0 = node, 1 = dev, 2 = dir, 3 = name etc.
|
|
*/
|
|
|
|
int fnamepart(char *inputfile, char *part, int whatpart)
|
|
{
|
|
pfnPtr pf;
|
|
int status;
|
|
char ipart[6][256], *i, *p;
|
|
|
|
pf = calloc(1, sizeof(pfn));
|
|
|
|
pf->dfab = cc$rms_fab;
|
|
pf->drab = cc$rms_rab;
|
|
pf->dnam = cc$rms_naml;
|
|
|
|
pf->dfab.fab$l_naml = &pf->dnam;
|
|
|
|
pf->dfab.fab$l_fna = (char *) -1;
|
|
pf->dfab.fab$l_dna = (char *) -1;
|
|
pf->dfab.fab$b_fns = 0;
|
|
pf->dfab.fab$w_ifi = 0;
|
|
|
|
pf->dnam.naml$l_long_defname = NULL; /* inputfile; */
|
|
pf->dnam.naml$l_long_defname_size = 0; /* strlen(inputfile); */
|
|
|
|
pf->dnam.naml$l_long_filename = inputfile;
|
|
pf->dnam.naml$l_long_filename_size = strlen(inputfile);
|
|
|
|
pf->dnam.naml$l_long_expand = pf->expanded_filename;
|
|
pf->dnam.naml$l_long_expand_alloc = NAM$C_MAXRSS;
|
|
|
|
pf->dnam.naml$b_nop |= NAML$M_SYNCHK | NAML$M_PWD;
|
|
|
|
status = sys$parse(&pf->dfab, 0, 0);
|
|
if(!(status&1)) {
|
|
free(pf);
|
|
return status;
|
|
}
|
|
|
|
fpcopy(ipart[0], pf->dnam.naml$l_long_node,
|
|
pf->dnam.naml$l_long_node_size);
|
|
fpcopy(ipart[1], pf->dnam.naml$l_long_dev,
|
|
pf->dnam.naml$l_long_dev_size);
|
|
fpcopy(ipart[2], pf->dnam.naml$l_long_dir,
|
|
pf->dnam.naml$l_long_dir_size);
|
|
fpcopy(ipart[3], pf->dnam.naml$l_long_name,
|
|
pf->dnam.naml$l_long_name_size);
|
|
fpcopy(ipart[4], pf->dnam.naml$l_long_type,
|
|
pf->dnam.naml$l_long_type_size);
|
|
fpcopy(ipart[5], pf->dnam.naml$l_long_ver,
|
|
pf->dnam.naml$l_long_ver_size);
|
|
|
|
for(i = ipart[whatpart], p = part; *i; ++i, ++p) {
|
|
if(p == part) {
|
|
*p = toupper(*i);
|
|
}
|
|
else {
|
|
*p = tolower(*i);
|
|
}
|
|
}
|
|
*p = 0;
|
|
|
|
free(pf);
|
|
return 1;
|
|
}
|
|
/*----------------------------------------------------------*/
|
|
|
|
int find_file(char *filename, char *gevonden, int *findex)
|
|
{
|
|
int status;
|
|
struct dsc$descriptor gevondend;
|
|
struct dsc$descriptor filespec;
|
|
char gevonden_file[NAM$C_MAXRSS + 1];
|
|
|
|
filespec.dsc$w_length = strlen(filename);
|
|
filespec.dsc$b_dtype = DSC$K_DTYPE_T;
|
|
filespec.dsc$b_class = DSC$K_CLASS_S;
|
|
filespec.dsc$a_pointer = filename;
|
|
|
|
gevondend.dsc$w_length = NAM$C_MAXRSS;
|
|
gevondend.dsc$b_dtype = DSC$K_DTYPE_T;
|
|
gevondend.dsc$b_class = DSC$K_CLASS_S;
|
|
gevondend.dsc$a_pointer = gevonden_file;
|
|
|
|
status = lib$find_file(&filespec, &gevondend, findex, 0, 0, 0, 0);
|
|
|
|
if((status & 1) == 1) {
|
|
/* !checksrc! disable BANNEDFUNC 1 */ /* FIXME */
|
|
strcpy(gevonden, strtok(gevonden_file, " "));
|
|
}
|
|
else {
|
|
gevonden[0] = 0;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
|
|
/*--------------------------------------------*/
|
|
|
|
manPtr addman(manPtr *manroot, char *filename)
|
|
{
|
|
manPtr m, f;
|
|
|
|
m = calloc(1, sizeof(man));
|
|
if(!m)
|
|
return NULL;
|
|
|
|
m->filename = strdup(filename);
|
|
|
|
if(!*manroot) {
|
|
*manroot = m;
|
|
}
|
|
else {
|
|
for(f = *manroot; f->next; f = f->next)
|
|
;
|
|
f->next = m;
|
|
}
|
|
return m;
|
|
}
|
|
|
|
/*--------------------------------------------*/
|
|
void freeman(manPtr *manroot)
|
|
{
|
|
manPtr m, n;
|
|
|
|
for(m = *manroot; m; m = n) {
|
|
free(m->filename);
|
|
n = m->next;
|
|
free(m);
|
|
}
|
|
*manroot = NULL;
|
|
}
|
|
|
|
/*--------------------------------------------*/
|
|
|
|
int listofmans(char *filespec, manPtr *manroot)
|
|
{
|
|
manPtr r;
|
|
int status;
|
|
int ffindex = 0;
|
|
char gevonden[NAM$C_MAXRSS + 1];
|
|
|
|
for(;;) {
|
|
status = find_file(filespec, gevonden, &ffindex);
|
|
|
|
if((status&1)) {
|
|
r = addman(manroot, gevonden);
|
|
if(!r)
|
|
return 2;
|
|
}
|
|
else {
|
|
if(!(status&1))
|
|
break;
|
|
}
|
|
}
|
|
|
|
lib$find_file_end(&ffindex);
|
|
if(status == RMS$_NMF)
|
|
status = 1;
|
|
|
|
return status;
|
|
}
|
|
|
|
/*--------------------------------------------*/
|
|
|
|
int convertman(char *filespec, FILE *hlp, int base_level, int add_parentheses)
|
|
{
|
|
FILE *man;
|
|
char *in, *uit;
|
|
char *m, *h;
|
|
size_t len, thislen, maxlen = 50000;
|
|
int bol, mode, return_status = 1;
|
|
char subjectname[NAM$C_MAXRSS + 1];
|
|
|
|
in = calloc(1, maxlen + 1);
|
|
uit = calloc(1, maxlen + 1);
|
|
|
|
if(!in || !uit)
|
|
return 2;
|
|
|
|
man = fopen(filespec, "r");
|
|
if(!man)
|
|
return vaxc$errno;
|
|
|
|
for(len = 0; !feof(man) && len < maxlen; len += thislen) {
|
|
thislen = fread(in + len, 1, maxlen - len, man);
|
|
}
|
|
|
|
fclose(man);
|
|
|
|
m = in;
|
|
h = uit;
|
|
|
|
*(m + len) = 0;
|
|
|
|
for(mode = 0, bol = 1; *m; ++m) {
|
|
|
|
switch(mode) {
|
|
case 0:
|
|
switch(*m) {
|
|
case '.':
|
|
if(bol) {
|
|
mode = 1;
|
|
}
|
|
else {
|
|
*h = *m;
|
|
++h;
|
|
}
|
|
break;
|
|
case '\\':
|
|
if(bol) {
|
|
*h = ' '; ++h;
|
|
*h = ' '; ++h;
|
|
}
|
|
mode = 2;
|
|
break;
|
|
default:
|
|
if(bol) {
|
|
*h = ' '; ++h;
|
|
*h = ' '; ++h;
|
|
}
|
|
*h = *m;
|
|
++h;
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case 1: /* after . at bol */
|
|
switch(*m) {
|
|
case '\\':
|
|
while(*m != '\n' && *m != '\r' && *m)
|
|
++m;
|
|
mode = 0;
|
|
break;
|
|
case 'B':
|
|
++m;
|
|
*h = ' '; ++h;
|
|
mode = 0;
|
|
break;
|
|
case 'I':
|
|
/* remove preceding eol */
|
|
if(*(m + 1) != 'P') {
|
|
--h;
|
|
while((*h == '\n' || *h == '\r') && h > uit)
|
|
--h;
|
|
++h;
|
|
}
|
|
|
|
/* skip .Ix */
|
|
for(; *m != ' ' && *m != '\n' && *m != '\r'; ++m)
|
|
;
|
|
|
|
/* copy line up to EOL */
|
|
|
|
for(; *m != '\n' && *m != '\r' && *m; ++m, ++h)
|
|
*h = *m;
|
|
|
|
/* if line ends in ., this is an EOL */
|
|
|
|
if(*(h-1) == '.') {
|
|
--h;
|
|
--m;
|
|
}
|
|
else {
|
|
/* if line does not end in ., skip EOL in source */
|
|
|
|
if(*(m + 1) == '\n' || *(m + 1) == '\r')
|
|
++m;
|
|
}
|
|
mode = 0;
|
|
break;
|
|
case 'S':
|
|
if(*(m + 1) == 'H') {
|
|
*h = '\n';++h;
|
|
if(strncmp(m + 3, "NAME", 4) == 0 ||
|
|
strncmp(m + 3, "SYNOPSIS", 8) == 0 ||
|
|
strncmp(m + 3, "DESCRIPTION", 11) == 0) {
|
|
while(*m != '\n' && *m != '\r')
|
|
++m;
|
|
mode = 0;
|
|
}
|
|
else {
|
|
++m;
|
|
|
|
/* write help level, and flag it */
|
|
|
|
*h = '0' + base_level + 1; ++h;
|
|
return_status |= 2;
|
|
|
|
*h = ' '; ++h;
|
|
|
|
/* skip H (or whatever after S) and blank */
|
|
++m; ++m;
|
|
|
|
for(; *m != '\n' && *m != '\r' && *m; ++m, ++h) {
|
|
|
|
/* write help label in lowercase, skip quotes */
|
|
/* fill blanks with underscores */
|
|
|
|
if(*m != '\"') {
|
|
*h = tolower(*m);
|
|
if(*h == ' ')
|
|
*h = '_';
|
|
}
|
|
else {
|
|
--h;
|
|
}
|
|
}
|
|
|
|
/* Add a linefeed or two */
|
|
|
|
*h = *m; ++h;
|
|
*h = *m; ++h;
|
|
|
|
mode = 0;
|
|
}
|
|
}
|
|
break;
|
|
case 'T':
|
|
if(*(m + 1) == 'H') {
|
|
*h = '0' + base_level; ++h;
|
|
return_status |= 2;
|
|
*h = ' '; ++h;
|
|
for(m = m + 3; *m != ' ' && *m; ++m, ++h) {
|
|
*h = *m;
|
|
}
|
|
if(add_parentheses) {
|
|
*h = '('; ++h;
|
|
*h = ')'; ++h;
|
|
}
|
|
while(*m != '\n' && *m != '\r' && *m)
|
|
++m;
|
|
mode = 0;
|
|
}
|
|
break;
|
|
default:
|
|
++m;
|
|
mode = 0;
|
|
break;
|
|
}
|
|
break;
|
|
case 2: /* after \ skip two characters or print the backslash */
|
|
switch(*m) {
|
|
case '\\':
|
|
*h = *m;
|
|
++h;
|
|
mode = 0;
|
|
break;
|
|
default:
|
|
++m;
|
|
mode = 0;
|
|
break;
|
|
}
|
|
break;
|
|
} /* end switch mode */
|
|
|
|
bol = 0;
|
|
if(*m == '\n' || *m == '\r')
|
|
bol = 1;
|
|
|
|
} /* end for mode */
|
|
|
|
*h = 0;
|
|
|
|
|
|
if(return_status & 2) {
|
|
fprintf(hlp, "%s\n\n", uit);
|
|
}
|
|
else {
|
|
fnamepart(filespec, subjectname, 3);
|
|
if(*subjectname) {
|
|
fprintf(hlp, "%d %s\n\n%s\n\n", base_level, subjectname, uit);
|
|
}
|
|
else {
|
|
/* No filename (as is the case with a logical),
|
|
use first word as subject name */
|
|
char *n, *s;
|
|
|
|
for(n = in; isspace(*n); ++n)
|
|
;
|
|
for(s = subjectname; !(isspace(*n)); ++n, ++s)
|
|
*s = *n;
|
|
*s = 0;
|
|
|
|
fprintf(hlp, "%d %s\n\n%s\n\n", base_level, subjectname, uit);
|
|
}
|
|
}
|
|
|
|
/*
|
|
printf("read %d from %s, written %d to helpfile, return_status = %d\n",
|
|
len, filespec, strlen(uit), return_status);
|
|
*/
|
|
|
|
free(m);
|
|
free(h);
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*--------------------------------------------*/
|
|
|
|
int convertmans(char *filespec, char *hlpfilename, int base_level, int append,
|
|
int add_parentheses)
|
|
{
|
|
int status = 1;
|
|
manPtr manroot = NULL, m;
|
|
FILE *hlp;
|
|
|
|
if(append) {
|
|
hlp = fopen(hlpfilename, "a+");
|
|
}
|
|
else {
|
|
hlp = fopen(hlpfilename, "w");
|
|
}
|
|
|
|
if(!hlp)
|
|
return vaxc$errno;
|
|
|
|
status = listofmans(filespec, &manroot);
|
|
if(!(status&1))
|
|
return status;
|
|
|
|
for(m = manroot; m; m = m->next) {
|
|
status = convertman(m->filename, hlp, base_level, add_parentheses);
|
|
if(!(status&1)) {
|
|
fprintf(stderr, "Convertman of %s went wrong\n", m->filename);
|
|
break;
|
|
}
|
|
}
|
|
freeman(&manroot);
|
|
return status;
|
|
}
|
|
|
|
/*--------------------------------------------*/
|
|
void print_help(void)
|
|
{
|
|
fprintf(stderr,
|
|
"Usage: [-a] [-b x] convertman <manfilespec> <helptextfile>\n"
|
|
" -a append <manfilespec> to <helptextfile>\n"
|
|
" -b <baselevel> if no headers found create one "
|
|
"with level <baselevel>\n"
|
|
" and the filename as title.\n"
|
|
" -p add parentheses() to baselevel help items.\n");
|
|
}
|
|
/*--------------------------------------------*/
|
|
|
|
main(int argc, char **argv)
|
|
{
|
|
int status;
|
|
int i, j;
|
|
int append, base_level, basechange, add_parentheses;
|
|
char *manfile = NULL;
|
|
char *helpfile = NULL;
|
|
|
|
if(argc < 3) {
|
|
print_help();
|
|
return 1;
|
|
}
|
|
|
|
append = 0;
|
|
base_level = 1;
|
|
basechange = 0;
|
|
add_parentheses = 0;
|
|
|
|
for(i = 1; i < argc; ++i) {
|
|
if(argv[i][0] == '-') {
|
|
for(j = 1; argv[i][j]; ++j) {
|
|
switch(argv[i][j]) {
|
|
case 'a':
|
|
append = 1;
|
|
break;
|
|
case 'b':
|
|
if((i + 1) < argc) {
|
|
base_level = atoi(argv[i + 1]);
|
|
basechange = 1;
|
|
}
|
|
break;
|
|
case 'p':
|
|
add_parentheses = 1;
|
|
break;
|
|
}
|
|
}
|
|
if(basechange) {
|
|
basechange = 0;
|
|
i = i + 1;
|
|
}
|
|
}
|
|
else {
|
|
if(!manfile) {
|
|
manfile = strdup(argv[i]);
|
|
}
|
|
else if(!helpfile) {
|
|
helpfile = strdup(argv[i]);
|
|
}
|
|
else {
|
|
fprintf(stderr, "Unrecognized parameter : %s\n", argv[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
fprintf(stderr,"manfile: %s, helpfile: %s, append: %d, base_level : %d\n",
|
|
manfile, helpfile, append, base_level);
|
|
*/
|
|
|
|
status = convertmans(manfile, helpfile, base_level, append,
|
|
add_parentheses);
|
|
|
|
free(manfile);
|
|
free(helpfile);
|
|
|
|
return status;
|
|
}
|