Changeset View
Changeset View
Standalone View
Standalone View
usr.bin/tftp/main.c
Show First 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | |||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
/* Many bug fixes are from Jim Guyton <guyton@rand-unix> */ | /* Many bug fixes are from Jim Guyton <guyton@rand-unix> */ | ||||
/* | /* | ||||
* TFTP User Program -- Command Interface. | * TFTP User Program -- Command Interface. | ||||
*/ | */ | ||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/types.h> | |||||
#include <sys/socket.h> | |||||
#include <sys/sysctl.h> | |||||
#include <sys/file.h> | #include <sys/file.h> | ||||
#include <sys/socket.h> | |||||
#include <sys/stat.h> | #include <sys/stat.h> | ||||
#include <sys/sysctl.h> | |||||
#include <netinet/in.h> | #include <netinet/in.h> | ||||
#include <arpa/inet.h> | #include <arpa/inet.h> | ||||
#include <arpa/tftp.h> | #include <arpa/tftp.h> | ||||
#include <ctype.h> | #include <ctype.h> | ||||
#include <err.h> | #include <err.h> | ||||
#include <histedit.h> | #include <histedit.h> | ||||
#include <netdb.h> | #include <netdb.h> | ||||
#include <setjmp.h> | #include <setjmp.h> | ||||
#include <signal.h> | #include <signal.h> | ||||
#include <stdbool.h> | #include <stdbool.h> | ||||
#include <stddef.h> | |||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include <unistd.h> | #include <unistd.h> | ||||
#include "tftp-utils.h" | #include "tftp-utils.h" | ||||
#include "tftp-io.h" | #include "tftp-io.h" | ||||
#include "tftp-options.h" | #include "tftp-options.h" | ||||
▲ Show 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | |||||
static void urihandling(char *URI); | static void urihandling(char *URI); | ||||
static void getusage(char *); | static void getusage(char *); | ||||
static void makeargv(char *line); | static void makeargv(char *line); | ||||
static void putusage(char *); | static void putusage(char *); | ||||
static void settftpmode(const char *); | static void settftpmode(const char *); | ||||
static char *tail(char *); | static char *tail(char *); | ||||
static struct cmd *getcmd(char *); | static const struct cmd *getcmd(const char *); | ||||
#define HELPINDENT (sizeof("connect")) | #define HELPINDENT (sizeof("connect")) | ||||
struct cmd { | struct cmd { | ||||
const char *name; | const char *name; | ||||
void (*handler)(int, char **); | void (*handler)(int, char **); | ||||
const char *help; | const char *help; | ||||
}; | }; | ||||
▲ Show 20 Lines • Show All 600 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
/* | /* | ||||
* Command parser. | * Command parser. | ||||
*/ | */ | ||||
static void | static void | ||||
command(bool interactive, EditLine *el, History *hist, HistEvent *hep) | command(bool interactive, EditLine *el, History *hist, HistEvent *hep) | ||||
{ | { | ||||
struct cmd *c; | const struct cmd *c; | ||||
const char *bp; | const char *bp; | ||||
char *cp; | char *cp; | ||||
int len, num; | int len, num; | ||||
char line[MAXLINE]; | char line[MAXLINE]; | ||||
for (;;) { | for (;;) { | ||||
if (interactive) { | if (interactive) { | ||||
if ((bp = el_gets(el, &num)) == NULL || num == 0) | if ((bp = el_gets(el, &num)) == NULL || num == 0) | ||||
Show All 27 Lines | for (;;) { | ||||
if (c == NULL) { | if (c == NULL) { | ||||
printf("?Invalid command\n"); | printf("?Invalid command\n"); | ||||
continue; | continue; | ||||
} | } | ||||
(*c->handler)(margc, margv); | (*c->handler)(margc, margv); | ||||
} | } | ||||
} | } | ||||
static struct cmd * | static const struct cmd * | ||||
getcmd(char *name) | getcmd(const char *name) | ||||
{ | { | ||||
const char *p, *q; | const char *p, *q; | ||||
struct cmd *c, *found; | const struct cmd *c, *found; | ||||
int nmatches, longest; | ptrdiff_t longest; | ||||
int nmatches; | |||||
longest = 0; | longest = 0; | ||||
nmatches = 0; | nmatches = 0; | ||||
found = 0; | found = 0; | ||||
for (c = cmdtab; (p = c->name) != NULL; c++) { | for (c = cmdtab; (p = c->name) != NULL; c++) { | ||||
for (q = name; *q == *p++; q++) | for (q = name; *q == *p++; q++) | ||||
if (*q == 0) /* exact match? */ | if (*q == '\0') /* exact match? */ | ||||
return (c); | return (c); | ||||
if (!*q) { /* the name was a prefix */ | if (*q == '\0') { /* the name was a prefix */ | ||||
if (q - name > longest) { | if (q - name > longest) { | ||||
longest = q - name; | longest = q - name; | ||||
nmatches = 1; | nmatches = 1; | ||||
found = c; | found = c; | ||||
} else if (q - name == longest) | } else if (q - name == longest) | ||||
nmatches++; | nmatches++; | ||||
} | } | ||||
} | } | ||||
Show All 38 Lines | |||||
} | } | ||||
/* | /* | ||||
* Help command. | * Help command. | ||||
*/ | */ | ||||
static void | static void | ||||
help(int argc, char *argv[]) | help(int argc, char *argv[]) | ||||
{ | { | ||||
struct cmd *c; | const struct cmd *c; | ||||
if (argc == 1) { | if (argc == 1) { | ||||
printf("Commands may be abbreviated. Commands are:\n\n"); | printf("Commands may be abbreviated. Commands are:\n\n"); | ||||
for (c = cmdtab; c->name; c++) | for (c = cmdtab; c->name; c++) | ||||
printf("%-*s\t%s\n", (int)HELPINDENT, c->name, c->help); | printf("%-*s\t%s\n", (int)HELPINDENT, c->name, c->help); | ||||
printf("\n[-] : You shouldn't use these ones anymore.\n"); | printf("\n[-] : You shouldn't use these ones anymore.\n"); | ||||
printf("[*] : RFC2347 options support required.\n"); | printf("[*] : RFC2347 options support required.\n"); | ||||
▲ Show 20 Lines • Show All 230 Lines • Show Last 20 Lines |