From 149c29f80cb85389e9b565cb598a8085c2474828 Mon Sep 17 00:00:00 2001 From: Slava Zanko Date: Fri, 6 Jul 2012 14:20:18 +0300 Subject: [PATCH] Indent files. Signed-off-by: Slava Zanko --- lib/event/internal.h | 3 +- lib/global.h | 2 +- lib/hook.c | 2 +- lib/mcconfig/paths.c | 2 +- lib/strutil/strutilutf8.c | 2 +- lib/tty/color.h | 2 +- lib/util.c | 4 +- lib/vfs/vfs.c | 4 +- lib/vfs/xdirentry.h | 2 +- lib/widget/history.h | 4 +- lib/widget/listbox.c | 10 +- src/cons.handler.c | 7 +- src/editor/editcmd_dialogs.h | 2 +- src/execute.c | 2 +- src/filemanager/command.c | 5 +- src/filemanager/ext.c | 6 +- src/filemanager/file.c | 6 +- src/filemanager/filegui.c | 64 +- src/filemanager/layout.c | 2 +- src/filemanager/layout.h | 2 +- src/filemanager/mountlist.c | 2 + src/filemanager/mountlist.h | 6 +- src/filemanager/panel.c | 2 +- src/filemanager/usermenu.h | 2 +- src/learn.c | 3 +- src/setup.h | 4 +- src/subshell.c | 2 +- src/vfs/cpio/cpio.c | 2 +- src/vfs/cpio/cpio.h | 2 +- src/vfs/extfs/extfs.c | 2 +- src/vfs/fish/fish.h | 2 +- src/vfs/plugins_init.h | 2 +- src/vfs/sfs/sfs.c | 3 +- src/vfs/smbfs/helpers/include/byteorder.h | 108 +- src/vfs/smbfs/helpers/include/charset.h | 4 +- src/vfs/smbfs/helpers/include/client.h | 253 +- src/vfs/smbfs/helpers/include/includes.h | 62 +- src/vfs/smbfs/helpers/include/kanji.h | 20 +- src/vfs/smbfs/helpers/include/local.h | 8 +- src/vfs/smbfs/helpers/include/nameserv.h | 447 +-- src/vfs/smbfs/helpers/include/proto.h | 1226 +++--- src/vfs/smbfs/helpers/include/smb.h | 1036 ++--- src/vfs/smbfs/helpers/include/trans2.h | 5 +- src/vfs/smbfs/helpers/lib/charcnv.c | 514 +-- src/vfs/smbfs/helpers/lib/charset.c | 811 ++-- src/vfs/smbfs/helpers/lib/debug.c | 306 +- src/vfs/smbfs/helpers/lib/interface.c | 501 +-- src/vfs/smbfs/helpers/lib/kanji.c | 2741 +++++++------ src/vfs/smbfs/helpers/lib/md4.c | 392 +- src/vfs/smbfs/helpers/lib/netmask.c | 376 +- src/vfs/smbfs/helpers/lib/slprintf.c | 52 +- src/vfs/smbfs/helpers/lib/system.c | 279 +- src/vfs/smbfs/helpers/lib/time.c | 592 +-- src/vfs/smbfs/helpers/lib/username.c | 874 +++-- src/vfs/smbfs/helpers/lib/util_file.c | 420 +- src/vfs/smbfs/helpers/lib/util_sock.c | 1871 ++++----- src/vfs/smbfs/helpers/lib/util_str.c | 2293 +++++------ src/vfs/smbfs/helpers/libsmb/clientgen.c | 5946 +++++++++++++++-------------- src/vfs/smbfs/helpers/libsmb/namequery.c | 1164 +++--- src/vfs/smbfs/helpers/libsmb/nmblib.c | 2008 +++++----- src/vfs/smbfs/helpers/libsmb/nterr.c | 1115 +++--- src/vfs/smbfs/helpers/libsmb/pwd_cache.c | 269 +- src/vfs/smbfs/helpers/libsmb/smbdes.c | 836 ++-- src/vfs/smbfs/helpers/libsmb/smbencrypt.c | 207 +- src/vfs/smbfs/helpers/libsmb/smberr.c | 389 +- src/vfs/smbfs/helpers/param/loadparm.c | 5048 ++++++++++++------------ src/vfs/smbfs/helpers/param/params.c | 610 +-- src/vfs/tar/tar.h | 2 +- src/vfs/undelfs/undelfs.h | 2 +- src/viewer/datasource.c | 2 +- src/viewer/display.c | 2 +- 71 files changed, 17119 insertions(+), 15839 deletions(-) rewrite src/vfs/smbfs/helpers/include/client.h (71%) rewrite src/vfs/smbfs/helpers/include/proto.h (92%) rewrite src/vfs/smbfs/helpers/lib/charcnv.c (77%) rewrite src/vfs/smbfs/helpers/lib/charset.c (77%) rewrite src/vfs/smbfs/helpers/lib/kanji.c (60%) rewrite src/vfs/smbfs/helpers/lib/md4.c (66%) rewrite src/vfs/smbfs/helpers/lib/username.c (60%) rewrite src/vfs/smbfs/helpers/lib/util_sock.c (67%) rewrite src/vfs/smbfs/helpers/lib/util_str.c (64%) rewrite src/vfs/smbfs/helpers/libsmb/clientgen.c (80%) rewrite src/vfs/smbfs/helpers/libsmb/namequery.c (76%) rewrite src/vfs/smbfs/helpers/libsmb/nmblib.c (71%) rewrite src/vfs/smbfs/helpers/libsmb/nterr.c (96%) rewrite src/vfs/smbfs/helpers/libsmb/smbdes.c (81%) rewrite src/vfs/smbfs/helpers/libsmb/smberr.c (80%) rewrite src/vfs/smbfs/helpers/param/loadparm.c (79%) diff --git a/lib/event/internal.h b/lib/event/internal.h index b6d45b498..f82ac3ae0 100644 --- a/lib/event/internal.h +++ b/lib/event/internal.h @@ -25,7 +25,8 @@ GTree *mc_event_get_event_group_by_name (const gchar * event_group_name, gboolea GPtrArray *mc_event_get_event_by_name (GTree * event_group, const gchar * event_name, gboolean create_new, GError ** mcerror); mc_event_callback_t *mc_event_is_callback_in_array (GPtrArray * callbacks, - mc_event_callback_func_t event_callback, gpointer event_init_data); + mc_event_callback_func_t event_callback, + gpointer event_init_data); /*** inline functions ****************************************************************************/ #endif /* MC_EVENT_INTERNAL_H */ diff --git a/lib/global.h b/lib/global.h index 7df9c4a26..d8e2bef95 100644 --- a/lib/global.h +++ b/lib/global.h @@ -208,7 +208,7 @@ typedef struct /* Ugly hack in order to distinguish between left and right panel in menubar */ /* Set if the command is being run from the "Right" menu */ - gboolean is_right; /* If the selected menu was the right */ + gboolean is_right; /* If the selected menu was the right */ } widget; struct diff --git a/lib/hook.c b/lib/hook.c index 15933602a..8e61ad033 100644 --- a/lib/hook.c +++ b/lib/hook.c @@ -2,7 +2,7 @@ Hooks. Slavaz: Warning! this file is deprecated and should be replaced - by mcevents functional. + by mcevents functional. Copyright (C) 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2009, 2010, 2011 diff --git a/lib/mcconfig/paths.c b/lib/mcconfig/paths.c index a8b5d37ba..841fc1953 100644 --- a/lib/mcconfig/paths.c +++ b/lib/mcconfig/paths.c @@ -540,7 +540,7 @@ mc_config_get_full_vpath (const char *config_name) str_path = mc_config_get_full_path (config_name); - ret_vpath = vfs_path_from_str(str_path); + ret_vpath = vfs_path_from_str (str_path); g_free (str_path); return ret_vpath; } diff --git a/lib/strutil/strutilutf8.c b/lib/strutil/strutilutf8.c index e98f9a4e9..4d9f9733d 100644 --- a/lib/strutil/strutilutf8.c +++ b/lib/strutil/strutilutf8.c @@ -675,7 +675,7 @@ str_utf8_term_trim (const char *text, int width) if (width < 1) { - result [0] = '\0'; + result[0] = '\0'; return result; } diff --git a/lib/tty/color.h b/lib/tty/color.h index ad778eb3d..00ce6714d 100644 --- a/lib/tty/color.h +++ b/lib/tty/color.h @@ -47,7 +47,7 @@ void tty_set_normal_attrs (void); void tty_color_set_defaults (const char *, const char *, const char *); -extern gboolean tty_use_256colors(void); +extern gboolean tty_use_256colors (void); /*** inline functions ****************************************************************************/ #endif /* MC_COLOR_H */ diff --git a/lib/util.c b/lib/util.c index 327f52a8a..155eb1d7b 100644 --- a/lib/util.c +++ b/lib/util.c @@ -110,7 +110,7 @@ is_8bit_printable (unsigned char c) /* --------------------------------------------------------------------------------------------- */ static char * -resolve_symlinks (const vfs_path_t *vpath) +resolve_symlinks (const vfs_path_t * vpath) { char *p, *p2; char *buf, *buf2, *q, *r, c; @@ -164,7 +164,7 @@ resolve_symlinks (const vfs_path_t *vpath) canonicalize_pathname (buf); r = strchr (buf, 0); if (!*r || *(r - 1) != PATH_SEP) - /* FIXME: this condition is always true because r points to the EOL */ + /* FIXME: this condition is always true because r points to the EOL */ { *r++ = PATH_SEP; *r = 0; diff --git a/lib/vfs/vfs.c b/lib/vfs/vfs.c index e173bbfeb..2f480e378 100644 --- a/lib/vfs/vfs.c +++ b/lib/vfs/vfs.c @@ -174,7 +174,7 @@ _vfs_translate_path (const char *path, int size, GIConv defcnv, GString * buffer (void) defcnv; g_string_assign (buffer, path); -#endif /* HAVE_CHARSET */ +#endif /* HAVE_CHARSET */ return state; } @@ -614,7 +614,7 @@ vfs_change_encoding (vfs_path_t * vpath, const char *encoding) return vpath; } -#endif /* HAVE_CHARSET */ +#endif /* HAVE_CHARSET */ /* --------------------------------------------------------------------------------------------- */ diff --git a/lib/vfs/xdirentry.h b/lib/vfs/xdirentry.h index 7d44d04d5..7b06deab9 100644 --- a/lib/vfs/xdirentry.h +++ b/lib/vfs/xdirentry.h @@ -176,7 +176,7 @@ struct vfs_s_inode *vfs_s_find_root (struct vfs_class *me, struct vfs_s_entry *e /* outside interface */ void vfs_s_init_class (struct vfs_class *vclass, struct vfs_s_subclass *sub); const char *vfs_s_get_path (const vfs_path_t * vpath, struct vfs_s_super **archive, int flags); -struct vfs_s_super *vfs_get_super_by_vpath(const vfs_path_t * vpath); +struct vfs_s_super *vfs_get_super_by_vpath (const vfs_path_t * vpath); void vfs_s_invalidate (struct vfs_class *me, struct vfs_s_super *super); char *vfs_s_fullpath (struct vfs_class *me, struct vfs_s_inode *ino); diff --git a/lib/widget/history.h b/lib/widget/history.h index f1b3f4cac..17a0a9a10 100644 --- a/lib/widget/history.h +++ b/lib/widget/history.h @@ -24,9 +24,9 @@ extern int num_history_items_recorded; /* read history to the mc_config, but don't save config to file */ GList *history_get (const char *input_name); /* load history form the mc_config */ -GList *history_load (struct mc_config_t * cfg, const char *name); +GList *history_load (struct mc_config_t *cfg, const char *name); /* save history to the mc_config, but don't save config to file */ -void history_save (struct mc_config_t * cfg, const char *name, GList * h); +void history_save (struct mc_config_t *cfg, const char *name, GList * h); /* for repositioning of history dialog we should pass widget to this * function, as position of history dialog depends on widget's position */ char *history_show (GList ** history, Widget * widget); diff --git a/lib/widget/listbox.c b/lib/widget/listbox.c index a7bfb2552..df6504637 100644 --- a/lib/widget/listbox.c +++ b/lib/widget/listbox.c @@ -123,9 +123,13 @@ listbox_draw (WListbox * l, gboolean focused) const Dlg_head *h = l->widget.owner; const gboolean disabled = (((Widget *) l)->options & W_DISABLED) != 0; const int normalc = disabled ? DISABLED_COLOR : h->color[DLG_COLOR_NORMAL]; - int selc = - disabled ? DISABLED_COLOR : focused ? h-> - color[DLG_COLOR_HOT_FOCUS] : h->color[DLG_COLOR_FOCUS]; + /* *INDENT-OFF* */ + int selc = disabled + ? DISABLED_COLOR + : focused + ? h->color[DLG_COLOR_HOT_FOCUS] + : h->color[DLG_COLOR_FOCUS]; + /* *INDENT-ON* */ GList *le; int pos; diff --git a/src/cons.handler.c b/src/cons.handler.c index 31b24324a..3dd6e03ea 100644 --- a/src/cons.handler.c +++ b/src/cons.handler.c @@ -380,9 +380,10 @@ console_save (void) for (i = 0; i < screen_shot.xsize * screen_shot.ysize; i++) { - screen_shot.buf[i] = - (screen_shot.buf[i] & 0xff00) | (unsigned char) revmap. - scrmap[screen_shot.buf[i] & 0xff]; + /* *INDENT-OFF* */ + screen_shot.buf[i] = (screen_shot.buf[i] & 0xff00) + | (unsigned char) revmap.scrmap[screen_shot.buf[i] & 0xff]; + /* *INDENT-ON* */ } } diff --git a/src/editor/editcmd_dialogs.h b/src/editor/editcmd_dialogs.h index 7b5b43728..5a39c157f 100644 --- a/src/editor/editcmd_dialogs.h +++ b/src/editor/editcmd_dialogs.h @@ -27,7 +27,7 @@ struct selection void editcmd_dialog_replace_show (WEdit *, const char *, const char *, char **, char **); -gboolean editcmd_dialog_search_show (WEdit *edit); +gboolean editcmd_dialog_search_show (WEdit * edit); int editcmd_dialog_raw_key_query (const char *, const char *, int); diff --git a/src/execute.c b/src/execute.c index 96b120f9e..66af51e55 100644 --- a/src/execute.c +++ b/src/execute.c @@ -340,7 +340,7 @@ toggle_panels (void) #ifdef HAVE_SUBSHELL_SUPPORT if (mc_global.tty.use_subshell) { - new_dir_p = vfs_current_is_local () ? &new_dir_vpath : NULL; + new_dir_p = vfs_current_is_local ()? &new_dir_vpath : NULL; invoke_subshell (NULL, VISIBLY, new_dir_p); } else diff --git a/src/filemanager/command.c b/src/filemanager/command.c index fa5de13ad..dc7385290 100644 --- a/src/filemanager/command.c +++ b/src/filemanager/command.c @@ -83,7 +83,8 @@ WInput *cmdline; static char * examine_cd (const char *_path) { - typedef enum { copy_sym, subst_var } state_t; + typedef enum + { copy_sym, subst_var } state_t; state_t state = copy_sym; char *q; @@ -424,7 +425,7 @@ do_cd_command (char *orig_cmd) path = examine_cd (&cmd[operand_pos]); if (*path == '\0') - q_vpath = vfs_path_from_str (mc_config_get_home_dir()); + q_vpath = vfs_path_from_str (mc_config_get_home_dir ()); else q_vpath = vfs_path_from_str_flags (path, VPF_NO_CANON); diff --git a/src/filemanager/ext.c b/src/filemanager/ext.c index c33509609..179e616f5 100644 --- a/src/filemanager/ext.c +++ b/src/filemanager/ext.c @@ -516,7 +516,7 @@ regex_check_type (const vfs_path_t * filename_vpath, const char *ptr, int *have_ if (*have_type == 0) { vfs_path_t *localfile_vpath; - const char *realname; /* name used with "file" */ + const char *realname; /* name used with "file" */ #ifdef HAVE_CHARSET int got_encoding_data; @@ -767,14 +767,14 @@ regex_command (const vfs_path_t * filename_vpath, const char *action, int *move_ else if (!strncmp (p, "shell/", 6)) { p += 6; - if (*p == '.' && file_len >= (size_t)(q - p)) + if (*p == '.' && file_len >= (size_t) (q - p)) { if (!strncmp (p, filename + file_len - (q - p), q - p)) found = 1; } else { - if ((size_t)(q - p) == file_len && !strncmp (p, filename, q - p)) + if ((size_t) (q - p) == file_len && !strncmp (p, filename, q - p)) found = 1; } } diff --git a/src/filemanager/file.c b/src/filemanager/file.c index cdbf8d2a4..3854eae2c 100644 --- a/src/filemanager/file.c +++ b/src/filemanager/file.c @@ -238,7 +238,7 @@ free_link (void *data) /* --------------------------------------------------------------------------------------------- */ static void * -free_linklist (GSList *lp) +free_linklist (GSList * lp) { g_slist_foreach (lp, (GFunc) free_link, NULL); g_slist_free (lp); @@ -249,7 +249,7 @@ free_linklist (GSList *lp) /* --------------------------------------------------------------------------------------------- */ static gboolean -is_in_linklist (const GSList *lp, const vfs_path_t * vpath, const struct stat *sb) +is_in_linklist (const GSList * lp, const vfs_path_t * vpath, const struct stat *sb) { const struct vfs_class *class; ino_t ino = sb->st_ino; @@ -330,7 +330,7 @@ check_hardlinks (const vfs_path_t * src_vpath, const vfs_path_t * dst_vpath, str lnk->dev = dev; lnk->src_vpath = vfs_path_clone (src_vpath); lnk->dst_vpath = vfs_path_clone (dst_vpath); - linklist = g_slist_prepend (linklist, lnk); + linklist = g_slist_prepend (linklist, lnk); } return FALSE; diff --git a/src/filemanager/filegui.c b/src/filemanager/filegui.c index 198f7d780..1eab093c2 100644 --- a/src/filemanager/filegui.c +++ b/src/filemanager/filegui.c @@ -57,9 +57,9 @@ #if ((STAT_STATVFS || STAT_STATVFS64) \ && (HAVE_STRUCT_STATVFS_F_BASETYPE || HAVE_STRUCT_STATVFS_F_FSTYPENAME \ || (! HAVE_STRUCT_STATFS_F_FSTYPENAME))) -# define USE_STATVFS 1 +#define USE_STATVFS 1 #else -# define USE_STATVFS 0 +#define USE_STATVFS 0 #endif #include @@ -70,36 +70,36 @@ #include #if USE_STATVFS -# include +#include #elif HAVE_SYS_VFS_H -# include +#include #elif HAVE_SYS_MOUNT_H && HAVE_SYS_PARAM_H /* NOTE: freebsd5.0 needs sys/param.h and sys/mount.h for statfs. It does have statvfs.h, but shouldn't use it, since it doesn't HAVE_STRUCT_STATVFS_F_BASETYPE. So find a clean way to fix it. */ /* NetBSD 1.5.2 needs these, for the declaration of struct statfs. */ -# include -# include -# if HAVE_NFS_NFS_CLNT_H && HAVE_NFS_VFS_H +#include +#include +#if HAVE_NFS_NFS_CLNT_H && HAVE_NFS_VFS_H /* Ultrix 4.4 needs these for the declaration of struct statfs. */ -# include -# include -# include -# endif +#include +#include +#include +#endif #elif HAVE_OS_H /* BeOS */ -# include +#include #endif #if USE_STATVFS -# define STRUCT_STATVFS struct statvfs -# if ! STAT_STATVFS && STAT_STATVFS64 -# define STATFS statvfs64 -# else -# define STATFS statvfs -# endif +#define STRUCT_STATVFS struct statvfs +#if ! STAT_STATVFS && STAT_STATVFS64 +#define STATFS statvfs64 +#else +#define STATFS statvfs +#endif #else -# define STATFS statfs -# if HAVE_OS_H /* BeOS */ +#define STATFS statfs +#if HAVE_OS_H /* BeOS */ /* BeOS has a statvfs function, but it does not return sensible values for f_files, f_ffree and f_favail, and lacks f_type, f_basetype and f_fstypename. Use 'struct fs_info' instead. */ @@ -113,29 +113,27 @@ statfs (char const *filename, struct fs_info *buf) errno = (device == B_ENTRY_NOT_FOUND ? ENOENT : device == B_BAD_VALUE ? EINVAL : device == B_NAME_TOO_LONG ? ENAMETOOLONG - : device == B_NO_MEMORY ? ENOMEM - : device == B_FILE_ERROR ? EIO - : 0); + : device == B_NO_MEMORY ? ENOMEM : device == B_FILE_ERROR ? EIO : 0); return -1; } /* If successful, buf->dev will be == device. */ return fs_stat_dev (device, buf); } -# define STRUCT_STATVFS struct fs_info -# else -# define STRUCT_STATVFS struct statfs -# endif +#define STRUCT_STATVFS struct fs_info +#else +#define STRUCT_STATVFS struct statfs +#endif #endif #if HAVE_STRUCT_STATVFS_F_BASETYPE -# define STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME f_basetype +#define STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME f_basetype #else -# if HAVE_STRUCT_STATVFS_F_FSTYPENAME || HAVE_STRUCT_STATFS_F_FSTYPENAME -# define STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME f_fstypename -# elif HAVE_OS_H /* BeOS */ -# define STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME fsh_name -# endif +#if HAVE_STRUCT_STATVFS_F_FSTYPENAME || HAVE_STRUCT_STATFS_F_FSTYPENAME +#define STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME f_fstypename +#elif HAVE_OS_H /* BeOS */ +#define STATXFS_FILE_SYSTEM_TYPE_MEMBER_NAME fsh_name +#endif #endif #include diff --git a/src/filemanager/layout.c b/src/filemanager/layout.c index c7470b27e..64ca1479e 100644 --- a/src/filemanager/layout.c +++ b/src/filemanager/layout.c @@ -557,7 +557,7 @@ init_layout (void) } equal_split = panels_layout.horizontal_split ? - panels_layout.horizontal_equal : panels_layout.vertical_equal; + panels_layout.horizontal_equal : panels_layout.vertical_equal; /* "Panel split" groupbox */ bright_widget = button_new (6, 14, B_2RIGHT, NARROW_BUTTON, "&>", b_left_right_cback); diff --git a/src/filemanager/layout.h b/src/filemanager/layout.h index 2c7600122..dee4d28a2 100644 --- a/src/filemanager/layout.h +++ b/src/filemanager/layout.h @@ -71,7 +71,7 @@ struct Widget *get_panel_widget (int idx); struct WPanel *get_other_panel (void); void save_panel_dir (int idx); -char *get_panel_dir_for (const struct WPanel * widget); +char *get_panel_dir_for (const struct WPanel *widget); void set_hintbar (const char *str); diff --git a/src/filemanager/mountlist.c b/src/filemanager/mountlist.c index 989ba54b7..171bfbd4a 100644 --- a/src/filemanager/mountlist.c +++ b/src/filemanager/mountlist.c @@ -1233,7 +1233,9 @@ safe_read (int fd, void *buf, size_t count) INT_MAX bytes fails with errno == EINVAL. See . When decreasing COUNT, keep it block-aligned. */ + /* *INDENT-OFF* */ enum { BUGGY_READ_MAXIMUM = INT_MAX & ~8191 }; + /* *INDENT-ON* */ for (;;) { diff --git a/src/filemanager/mountlist.h b/src/filemanager/mountlist.h index 46f35137e..62fa9f970 100644 --- a/src/filemanager/mountlist.h +++ b/src/filemanager/mountlist.h @@ -1,6 +1,6 @@ /* Declarations for list of mounted filesystems -*/ + */ /** \file mountlist.h * \brief Header: list of mounted filesystems @@ -24,8 +24,8 @@ struct my_statfs char *typename; const char *mpoint; const char *device; - uintmax_t avail; /* in kB */ - uintmax_t total; /* in kB */ + uintmax_t avail; /* in kB */ + uintmax_t total; /* in kB */ uintmax_t nfree; uintmax_t nodes; }; diff --git a/src/filemanager/panel.c b/src/filemanager/panel.c index 36f496f58..fc53d038f 100644 --- a/src/filemanager/panel.c +++ b/src/filemanager/panel.c @@ -4423,7 +4423,7 @@ remove_encoding_from_path (const vfs_path_t * vpath) g_string_free (tmp_conv, TRUE); return ret_vpath; } -#endif /* HAVE_CHARSET */ +#endif /* HAVE_CHARSET */ /* --------------------------------------------------------------------------------------------- */ /** diff --git a/src/filemanager/usermenu.h b/src/filemanager/usermenu.h index 9596d788a..c3676e0ff 100644 --- a/src/filemanager/usermenu.h +++ b/src/filemanager/usermenu.h @@ -19,7 +19,7 @@ struct WEdit; /*** declarations of public functions ************************************************************/ -gboolean user_menu_cmd (struct WEdit *edit_widget, const char * menu_file, int selected_entry); +gboolean user_menu_cmd (struct WEdit *edit_widget, const char *menu_file, int selected_entry); char *expand_format (struct WEdit *edit_widget, char c, gboolean do_quote); int check_format_view (const char *); int check_format_var (const char *, char **); diff --git a/src/learn.c b/src/learn.c index 39a8f1f6c..5d8804f4c 100644 --- a/src/learn.c +++ b/src/learn.c @@ -373,7 +373,8 @@ learn_save (void) esc_str = strutils_escape (learnkeys[i].sequence, -1, ";\\", TRUE); - mc_config_set_string_raw_value (mc_main_config, section, key_name_conv_tab[i].name, esc_str); + mc_config_set_string_raw_value (mc_main_config, section, key_name_conv_tab[i].name, + esc_str); g_free (esc_str); } diff --git a/src/setup.h b/src/setup.h index 55b9bf94f..ec4f6948b 100644 --- a/src/setup.h +++ b/src/setup.h @@ -108,8 +108,8 @@ char *load_anon_passwd (void); void load_keymap_defs (gboolean load_from_file); void free_keymap_defs (void); -void panel_load_setup (struct WPanel * panel, const char *section); -void panel_save_setup (struct WPanel * panel, const char *section); +void panel_load_setup (struct WPanel *panel, const char *section); +void panel_save_setup (struct WPanel *panel, const char *section); void panels_load_options (void); void panels_save_options (void); diff --git a/src/subshell.c b/src/subshell.c index 410a88d1e..ad11fd2e0 100644 --- a/src/subshell.c +++ b/src/subshell.c @@ -252,7 +252,7 @@ init_subshell_child (const char *pty_name) /* It simplifies things to change to our home directory here, */ /* and the user's startup file may do a `cd' command anyway */ - chdir (mc_config_get_home_dir ()); /* FIXME? What about when we re-run the subshell? */ + chdir (mc_config_get_home_dir ()); /* FIXME? What about when we re-run the subshell? */ /* Set MC_SID to prevent running one mc from another */ mc_sid = getsid (0); diff --git a/src/vfs/cpio/cpio.c b/src/vfs/cpio/cpio.c index a76d376bc..a86177e06 100644 --- a/src/vfs/cpio/cpio.c +++ b/src/vfs/cpio/cpio.c @@ -854,7 +854,7 @@ init_cpiofs (void) { static struct vfs_s_subclass cpio_subclass; - cpio_subclass.flags = VFS_S_READONLY; /* FIXME: cpiofs used own temp files */ + cpio_subclass.flags = VFS_S_READONLY; /* FIXME: cpiofs used own temp files */ cpio_subclass.archive_check = cpio_super_check; cpio_subclass.archive_same = cpio_super_same; cpio_subclass.open_archive = cpio_open_archive; diff --git a/src/vfs/cpio/cpio.h b/src/vfs/cpio/cpio.h index ca4c9d195..de0238369 100644 --- a/src/vfs/cpio/cpio.h +++ b/src/vfs/cpio/cpio.h @@ -11,7 +11,7 @@ /*** declarations of public functions ************************************************************/ -void init_cpiofs(void); +void init_cpiofs (void); /*** inline functions ****************************************************************************/ diff --git a/src/vfs/extfs/extfs.c b/src/vfs/extfs/extfs.c index b6c52e0d8..d3e356d85 100644 --- a/src/vfs/extfs/extfs.c +++ b/src/vfs/extfs/extfs.c @@ -422,7 +422,7 @@ extfs_open_archive (int fstype, const char *name, struct archive **pparc) goto ret; } - tmp = name_quote ( vfs_path_get_last_path_str (name_vpath), 0); + tmp = name_quote (vfs_path_get_last_path_str (name_vpath), 0); } cmd = g_strconcat (info->path, info->prefix, " list ", diff --git a/src/vfs/fish/fish.h b/src/vfs/fish/fish.h index 1f3611021..245c14848 100644 --- a/src/vfs/fish/fish.h +++ b/src/vfs/fish/fish.h @@ -21,7 +21,7 @@ extern int fish_directory_timeout; /*** declarations of public functions ************************************************************/ -void init_fish(void); +void init_fish (void); /*** inline functions ****************************************************************************/ diff --git a/src/vfs/plugins_init.h b/src/vfs/plugins_init.h index 5a60bd540..9a36f1835 100644 --- a/src/vfs/plugins_init.h +++ b/src/vfs/plugins_init.h @@ -11,7 +11,7 @@ /*** declarations of public functions ************************************************************/ -void vfs_plugins_init(void); +void vfs_plugins_init (void); /*** inline functions ****************************************************************************/ diff --git a/src/vfs/sfs/sfs.c b/src/vfs/sfs/sfs.c index 2e146c665..75cc97d74 100644 --- a/src/vfs/sfs/sfs.c +++ b/src/vfs/sfs/sfs.c @@ -190,7 +190,8 @@ sfs_vfmake (const vfs_path_t * vpath, vfs_path_t * cache_vpath) COPY_CHAR; continue; } - if (ptr != NULL) { + if (ptr != NULL) + { COPY_STRING (ptr); } } diff --git a/src/vfs/smbfs/helpers/include/byteorder.h b/src/vfs/smbfs/helpers/include/byteorder.h index afb58e002..fd97ccb82 100644 --- a/src/vfs/smbfs/helpers/include/byteorder.h +++ b/src/vfs/smbfs/helpers/include/byteorder.h @@ -2,7 +2,7 @@ Unix SMB/Netbios implementation. Version 1.9. SMB Byte handling -*/ + */ #ifndef _BYTEORDER_H #define _BYTEORDER_H @@ -11,73 +11,73 @@ This file implements macros for machine independent short and int manipulation -Here is a description of this file that I emailed to the samba list once: + Here is a description of this file that I emailed to the samba list once: -> I am confused about the way that byteorder.h works in Samba. I have -> looked at it, and I would have thought that you might make a distinction -> between LE and BE machines, but you only seem to distinguish between 386 -> and all other architectures. -> -> Can you give me a clue? + > I am confused about the way that byteorder.h works in Samba. I have + > looked at it, and I would have thought that you might make a distinction + > between LE and BE machines, but you only seem to distinguish between 386 + > and all other architectures. + > + > Can you give me a clue? -sure. + sure. -The distinction between 386 and other architectures is only there as -an optimisation. You can take it out completely and it will make no -difference. The routines (macros) in byteorder.h are totally byteorder -independent. The 386 optimsation just takes advantage of the fact that -the x86 processors don't care about alignment, so we don't have to -align ints on int boundaries etc. If there are other processors out -there that aren't alignment sensitive then you could also define -CAREFUL_ALIGNMENT=0 on those processors as well. + The distinction between 386 and other architectures is only there as + an optimisation. You can take it out completely and it will make no + difference. The routines (macros) in byteorder.h are totally byteorder + independent. The 386 optimsation just takes advantage of the fact that + the x86 processors don't care about alignment, so we don't have to + align ints on int boundaries etc. If there are other processors out + there that aren't alignment sensitive then you could also define + CAREFUL_ALIGNMENT=0 on those processors as well. -Ok, now to the macros themselves. I'll take a simple example, say we -want to extract a 2 byte integer from a SMB packet and put it into a -type called uint16 that is in the local machines byte order, and you -want to do it with only the assumption that uint16 is _at_least_ 16 -bits long (this last condition is very important for architectures -that don't have any int types that are 2 bytes long) + Ok, now to the macros themselves. I'll take a simple example, say we + want to extract a 2 byte integer from a SMB packet and put it into a + type called uint16 that is in the local machines byte order, and you + want to do it with only the assumption that uint16 is _at_least_ 16 + bits long (this last condition is very important for architectures + that don't have any int types that are 2 bytes long) -You do this: + You do this: -#define CVAL(buf,pos) (((unsigned char *)(buf))[pos]) -#define PVAL(buf,pos) ((unsigned)CVAL(buf,pos)) -#define SVAL(buf,pos) (PVAL(buf,pos)|PVAL(buf,(pos)+1)<<8) + #define CVAL(buf,pos) (((unsigned char *)(buf))[pos]) + #define PVAL(buf,pos) ((unsigned)CVAL(buf,pos)) + #define SVAL(buf,pos) (PVAL(buf,pos)|PVAL(buf,(pos)+1)<<8) -then to extract a uint16 value at offset 25 in a buffer you do this: + then to extract a uint16 value at offset 25 in a buffer you do this: -char *buffer = foo_bar(); -uint16 xx = SVAL(buffer,25); + char *buffer = foo_bar(); + uint16 xx = SVAL(buffer,25); -We are using the byteoder independence of the ANSI C bitshifts to do -the work. A good optimising compiler should turn this into efficient -code, especially if it happens to have the right byteorder :-) + We are using the byteoder independence of the ANSI C bitshifts to do + the work. A good optimising compiler should turn this into efficient + code, especially if it happens to have the right byteorder :-) -I know these macros can be made a bit tidier by removing some of the -casts, but you need to look at byteorder.h as a whole to see the -reasoning behind them. byteorder.h defines the following macros: + I know these macros can be made a bit tidier by removing some of the + casts, but you need to look at byteorder.h as a whole to see the + reasoning behind them. byteorder.h defines the following macros: -SVAL(buf,pos) - extract a 2 byte SMB value -IVAL(buf,pos) - extract a 4 byte SMB value -SVALS(buf,pos) signed version of SVAL() -IVALS(buf,pos) signed version of IVAL() + SVAL(buf,pos) - extract a 2 byte SMB value + IVAL(buf,pos) - extract a 4 byte SMB value + SVALS(buf,pos) signed version of SVAL() + IVALS(buf,pos) signed version of IVAL() -SSVAL(buf,pos,val) - put a 2 byte SMB value into a buffer -SIVAL(buf,pos,val) - put a 4 byte SMB value into a buffer -SSVALS(buf,pos,val) - signed version of SSVAL() -SIVALS(buf,pos,val) - signed version of SIVAL() + SSVAL(buf,pos,val) - put a 2 byte SMB value into a buffer + SIVAL(buf,pos,val) - put a 4 byte SMB value into a buffer + SSVALS(buf,pos,val) - signed version of SSVAL() + SIVALS(buf,pos,val) - signed version of SIVAL() -RSVAL(buf,pos) - like SVAL() but for NMB byte ordering -RSVALS(buf,pos) - like SVALS() but for NMB byte ordering -RIVAL(buf,pos) - like IVAL() but for NMB byte ordering -RIVALS(buf,pos) - like IVALS() but for NMB byte ordering -RSSVAL(buf,pos,val) - like SSVAL() but for NMB ordering -RSIVAL(buf,pos,val) - like SIVAL() but for NMB ordering -RSIVALS(buf,pos,val) - like SIVALS() but for NMB ordering + RSVAL(buf,pos) - like SVAL() but for NMB byte ordering + RSVALS(buf,pos) - like SVALS() but for NMB byte ordering + RIVAL(buf,pos) - like IVAL() but for NMB byte ordering + RIVALS(buf,pos) - like IVALS() but for NMB byte ordering + RSSVAL(buf,pos,val) - like SSVAL() but for NMB ordering + RSIVAL(buf,pos,val) - like SIVAL() but for NMB ordering + RSIVALS(buf,pos,val) - like SIVALS() but for NMB ordering -it also defines lots of intermediate macros, just ignore those :-) + it also defines lots of intermediate macros, just ignore those :-) -*/ + */ /* some switch macros that do both store and read to and from SMB buffers */ @@ -142,7 +142,7 @@ it also defines lots of intermediate macros, just ignore those :-) /* WARNING: This section is dependent on the length of int16 and int32 being correct -*/ + */ /* get single value from an SMB buffer */ #define SVAL(buf,pos) (*(uint16 *)((char *)(buf) + (pos))) diff --git a/src/vfs/smbfs/helpers/include/charset.h b/src/vfs/smbfs/helpers/include/charset.h index d81295b83..910dbcc56 100644 --- a/src/vfs/smbfs/helpers/include/charset.h +++ b/src/vfs/smbfs/helpers/include/charset.h @@ -2,7 +2,7 @@ Unix SMB/Netbios implementation. Version 1.9. Character set handling -*/ + */ #ifndef CHARSET_C @@ -44,7 +44,7 @@ extern char *lower_char_map; /* this is used to determine if a character is safe to use in something that may be put on a command line */ #define issafe(c) (isalnum((c&0xff)) || strchr("-._",c)) -#endif /* !CHARSET_C */ +#endif /* !CHARSET_C */ /* Dynamic codepage files defines. */ diff --git a/src/vfs/smbfs/helpers/include/client.h b/src/vfs/smbfs/helpers/include/client.h dissimilarity index 71% index 0747e4569..35a708125 100644 --- a/src/vfs/smbfs/helpers/include/client.h +++ b/src/vfs/smbfs/helpers/include/client.h @@ -1,126 +1,127 @@ -/* - Unix SMB/Netbios implementation. - Version 1.9. - SMB parameters and setup -*/ - -#ifndef _CLIENT_H -#define _CLIENT_H - -/* the client asks for a smaller buffer to save ram and also to get more - overlap on the wire. This size gives us a nice read/write size, which - will be a multiple of the page size on almost any system */ -#define CLI_BUFFER_SIZE (0xFFFF) - -/* - * These definitions depend on smb.h - */ - -typedef struct file_info -{ - SMB_OFF_T size; - uint16 mode; - uid_t uid; - gid_t gid; - /* these times are normally kept in GMT */ - time_t mtime; - time_t atime; - time_t ctime; - pstring name; -} file_info; - -struct print_job_info -{ - uint16 id; - uint16 priority; - size_t size; - fstring user; - fstring name; - time_t t; -}; - -struct pwd_info -{ - BOOL null_pwd; - BOOL cleartext; - BOOL crypted; - - fstring password; - - uchar smb_lm_pwd[16]; - uchar smb_nt_pwd[16]; - - uchar smb_lm_owf[24]; - uchar smb_nt_owf[24]; -}; - -struct cli_state { - int port; - int fd; - uint16 cnum; - uint16 pid; - uint16 mid; - uint16 vuid; - int protocol; - int sec_mode; - int rap_error; - int privileges; - - fstring eff_name; - fstring desthost; - fstring user_name; - fstring domain; - - /* - * The following strings are the - * ones returned by the server if - * the protocol > NT1. - */ - fstring server_type; - fstring server_os; - fstring server_domain; - - fstring share; - fstring dev; - struct nmb_name called; - struct nmb_name calling; - fstring full_dest_host_name; - struct in_addr dest_ip; - - struct pwd_info pwd; - unsigned char cryptkey[8]; - uint32 sesskey; - int serverzone; - uint32 servertime; - int readbraw_supported; - int writebraw_supported; - int timeout; /* in milliseconds. */ - int max_xmit; - int max_mux; - char *outbuf; - char *inbuf; - int bufsize; - int initialised; - int win95; - uint32 capabilities; - - /* - * Only used in NT domain calls. - */ - - uint32 nt_error; /* NT RPC error code. */ - uint16 nt_pipe_fnum; /* Pipe handle. */ - unsigned char sess_key[16]; /* Current session key. */ - unsigned char ntlmssp_hash[258]; /* ntlmssp data. */ - uint32 ntlmssp_cli_flgs; /* ntlmssp client flags */ - uint32 ntlmssp_srv_flgs; /* ntlmssp server flags */ - uint32 ntlmssp_seq_num; /* ntlmssp sequence number */ - DOM_CRED clnt_cred; /* Client credential. */ - fstring mach_acct; /* MYNAME$. */ - fstring srv_name_slash; /* \\remote server. */ - fstring clnt_name_slash; /* \\local client. */ - uint16 max_xmit_frag; - uint16 max_recv_frag; -}; - -#endif /* _CLIENT_H */ +/* + Unix SMB/Netbios implementation. + Version 1.9. + SMB parameters and setup + */ + +#ifndef _CLIENT_H +#define _CLIENT_H + +/* the client asks for a smaller buffer to save ram and also to get more + overlap on the wire. This size gives us a nice read/write size, which + will be a multiple of the page size on almost any system */ +#define CLI_BUFFER_SIZE (0xFFFF) + +/* + * These definitions depend on smb.h + */ + +typedef struct file_info +{ + SMB_OFF_T size; + uint16 mode; + uid_t uid; + gid_t gid; + /* these times are normally kept in GMT */ + time_t mtime; + time_t atime; + time_t ctime; + pstring name; +} file_info; + +struct print_job_info +{ + uint16 id; + uint16 priority; + size_t size; + fstring user; + fstring name; + time_t t; +}; + +struct pwd_info +{ + BOOL null_pwd; + BOOL cleartext; + BOOL crypted; + + fstring password; + + uchar smb_lm_pwd[16]; + uchar smb_nt_pwd[16]; + + uchar smb_lm_owf[24]; + uchar smb_nt_owf[24]; +}; + +struct cli_state +{ + int port; + int fd; + uint16 cnum; + uint16 pid; + uint16 mid; + uint16 vuid; + int protocol; + int sec_mode; + int rap_error; + int privileges; + + fstring eff_name; + fstring desthost; + fstring user_name; + fstring domain; + + /* + * The following strings are the + * ones returned by the server if + * the protocol > NT1. + */ + fstring server_type; + fstring server_os; + fstring server_domain; + + fstring share; + fstring dev; + struct nmb_name called; + struct nmb_name calling; + fstring full_dest_host_name; + struct in_addr dest_ip; + + struct pwd_info pwd; + unsigned char cryptkey[8]; + uint32 sesskey; + int serverzone; + uint32 servertime; + int readbraw_supported; + int writebraw_supported; + int timeout; /* in milliseconds. */ + int max_xmit; + int max_mux; + char *outbuf; + char *inbuf; + int bufsize; + int initialised; + int win95; + uint32 capabilities; + + /* + * Only used in NT domain calls. + */ + + uint32 nt_error; /* NT RPC error code. */ + uint16 nt_pipe_fnum; /* Pipe handle. */ + unsigned char sess_key[16]; /* Current session key. */ + unsigned char ntlmssp_hash[258]; /* ntlmssp data. */ + uint32 ntlmssp_cli_flgs; /* ntlmssp client flags */ + uint32 ntlmssp_srv_flgs; /* ntlmssp server flags */ + uint32 ntlmssp_seq_num; /* ntlmssp sequence number */ + DOM_CRED clnt_cred; /* Client credential. */ + fstring mach_acct; /* MYNAME$. */ + fstring srv_name_slash; /* \\remote server. */ + fstring clnt_name_slash; /* \\local client. */ + uint16 max_xmit_frag; + uint16 max_recv_frag; +}; + +#endif /* _CLIENT_H */ diff --git a/src/vfs/smbfs/helpers/include/includes.h b/src/vfs/smbfs/helpers/include/includes.h index 4de51cb8d..8d481ad1d 100644 --- a/src/vfs/smbfs/helpers/include/includes.h +++ b/src/vfs/smbfs/helpers/include/includes.h @@ -4,9 +4,9 @@ Unix SMB/Netbios implementation. Version 1.9. Machine customisation and include handling -*/ + */ -#ifndef NO_CONFIG_H /* for some tests */ +#ifndef NO_CONFIG_H /* for some tests */ #include "config.h" #endif @@ -156,7 +156,7 @@ /* POSIX terminal handling. */ #include -# include +#include #ifdef HAVE_SYS_MMAN_H #include @@ -185,23 +185,23 @@ #include #endif -#ifdef HAVE_SYS_FS_S5PARAM_H +#ifdef HAVE_SYS_FS_S5PARAM_H #include #endif #if defined (HAVE_SYS_FILSYS_H) && !defined (_CRAY) -#include +#include #endif #ifdef HAVE_SYS_STATFS_H -# include +#include #endif -#ifdef HAVE_DUSTAT_H +#ifdef HAVE_DUSTAT_H #include #endif -#ifdef HAVE_SYS_STATVFS_H +#ifdef HAVE_SYS_STATVFS_H #include #endif @@ -219,7 +219,7 @@ #include #include #define PASSWORD_LENGTH 16 -#endif /* HAVE_SYS_SECURITY_H */ +#endif /* HAVE_SYS_SECURITY_H */ #ifdef HAVE_COMPAT_H #include @@ -269,7 +269,7 @@ they actually only need to be at least 16 and 32 bits respectively. Thus if your word size is 8 bytes just defining them as signed and unsigned int will work. -*/ + */ #ifndef uint8 #define uint8 unsigned char @@ -334,23 +334,23 @@ */ #ifndef SMB_INO_T -# define SMB_INO_T ino_t +#define SMB_INO_T ino_t #endif #ifndef LARGE_SMB_INO_T -# if defined(SIZEOF_INO_T) && (SIZEOF_INO_T == 8) -# define LARGE_SMB_INO_T 1 -# endif +#if defined(SIZEOF_INO_T) && (SIZEOF_INO_T == 8) +#define LARGE_SMB_INO_T 1 +#endif #endif #ifdef LARGE_SMB_INO_T #define SINO_T(p, ofs, v) (SIVAL(p,ofs,(v)&0xFFFFFFFF), SIVAL(p,(ofs)+4,(v)>>32)) -#else +#else #define SINO_T(p, ofs, v) (SIVAL(p,ofs,v),SIVAL(p,(ofs)+4,0)) #endif #ifndef SMB_OFF_T -# define SMB_OFF_T off_t +#define SMB_OFF_T off_t #endif #define SMB_OFF_T_BITS (sizeof(SMB_OFF_T)*8) @@ -361,14 +361,14 @@ */ #ifndef LARGE_SMB_OFF_T -# if defined(SIZEOF_OFF_T) && (SIZEOF_OFF_T == 8) -# define LARGE_SMB_OFF_T 1 -# endif +#if defined(SIZEOF_OFF_T) && (SIZEOF_OFF_T == 8) +#define LARGE_SMB_OFF_T 1 +#endif #endif #ifdef LARGE_SMB_OFF_T #define SOFF_T(p, ofs, v) (SIVAL(p,ofs,(v)&0xFFFFFFFF), SIVAL(p,(ofs)+4,(v)>>32)) -#else +#else #define SOFF_T(p, ofs, v) (SIVAL(p,ofs,v),SIVAL(p,(ofs)+4,0)) #endif @@ -377,7 +377,7 @@ */ #ifndef SMB_STRUCT_STAT -# define SMB_STRUCT_STAT struct stat +#define SMB_STRUCT_STAT struct stat #endif /* @@ -385,7 +385,7 @@ */ #ifndef SMB_STRUCT_DIRENT -# define SMB_STRUCT_DIRENT struct dirent +#define SMB_STRUCT_DIRENT struct dirent #endif /* @@ -393,19 +393,19 @@ */ #ifndef SMB_STRUCT_FLOCK -# define SMB_STRUCT_FLOCK struct flock +#define SMB_STRUCT_FLOCK struct flock #endif #ifndef SMB_F_SETLKW -# define SMB_F_SETLKW F_SETLKW +#define SMB_F_SETLKW F_SETLKW #endif #ifndef SMB_F_SETLK -# define SMB_F_SETLK F_SETLK +#define SMB_F_SETLK F_SETLK #endif #ifndef SMB_F_GETLK -# define SMB_F_GETLK F_GETLK +#define SMB_F_GETLK F_GETLK #endif #if defined(HAVE_LONGLONG) @@ -515,7 +515,7 @@ #endif /* what is the longest significant password available on your system? - Knowing this speeds up password searches a lot */ + Knowing this speeds up password searches a lot */ #ifndef PASSWORD_LENGTH #define PASSWORD_LENGTH 8 #endif @@ -549,19 +549,19 @@ #endif #ifndef HAVE_INITGROUPS -int initgroups(char *name,gid_t id); +int initgroups (char *name, gid_t id); #endif #ifndef HAVE_RENAME -int rename(const char *zfrom, const char *zto); +int rename (const char *zfrom, const char *zto); #endif #ifndef HAVE_MKTIME -time_t mktime(struct tm *t); +time_t mktime (struct tm *t); #endif #ifndef HAVE_STRTOUL -unsigned long strtoul(const char *nptr, char **endptr, int base); +unsigned long strtoul (const char *nptr, char **endptr, int base); #endif #ifdef REPLACE_GETPASS diff --git a/src/vfs/smbfs/helpers/include/kanji.h b/src/vfs/smbfs/helpers/include/kanji.h index c20bfc425..536f69300 100644 --- a/src/vfs/smbfs/helpers/include/kanji.h +++ b/src/vfs/smbfs/helpers/include/kanji.h @@ -2,7 +2,7 @@ Unix SMB/Netbios implementation. Version 1.9. Kanji Extensions -*/ + */ #ifndef _KANJI_H_ #define _KANJI_H_ @@ -86,7 +86,7 @@ #define is_hangul(c) ((0x81 <= ((unsigned char) (c)) && ((unsigned char) (c)) <= 0xfd)) /* For traditional Chinese (known as Big5 encoding - code page 950). */ -#define is_big5_c1(c) ((0xa1 <= ((unsigned char) (c)) && ((unsigned char) (c)) <= 0xf9)) +#define is_big5_c1(c) ((0xa1 <= ((unsigned char) (c)) && ((unsigned char) (c)) <= 0xf9)) /* For simplified Chinese (code page - 936). */ #define is_simpch_c1(c) ((0xa1 <= ((unsigned char) (c)) && ((unsigned char) (c)) <= 0xf7)) @@ -118,14 +118,14 @@ /* Ensure we use our definitions in all other files than kanji.c. */ /* Function pointers we will replace. */ -extern char *(*multibyte_strchr)(const char *s, int c); -extern char *(*multibyte_strrchr)(const char *s, int c); -extern char *(*multibyte_strstr)(const char *s1, const char *s2); -extern char *(*multibyte_strtok)(char *s1, const char *s2); -extern char *(*_dos_to_unix)(char *str, BOOL overwrite); -extern char *(*_unix_to_dos)(char *str, BOOL overwrite); -extern BOOL (*is_multibyte_char)(char c); -extern int (*_skip_multibyte_char)(char c); +extern char *(*multibyte_strchr) (const char *s, int c); +extern char *(*multibyte_strrchr) (const char *s, int c); +extern char *(*multibyte_strstr) (const char *s1, const char *s2); +extern char *(*multibyte_strtok) (char *s1, const char *s2); +extern char *(*_dos_to_unix) (char *str, BOOL overwrite); +extern char *(*_unix_to_dos) (char *str, BOOL overwrite); +extern BOOL (*is_multibyte_char) (char c); +extern int (*_skip_multibyte_char) (char c); #define strchr(s1, c) ((*multibyte_strchr)((s1), (c))) #define strrchr(s1, c) ((*multibyte_strrchr)((s1), (c))) diff --git a/src/vfs/smbfs/helpers/include/local.h b/src/vfs/smbfs/helpers/include/local.h index 67dafda80..f55d8c142 100644 --- a/src/vfs/smbfs/helpers/include/local.h +++ b/src/vfs/smbfs/helpers/include/local.h @@ -25,7 +25,7 @@ refer to the special "printers" service */ #define PRINTERS_NAME "printers" -/* Yves Gaige requested this set this */ +/* Yves Gaige requested this set this */ /* to a maximum of 8 if old smb clients break because of long printer names. */ #define MAXPRINTERLEN 15 @@ -59,7 +59,7 @@ #ifndef MAX_OPEN_FILES #define MAX_OPEN_FILES 10000 #endif - + /* the max number of simultanous connections to the server by all clients */ #define MAXSTATUS 100000 @@ -80,7 +80,7 @@ /* shall filenames with illegal chars in them get mangled in long filename listings? */ -#define MANGLE_LONG_FILENAMES +#define MANGLE_LONG_FILENAMES /* define this if you want to stop spoofing with .. and soft links NOTE: This also slows down the server considerably */ @@ -152,7 +152,7 @@ #define SHORT_CONNECT_TIMEOUT 5000 /* default socket options. Dave Miller thinks we should default to TCP_NODELAY - given the socket IO pattern that Samba uses*/ + given the socket IO pattern that Samba uses */ #ifdef TCP_NODELAY #define DEFAULT_SOCKET_OPTIONS "TCP_NODELAY" #else diff --git a/src/vfs/smbfs/helpers/include/nameserv.h b/src/vfs/smbfs/helpers/include/nameserv.h index cb575753b..e9147851c 100644 --- a/src/vfs/smbfs/helpers/include/nameserv.h +++ b/src/vfs/smbfs/helpers/include/nameserv.h @@ -4,7 +4,7 @@ Unix SMB/Netbios implementation. Version 1.9. NBT netbios header - version 2 -*/ + */ #define PERMANENT_TTL 0 @@ -12,16 +12,18 @@ #define MAINTAIN_LIST 2 #define ELECTION_VERSION 1 -#define MAX_DGRAM_SIZE (576) /* tcp/ip datagram limit is 576 bytes */ +#define MAX_DGRAM_SIZE (576) /* tcp/ip datagram limit is 576 bytes */ #define MIN_DGRAM_SIZE 12 /********************************************************* Types of reply packet. **********************************************************/ -enum netbios_reply_type_code { NMB_QUERY, NMB_STATUS, NMB_REG, NMB_REG_REFRESH, - NMB_REL, NMB_WAIT_ACK, NMB_MULTIHOMED_REG, - WINS_REG, WINS_QUERY }; +enum netbios_reply_type_code +{ NMB_QUERY, NMB_STATUS, NMB_REG, NMB_REG_REFRESH, + NMB_REL, NMB_WAIT_ACK, NMB_MULTIHOMED_REG, + WINS_REG, WINS_QUERY +}; /* From rfc1002, 4.2.1.2 */ /* Question types. */ @@ -33,14 +35,14 @@ enum netbios_reply_type_code { NMB_QUERY, NMB_STATUS, NMB_REG, NMB_REG_REFRESH, /* Opcode definitions */ #define NMB_NAME_QUERY_OPCODE 0x0 -#define NMB_NAME_REG_OPCODE 0x05 /* see rfc1002.txt 4.2.2,3,5,6,7,8 */ -#define NMB_NAME_RELEASE_OPCODE 0x06 /* see rfc1002.txt 4.2.9,10,11 */ -#define NMB_WACK_OPCODE 0x07 /* see rfc1002.txt 4.2.16 */ +#define NMB_NAME_REG_OPCODE 0x05 /* see rfc1002.txt 4.2.2,3,5,6,7,8 */ +#define NMB_NAME_RELEASE_OPCODE 0x06 /* see rfc1002.txt 4.2.9,10,11 */ +#define NMB_WACK_OPCODE 0x07 /* see rfc1002.txt 4.2.16 */ /* Ambiguity in rfc1002 about which of these is correct. */ /* WinNT uses 8 by default but can be made to use 9. */ -#define NMB_NAME_REFRESH_OPCODE_8 0x08 /* see rfc1002.txt 4.2.4 */ -#define NMB_NAME_REFRESH_OPCODE_9 0x09 /* see rfc1002.txt 4.2.4 */ -#define NMB_NAME_MULTIHOMED_REG_OPCODE 0x0F /* Invented by Microsoft. */ +#define NMB_NAME_REFRESH_OPCODE_8 0x08 /* see rfc1002.txt 4.2.4 */ +#define NMB_NAME_REFRESH_OPCODE_9 0x09 /* see rfc1002.txt 4.2.4 */ +#define NMB_NAME_MULTIHOMED_REG_OPCODE 0x0F /* Invented by Microsoft. */ /* XXXX what about all the other types?? 0x1, 0x2, 0x3, 0x4, 0x8? */ @@ -60,10 +62,10 @@ enum netbios_reply_type_code { NMB_QUERY, NMB_STATUS, NMB_REG, NMB_REG_REFRESH, #define NB_ACTIVE 0x04 #define NB_CONFL 0x08 #define NB_DEREG 0x10 -#define NB_BFLAG 0x00 /* Broadcast node type. */ -#define NB_PFLAG 0x20 /* Point-to-point node type. */ -#define NB_MFLAG 0x40 /* Mixed bcast & p-p node type. */ -#define NB_HFLAG 0x60 /* Microsoft 'hybrid' node type. */ +#define NB_BFLAG 0x00 /* Broadcast node type. */ +#define NB_PFLAG 0x20 /* Point-to-point node type. */ +#define NB_MFLAG 0x40 /* Mixed bcast & p-p node type. */ +#define NB_HFLAG 0x60 /* Microsoft 'hybrid' node type. */ #define NB_NODETYPEMASK 0x60 /* Mask applied to outgoing NetBIOS flags. */ #define NB_FLGMSK 0xE0 @@ -81,13 +83,13 @@ enum netbios_reply_type_code { NMB_QUERY, NMB_STATUS, NMB_REG, NMB_REG_REFRESH, #define NAME_IS_DEREGISTERING(p) ((p)->data.nb_flags & NB_DEREG) /* Error codes for NetBIOS requests. */ -#define FMT_ERR 0x1 /* Packet format error. */ -#define SRV_ERR 0x2 /* Internal server error. */ -#define NAM_ERR 0x3 /* Name does not exist. */ -#define IMP_ERR 0x4 /* Request not implemented. */ -#define RFS_ERR 0x5 /* Request refused. */ -#define ACT_ERR 0x6 /* Active error - name owned by another host. */ -#define CFT_ERR 0x7 /* Name in conflict error. */ +#define FMT_ERR 0x1 /* Packet format error. */ +#define SRV_ERR 0x2 /* Internal server error. */ +#define NAM_ERR 0x3 /* Name does not exist. */ +#define IMP_ERR 0x4 /* Request not implemented. */ +#define RFS_ERR 0x5 /* Request refused. */ +#define ACT_ERR 0x6 /* Active error - name owned by another host. */ +#define CFT_ERR 0x7 /* Name in conflict error. */ #define REFRESH_TIME (15*60) #define NAME_POLL_REFRESH_TIME (5*60) @@ -123,47 +125,51 @@ enum netbios_reply_type_code { NMB_QUERY, NMB_STATUS, NMB_REG, NMB_REG_REFRESH, * */ -enum name_source {LMHOSTS_NAME, REGISTER_NAME, SELF_NAME, DNS_NAME, - DNSFAIL_NAME, PERMANENT_NAME, WINS_PROXY_NAME}; -enum node_type {B_NODE=0, P_NODE=1, M_NODE=2, NBDD_NODE=3}; -enum packet_type {NMB_PACKET, DGRAM_PACKET}; +enum name_source +{ LMHOSTS_NAME, REGISTER_NAME, SELF_NAME, DNS_NAME, + DNSFAIL_NAME, PERMANENT_NAME, WINS_PROXY_NAME +}; +enum node_type +{ B_NODE = 0, P_NODE = 1, M_NODE = 2, NBDD_NODE = 3 }; +enum packet_type +{ NMB_PACKET, DGRAM_PACKET }; enum master_state { - MST_NONE, - MST_POTENTIAL, - MST_BACKUP, - MST_MSB, - MST_BROWSER, - MST_UNBECOMING_MASTER + MST_NONE, + MST_POTENTIAL, + MST_BACKUP, + MST_MSB, + MST_BROWSER, + MST_UNBECOMING_MASTER }; enum domain_state { - DOMAIN_NONE, - DOMAIN_WAIT, - DOMAIN_MST + DOMAIN_NONE, + DOMAIN_WAIT, + DOMAIN_MST }; enum logon_state { - LOGON_NONE, - LOGON_WAIT, - LOGON_SRV + LOGON_NONE, + LOGON_WAIT, + LOGON_SRV }; struct subnet_record; struct nmb_data { - uint16 nb_flags; /* Netbios flags. */ - int num_ips; /* Number of ip entries. */ - struct in_addr *ip; /* The ip list for this name. */ + uint16 nb_flags; /* Netbios flags. */ + int num_ips; /* Number of ip entries. */ + struct in_addr *ip; /* The ip list for this name. */ - enum name_source source; /* Where the name came from. */ + enum name_source source; /* Where the name came from. */ - time_t death_time; /* The time the record must be removed (do not remove if 0). */ - time_t refresh_time; /* The time the record should be refreshed. */ + time_t death_time; /* The time the record must be removed (do not remove if 0). */ + time_t refresh_time; /* The time the record should be refreshed. */ }; /* This is used to hold the list of servers in my domain, and is @@ -171,71 +177,72 @@ struct nmb_data struct server_record { - struct server_record *next; - struct server_record *prev; + struct server_record *next; + struct server_record *prev; - struct subnet_record *subnet; + struct subnet_record *subnet; - struct server_info_struct serv; - time_t death_time; + struct server_info_struct serv; + time_t death_time; }; /* A workgroup structure. It contains a list of servers. */ struct work_record { - struct work_record *next; - struct work_record *prev; + struct work_record *next; + struct work_record *prev; - struct subnet_record *subnet; + struct subnet_record *subnet; - struct server_record *serverlist; + struct server_record *serverlist; - /* Stage of development from non-local-master up to local-master browser. */ - enum master_state mst_state; + /* Stage of development from non-local-master up to local-master browser. */ + enum master_state mst_state; - /* Stage of development from non-domain-master to domain-master browser. */ - enum domain_state dom_state; + /* Stage of development from non-domain-master to domain-master browser. */ + enum domain_state dom_state; - /* Stage of development from non-logon-server to logon server. */ - enum logon_state log_state; + /* Stage of development from non-logon-server to logon server. */ + enum logon_state log_state; - /* Work group info. */ - fstring work_group; - int token; /* Used when communicating with backup browsers. */ - fstring local_master_browser_name; /* Current local master browser. */ + /* Work group info. */ + fstring work_group; + int token; /* Used when communicating with backup browsers. */ + fstring local_master_browser_name; /* Current local master browser. */ - /* Announce info. */ - time_t lastannounce_time; - int announce_interval; - BOOL needannounce; + /* Announce info. */ + time_t lastannounce_time; + int announce_interval; + BOOL needannounce; - /* Timeout time for this workgroup. 0 means permanent. */ - time_t death_time; + /* Timeout time for this workgroup. 0 means permanent. */ + time_t death_time; - /* Election info */ - BOOL RunningElection; - BOOL needelection; - int ElectionCount; - uint32 ElectionCriterion; + /* Election info */ + BOOL RunningElection; + BOOL needelection; + int ElectionCount; + uint32 ElectionCriterion; - /* Domain master browser info. Used for efficient syncs. */ - struct nmb_name dmb_name; - struct in_addr dmb_addr; + /* Domain master browser info. Used for efficient syncs. */ + struct nmb_name dmb_name; + struct in_addr dmb_addr; }; /* typedefs needed to define copy & free functions for userdata. */ struct userdata_struct; -typedef struct userdata_struct * (*userdata_copy_fn)(struct userdata_struct *); -typedef void (*userdata_free_fn)(struct userdata_struct *); +typedef struct userdata_struct *(*userdata_copy_fn) (struct userdata_struct *); +typedef void (*userdata_free_fn) (struct userdata_struct *); /* Structure to define any userdata passed around. */ -struct userdata_struct { - userdata_copy_fn copy_fn; - userdata_free_fn free_fn; - unsigned int userdata_len; - char data[16]; /* 16 is to ensure alignment/padding on all systems */ +struct userdata_struct +{ + userdata_copy_fn copy_fn; + userdata_free_fn free_fn; + unsigned int userdata_len; + char data[16]; /* 16 is to ensure alignment/padding on all systems */ }; struct response_record; @@ -243,99 +250,83 @@ struct packet_struct; struct res_rec; /* typedef to define the function called when this response packet comes in. */ -typedef void (*response_function)(struct subnet_record *, struct response_record *, - struct packet_struct *); +typedef void (*response_function) (struct subnet_record *, struct response_record *, + struct packet_struct *); /* typedef to define the function called when this response record times out. */ -typedef void (*timeout_response_function)(struct subnet_record *, - struct response_record *); +typedef void (*timeout_response_function) (struct subnet_record *, struct response_record *); /* typedef to define the function called when the request that caused this response record to be created is successful. */ -typedef void (*success_function)(struct subnet_record *, struct userdata_struct *, ...); +typedef void (*success_function) (struct subnet_record *, struct userdata_struct *, ...); /* typedef to define the function called when the request that caused this response record to be created is unsuccessful. */ -typedef void (*fail_function)(struct subnet_record *, struct response_record *, ...); +typedef void (*fail_function) (struct subnet_record *, struct response_record *, ...); /* List of typedefs for success and fail functions of the different query types. Used to catch any compile time prototype errors. */ -typedef void (*register_name_success_function)( struct subnet_record *, +typedef void (*register_name_success_function) (struct subnet_record *, struct userdata_struct *, - struct nmb_name *, - uint16, - int, - struct in_addr); -typedef void (*register_name_fail_function)( struct subnet_record *, - struct response_record *, - struct nmb_name *); - -typedef void (*release_name_success_function)( struct subnet_record *, - struct userdata_struct *, - struct nmb_name *, - struct in_addr); -typedef void (*release_name_fail_function)( struct subnet_record *, - struct response_record *, - struct nmb_name *); - -typedef void (*refresh_name_success_function)( struct subnet_record *, - struct userdata_struct *, - struct nmb_name *, - uint16, - int, - struct in_addr); -typedef void (*refresh_name_fail_function)( struct subnet_record *, - struct response_record *, - struct nmb_name *); - -typedef void (*query_name_success_function)( struct subnet_record *, + struct nmb_name *, uint16, int, struct in_addr); +typedef void (*register_name_fail_function) (struct subnet_record *, + struct response_record *, struct nmb_name *); + +typedef void (*release_name_success_function) (struct subnet_record *, + struct userdata_struct *, + struct nmb_name *, struct in_addr); +typedef void (*release_name_fail_function) (struct subnet_record *, + struct response_record *, struct nmb_name *); + +typedef void (*refresh_name_success_function) (struct subnet_record *, + struct userdata_struct *, + struct nmb_name *, uint16, int, struct in_addr); +typedef void (*refresh_name_fail_function) (struct subnet_record *, + struct response_record *, struct nmb_name *); + +typedef void (*query_name_success_function) (struct subnet_record *, struct userdata_struct *, struct nmb_name *, - struct in_addr, - struct res_rec *answers); + struct in_addr, struct res_rec * answers); -typedef void (*query_name_fail_function)( struct subnet_record *, - struct response_record *, - struct nmb_name *, - int); +typedef void (*query_name_fail_function) (struct subnet_record *, + struct response_record *, struct nmb_name *, int); -typedef void (*node_status_success_function)( struct subnet_record *, +typedef void (*node_status_success_function) (struct subnet_record *, struct userdata_struct *, - struct res_rec *, - struct in_addr); -typedef void (*node_status_fail_function)( struct subnet_record *, - struct response_record *); + struct res_rec *, struct in_addr); +typedef void (*node_status_fail_function) (struct subnet_record *, struct response_record *); /* Initiated name queries are recorded in this list to track any responses. */ struct response_record { - struct response_record *next; - struct response_record *prev; + struct response_record *next; + struct response_record *prev; + + uint16 response_id; - uint16 response_id; + /* Callbacks for packets received or not. */ + response_function resp_fn; + timeout_response_function timeout_fn; - /* Callbacks for packets received or not. */ - response_function resp_fn; - timeout_response_function timeout_fn; + /* Callbacks for the request succeeding or not. */ + success_function success_fn; + fail_function fail_fn; - /* Callbacks for the request succeeding or not. */ - success_function success_fn; - fail_function fail_fn; - - struct packet_struct *packet; + struct packet_struct *packet; - struct userdata_struct *userdata; + struct userdata_struct *userdata; - int num_msgs; + int num_msgs; - time_t repeat_time; - time_t repeat_interval; - int repeat_count; + time_t repeat_time; + time_t repeat_interval; + int repeat_count; - /* Recursion protection. */ - BOOL in_expiration_processing; + /* Recursion protection. */ + BOOL in_expiration_processing; }; /* A subnet structure. It contains a list of workgroups and netbios names. */ @@ -344,103 +335,112 @@ struct response_record B nodes will have their own, totally separate subnet record, with their own netbios name set. These do NOT interact with other subnet records' netbios names. -*/ + */ -enum subnet_type { - NORMAL_SUBNET = 0, /* Subnet listed in interfaces list. */ - UNICAST_SUBNET = 1, /* Subnet for unicast packets. */ - REMOTE_BROADCAST_SUBNET = 2, /* Subnet for remote broadcasts. */ - WINS_SERVER_SUBNET = 3 /* Only created if we are a WINS server. */ +enum subnet_type +{ + NORMAL_SUBNET = 0, /* Subnet listed in interfaces list. */ + UNICAST_SUBNET = 1, /* Subnet for unicast packets. */ + REMOTE_BROADCAST_SUBNET = 2, /* Subnet for remote broadcasts. */ + WINS_SERVER_SUBNET = 3 /* Only created if we are a WINS server. */ }; /* A resource record. */ -struct res_rec { - struct nmb_name rr_name; - int rr_type; - int rr_class; - int ttl; - int rdlength; - char rdata[MAX_DGRAM_SIZE]; +struct res_rec +{ + struct nmb_name rr_name; + int rr_type; + int rr_class; + int ttl; + int rdlength; + char rdata[MAX_DGRAM_SIZE]; }; /* An nmb packet. */ struct nmb_packet { - struct { - int name_trn_id; - int opcode; - BOOL response; - struct { - BOOL bcast; - BOOL recursion_available; - BOOL recursion_desired; - BOOL trunc; - BOOL authoritative; - } nm_flags; - int rcode; - int qdcount; - int ancount; - int nscount; - int arcount; - } header; - - struct { - struct nmb_name question_name; - int question_type; - int question_class; - } question; - - struct res_rec *answers; - struct res_rec *nsrecs; - struct res_rec *additional; + struct + { + int name_trn_id; + int opcode; + BOOL response; + struct + { + BOOL bcast; + BOOL recursion_available; + BOOL recursion_desired; + BOOL trunc; + BOOL authoritative; + } nm_flags; + int rcode; + int qdcount; + int ancount; + int nscount; + int arcount; + } header; + + struct + { + struct nmb_name question_name; + int question_type; + int question_class; + } question; + + struct res_rec *answers; + struct res_rec *nsrecs; + struct res_rec *additional; }; /* A datagram - this normally contains SMB data in the data[] array. */ -struct dgram_packet { - struct { - int msg_type; - struct { - enum node_type node_type; - BOOL first; - BOOL more; - } flags; - int dgm_id; - struct in_addr source_ip; - int source_port; - int dgm_length; - int packet_offset; - } header; - struct nmb_name source_name; - struct nmb_name dest_name; - int datasize; - char data[MAX_DGRAM_SIZE]; +struct dgram_packet +{ + struct + { + int msg_type; + struct + { + enum node_type node_type; + BOOL first; + BOOL more; + } flags; + int dgm_id; + struct in_addr source_ip; + int source_port; + int dgm_length; + int packet_offset; + } header; + struct nmb_name source_name; + struct nmb_name dest_name; + int datasize; + char data[MAX_DGRAM_SIZE]; }; /* Define a structure used to queue packets. This will be a linked - list of nmb packets. */ + list of nmb packets. */ struct packet_struct { - struct packet_struct *next; - struct packet_struct *prev; - BOOL locked; - struct in_addr ip; - int port; - int fd; - time_t timestamp; - enum packet_type packet_type; - union { - struct nmb_packet nmb; - struct dgram_packet dgram; - } packet; + struct packet_struct *next; + struct packet_struct *prev; + BOOL locked; + struct in_addr ip; + int port; + int fd; + time_t timestamp; + enum packet_type packet_type; + union + { + struct nmb_packet nmb; + struct dgram_packet dgram; + } packet; }; /* NETLOGON opcodes */ -#define QUERYFORPDC 7 /* Query for PDC. */ -#define QUERYFORPDC_R 12 /* Response to Query for PDC. */ +#define QUERYFORPDC 7 /* Query for PDC. */ +#define QUERYFORPDC_R 12 /* Response to Query for PDC. */ #define SAMLOGON 18 #define SAMLOGON_R 19 @@ -462,11 +462,11 @@ struct packet_struct /* Broadcast packet announcement intervals, in minutes. */ /* Attempt to add domain logon and domain master names. */ -#define CHECK_TIME_ADD_DOM_NAMES 5 +#define CHECK_TIME_ADD_DOM_NAMES 5 /* Search for master browsers of workgroups samba knows about, except default. */ -#define CHECK_TIME_MST_BROWSE 5 +#define CHECK_TIME_MST_BROWSE 5 /* Request backup browser announcements from other servers. */ #define CHECK_TIME_ANNOUNCE_BACKUP 15 @@ -501,5 +501,6 @@ extern struct subnet_record *remote_broadcast_subnet; #define NEXT_SUBNET_INCLUDING_UNICAST(x) (get_next_subnet_maybe_unicast((x))) /* To be removed. */ -enum state_type { TEST }; +enum state_type +{ TEST }; #endif /* _NAMESERV_H_ */ diff --git a/src/vfs/smbfs/helpers/include/proto.h b/src/vfs/smbfs/helpers/include/proto.h dissimilarity index 92% index c6d22321d..bdf30dbb0 100644 --- a/src/vfs/smbfs/helpers/include/proto.h +++ b/src/vfs/smbfs/helpers/include/proto.h @@ -1,620 +1,606 @@ -#ifndef _PROTO_H_ -#define _PROTO_H_ -/* This file is automatically generated with "make proto". DO NOT EDIT */ - -/* The following definitions come from lib/charcnv.c */ - -char *unix2dos_format(char *str,BOOL overwrite); -char *dos2unix_format(char *str, BOOL overwrite); -void interpret_character_set(const char *str); - -/* The following definitions come from lib/charset.c */ - -void charset_initialise(void); -void codepage_initialise(int client_codepage); -void add_char_string(const char *s); - -/* The following definitions come from lib/debug.c */ - -void setup_logging( const char *pname, BOOL interactive ); -void dbgflush( void ); -BOOL dbghdr( int level, const char *file, const char *func, int line ); - -/* The following definitions come from lib/interface.c */ - -void load_interfaces(void); -void iface_set_default(char *ip,char *bcast,char *nmask); -BOOL ismyip(struct in_addr ip); -BOOL is_local_net(struct in_addr from); -int iface_count(void); -BOOL we_are_multihomed(void); -struct interface *get_interface(int n); -struct in_addr *iface_n_ip(int n); -unsigned iface_hash(void); -struct in_addr *iface_bcast(struct in_addr ip); -struct in_addr *iface_ip(struct in_addr ip); - -/* The following definitions come from lib/kanji.c */ - -void interpret_coding_system(const char *str); -BOOL is_multibyte_codepage(void); -void initialize_multibyte_vectors( int client_codepage); - -/* The following definitions come from lib/md4.c */ - -void mdfour(unsigned char *out, unsigned char *in, int n); - -/* The following definitions come from lib/netmask.c */ - -int get_netmask(struct in_addr *ipaddr, struct in_addr *nmask); - -/* The following definitions come from lib/slprintf.c */ - -int vslprintf(char *str, int n, const char *format, va_list ap); - -/* The following definitions come from lib/system.c */ - -int sys_select(int maxfd, fd_set *fds,struct timeval *tval); -int sys_stat(const char *fname,SMB_STRUCT_STAT *sbuf); -int sys_lstat(const char *fname,SMB_STRUCT_STAT *sbuf); -int sys_fseek(FILE *fp, SMB_OFF_T offset, int whence); -SMB_OFF_T sys_ftell(FILE *fp); -int sys_open(const char *path, int oflag, mode_t mode); -FILE *sys_fopen(const char *path, const char *type); -SMB_STRUCT_DIRENT *sys_readdir(DIR *dirp); -char *sys_getwd(char *s); -int sys_chown(const char *fname,uid_t uid,gid_t gid); -struct hostent *sys_gethostbyname(const char *name); -long sys_random(void); -void sys_srandom(unsigned int seed); - -/* The following definitions come from lib/time.c */ - -void GetTimeOfDay(struct timeval *tval); -void TimeInit(void); -int TimeDiff(time_t t); -struct tm *LocalTime(time_t *t); -time_t nt_time_to_unix(NTTIME *nt); -time_t interpret_long_date(char *p); -void unix_to_nt_time(NTTIME *nt, time_t t); -void put_long_date(char *p,time_t t); -BOOL null_mtime(time_t mtime); -void put_dos_date(char *buf,int offset,time_t unixdate); -void put_dos_date2(char *buf,int offset,time_t unixdate); -void put_dos_date3(char *buf,int offset,time_t unixdate); -time_t make_unix_date(void *date_ptr); -time_t make_unix_date2(void *date_ptr); -time_t make_unix_date3(void *date_ptr); -char *http_timestring(time_t t); -char *timestring(void ); -time_t get_create_time(SMB_STRUCT_STAT *st,BOOL fake_dirs); - -/* The following definitions come from lib/username.c */ - -const char *get_home_dir(char *user); -BOOL map_username(const char *user); -struct passwd *Get_Pwnam(const char *user); -BOOL user_in_list(const char *user,char *list); - -/* The following definitions come from lib/util.c */ - -const char *tmpdir(void); -BOOL in_group(gid_t group, gid_t current_gid, int ngroups, gid_t *groups); -char *Atoic(char *p, int *n, char *c); -char *get_numlist(char *p, uint32 **num, int *count); -void putip(void *dest,void *src); -char *dns_to_netbios_name(char *dns_name); -int name_mangle( char *In, char *Out, char name_type ); -BOOL file_exist(char *fname,SMB_STRUCT_STAT *sbuf); -time_t file_modtime(char *fname); -BOOL directory_exist(char *dname,SMB_STRUCT_STAT *st); -SMB_OFF_T file_size(char *file_name); -char *attrib_string(uint16 mode); -void unix_format(char *fname); -void dos_format(char *fname); -void show_msg(char *buf); -int smb_len(char *buf); -void _smb_setlen(char *buf,int len); -void smb_setlen(char *buf,int len); -int set_message(char *buf,int num_words,int num_bytes,BOOL zero); -int smb_buflen(char *buf); -char *smb_buf(char *buf); -int smb_offset(char *p,char *buf); -void dos_clean_name(char *s); -void unix_clean_name(char *s); -BOOL reduce_name(char *s,char *dir,BOOL widelinks); -void expand_mask(char *Mask,BOOL doext); -void make_dir_struct(char *buf,char *mask,char *fname,SMB_OFF_T size,int mode,time_t date); -void close_low_fds(void); -int set_blocking(int fd, BOOL set); -int TvalDiff(struct timeval *tvalold,struct timeval *tvalnew); -SMB_OFF_T transfer_file(int infd,int outfd,SMB_OFF_T n,char *header,int headlen,int align); -int name_extract(char *buf,int ofs,char *name); -int name_len(char *s1); -void msleep(int t); -BOOL do_match(char *str, char *regexp, int case_sig); -BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2); -int set_filelen(int fd, SMB_OFF_T len); -void *Realloc(void *p,size_t size); -BOOL get_myname(char *my_name,struct in_addr *ip); -BOOL ip_equal(struct in_addr ip1,struct in_addr ip2); -int interpret_protocol(char *str,int def); -uint32 interpret_addr(const char *str); -struct in_addr *interpret_addr2(const char *str); -BOOL zero_ip(struct in_addr ip); -BOOL matchname(char *remotehost,struct in_addr addr); -void standard_sub_basic(char *str); -void standard_sub(connection_struct *conn,char *str); -BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask); -struct hostent *Get_Hostbyname(const char *name); -char *uidtoname(uid_t uid); -char *gidtoname(gid_t gid); -uid_t nametouid(const char *name); -void smb_panic(const char *why); -char *readdirname(DIR *p); -BOOL is_in_path(char *name, name_compare_entry *namelist); -void set_namearray(name_compare_entry **ppname_array, char *namelist); -void free_namearray(name_compare_entry *name_array); -BOOL fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type); -BOOL is_myname(char *s); -void set_remote_arch(enum remote_arch_types type); -enum remote_arch_types get_remote_arch(void); -char *align2(char *q, char *base); -void out_ascii(FILE *f, unsigned char *buf,int len); -void out_data(FILE *f,char *buf1,int len, int per_line); -void print_asc(int level, unsigned char *buf,int len); -void dump_data(int level,char *buf1,int len); -char *tab_depth(int depth); -int str_checksum(const char *s); -void zero_free(void *p, size_t size); -int set_maxfiles(int requested_max); - -/* The following definitions come from lib/util_file.c */ - -BOOL do_file_lock(int fd, int waitsecs, int type); -BOOL file_lock(int fd, int type, int secs, int *plock_depth); -BOOL file_unlock(int fd, int *plock_depth); -void *startfilepwent(char *pfile, char *s_readbuf, int bufsize, - int *file_lock_depth, BOOL update); -void endfilepwent(void *vp, int *file_lock_depth); -SMB_BIG_UINT getfilepwpos(void *vp); -BOOL setfilepwpos(void *vp, SMB_BIG_UINT tok); -int getfileline(void *vp, char *linebuf, int linebuf_size); -char *fgets_slash(char *s2,int maxlen,FILE *f); - -/* The following definitions come from lib/util_sock.c */ - -BOOL is_a_socket(int fd); -void set_socket_options(int fd, char *options); -void close_sockets(void ); -ssize_t write_socket(int fd,char *buf,size_t len); -ssize_t read_udp_socket(int fd,char *buf,size_t len); -ssize_t read_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned int time_out); -BOOL send_keepalive(int client); -ssize_t read_data(int fd,char *buffer,size_t N); -ssize_t write_data(int fd,char *buffer,size_t N); -ssize_t read_smb_length(int fd,char *inbuf,unsigned int timeout); -BOOL receive_smb(int fd,char *buffer, unsigned int timeout); -BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout); -BOOL send_null_session_msg(int fd); -BOOL send_smb(int fd,char *buffer); -BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type); -int open_socket_in(int type, int port, int dlevel,uint32 socket_addr, BOOL rebind); -int open_socket_out(int type, struct in_addr *addr, int port ,int timeout); -char *client_name(int fd); -char *client_addr(int fd); - -/* The following definitions come from lib/util_str.c */ - -void set_first_token(char *ptr); -BOOL next_token(char **ptr,char *buff, const char *sep, size_t bufsize); -char **toktocliplist(int *ctok, char *sep); -int StrCaseCmp(const char *s, const char *t); -int StrnCaseCmp(const char *s, const char *t, size_t n); -BOOL strequal(const char *s1, const char *s2); -BOOL strnequal(const char *s1,const char *s2,size_t n); -BOOL strcsequal(const char *s1,const char *s2); -void strlower(char *s); -void strupper(char *s); -void strnorm(char *s); -BOOL strisnormal(char *s); -void string_replace(char *s,char oldc,char newc); -char *skip_string(char *buf,size_t n); -size_t str_charnum(const char *s); -BOOL trim_string(char *s,const char *front,const char *back); -BOOL strhasupper(const char *s); -BOOL strhaslower(const char *s); -size_t count_chars(const char *s,char c); -char *safe_strcpy(char *dest,const char *src, size_t maxlength); -char *safe_strcat(char *dest, const char *src, size_t maxlength); -char *StrCpy(char *dest,const char *src); -char *StrnCpy(char *dest,const char *src,size_t n); -char *strncpyn(char *dest, const char *src,size_t n, char c); -size_t strhex_to_str(char *p, size_t len, const char *strhex); -BOOL in_list(char *s,char *list,BOOL casesensitive); -BOOL string_init(char **dest,const char *src); -void string_free(char **s); -BOOL string_set(char **dest,const char *src); -void string_sub(char *s,const char *pattern,const char *insert); -void all_string_sub(char *s,const char *pattern,const char *insert); -void split_at_last_component(char *path, char *front, char sep, char *back); - -/* The following definitions come from libsmb/clientgen.c */ - -int cli_set_port(struct cli_state *cli, int port); -char *cli_errstr(struct cli_state *cli); -BOOL cli_api_pipe(struct cli_state *cli, char *pipe_name, int pipe_name_len, - uint16 *setup, uint32 setup_count, uint32 max_setup_count, - char *params, uint32 param_count, uint32 max_param_count, - char *data, uint32 data_count, uint32 max_data_count, - char **rparam, uint32 *rparam_count, - char **rdata, uint32 *rdata_count); -BOOL cli_api(struct cli_state *cli, - char *param, int prcnt, int mprcnt, - char *data, int drcnt, int mdrcnt, - char **rparam, int *rprcnt, - char **rdata, int *rdrcnt); -BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation); -int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, const char *, void *), void * state); -BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, - void (*fn)(const char *, uint32, const char *, void *), void *state); -BOOL cli_session_setup(struct cli_state *cli, - char *user, - char *pass, int passlen, - char *ntpass, int ntpasslen, - char *workgroup); -BOOL cli_ulogoff(struct cli_state *cli); -BOOL cli_send_tconX(struct cli_state *cli, - const char *share, const char *dev, const char *pass, int passlen); -BOOL cli_tdis(struct cli_state *cli); -BOOL cli_rename(struct cli_state *cli, char *fname_src, char *fname_dst); -BOOL cli_unlink(struct cli_state *cli, char *fname); -BOOL cli_mkdir(struct cli_state *cli, char *dname); -BOOL cli_rmdir(struct cli_state *cli, char *dname); -int cli_nt_create(struct cli_state *cli, char *fname); -int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode); -BOOL cli_close(struct cli_state *cli, int fnum); -BOOL cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int timeout); -BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int timeout); -size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size); -ssize_t cli_write(struct cli_state *cli, - int fnum, uint16 write_mode, - const char *buf, off_t offset, size_t size); -ssize_t cli_smbwrite(struct cli_state *cli, - int fnum, const char *buf, off_t offset, size_t size); -BOOL cli_getattrE(struct cli_state *cli, int fd, - uint16 *attr, size_t *size, - time_t *c_time, time_t *a_time, time_t *m_time); -BOOL cli_getatr(struct cli_state *cli, char *fname, - uint16 *attr, size_t *size, time_t *t); -BOOL cli_setatr(struct cli_state *cli, char *fname, uint16 attr, time_t t); -BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, - time_t *c_time, time_t *a_time, time_t *m_time, - size_t *size, uint16 *mode); -BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, - time_t *c_time, time_t *a_time, time_t *m_time, - time_t *w_time, size_t *size, uint16 *mode, - SMB_INO_T *ino); -BOOL cli_qfileinfo(struct cli_state *cli, int fnum, - uint16 *mode, size_t *size, - time_t *c_time, time_t *a_time, time_t *m_time, - time_t *w_time, SMB_INO_T *ino); -int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, - void (*fn)(file_info *, const char *, void *), void *state); -BOOL cli_negprot(struct cli_state *cli); -BOOL cli_session_request(struct cli_state *cli, - struct nmb_name *calling, struct nmb_name *called); -BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip); -struct cli_state *cli_initialise(struct cli_state *cli); -void cli_shutdown(struct cli_state *cli); -int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num, uint32 *nt_rpc_error); -void cli_sockopt(struct cli_state *cli, char *options); -uint16 cli_setpid(struct cli_state *cli, uint16 pid); -BOOL cli_reestablish_connection(struct cli_state *cli); -BOOL cli_establish_connection(struct cli_state *cli, - char *dest_host, struct in_addr *dest_ip, - struct nmb_name *calling, struct nmb_name *called, - char *service, char *service_type, - BOOL do_shutdown, BOOL do_tcon); -BOOL cli_chkpath(struct cli_state *cli, char *path); -BOOL cli_message_start(struct cli_state *cli, char *host, char *username, - int *grp); -BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp); -BOOL cli_message_end(struct cli_state *cli, int grp); -BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail); - -/* The following definitions come from libsmb/namequery.c */ - -struct in_addr *name_query(int fd,const char *name,int name_type, BOOL bcast,BOOL recurse, - struct in_addr to_ip, int *count, void (*fn)(struct packet_struct *)); -FILE *startlmhosts(const char *fname); -BOOL getlmhostsent( FILE *fp, pstring name, int *name_type, struct in_addr *ipaddr); -void endlmhosts(FILE *fp); -BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type); -BOOL find_master_ip(char *group, struct in_addr *master_ip); - -/* The following definitions come from libsmb/nmblib.c */ - -void debug_nmb_packet(struct packet_struct *p); -char *nmb_namestr(struct nmb_name *n); -struct packet_struct *copy_packet(struct packet_struct *packet); -void free_packet(struct packet_struct *packet); -struct packet_struct *read_packet(int fd,enum packet_type packet_type); -void make_nmb_name( struct nmb_name *n, const char *name, int type ); -BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2); -BOOL send_packet(struct packet_struct *p); -struct packet_struct *receive_packet(int fd,enum packet_type type,int t); -void sort_query_replies(char *data, int n, struct in_addr ip); - -/* The following definitions come from libsmb/nterr.c */ - -const char *get_nt_error_msg(uint32 nt_code); - -/* The following definitions come from libsmb/pwd_cache.c */ - -void pwd_init(struct pwd_info *pwd); -void pwd_obfuscate_key(struct pwd_info *pwd, uint32 int_key, char *str_key); -void pwd_read(struct pwd_info *pwd, char *passwd_report, BOOL do_encrypt); -void pwd_set_nullpwd(struct pwd_info *pwd); -void pwd_set_cleartext(struct pwd_info *pwd, char *clr); -void pwd_get_cleartext(struct pwd_info *pwd, char *clr); -void pwd_set_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]); -void pwd_get_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]); -void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr); -void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8]); -void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24], uchar nt_owf[24]); - -/* The following definitions come from libsmb/smbdes.c */ - -void E_P16(unsigned char *p14,unsigned char *p16); -void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24); -void D_P16(unsigned char *p14, unsigned char *in, unsigned char *out); -void E_old_pw_hash( unsigned char *p14, unsigned char *in, unsigned char *out); -void cred_hash1(unsigned char *out,unsigned char *in,unsigned char *key); -void cred_hash2(unsigned char *out,unsigned char *in,unsigned char *key); -void cred_hash3(unsigned char *out,unsigned char *in,unsigned char *key, int forw); -void SamOEMhash( unsigned char *data, unsigned char *key, int val); - -/* The following definitions come from libsmb/smbencrypt.c */ - -void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24); -void E_md4hash(uchar *passwd, uchar *p16); -void nt_lm_owf_gen(char *pwd, uchar nt_p16[16], uchar p16[16]); -void SMBOWFencrypt(uchar passwd[16], uchar *c8, uchar p24[24]); -void NTLMSSPOWFencrypt(uchar passwd[8], uchar *ntlmchalresp, uchar p24[24]); -void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24); - -/* The following definitions come from libsmb/smberr.c */ - -char *smb_errstr(char *inbuf); - -/* The following definitions come from param/loadparm.c */ - -char *lp_logfile(void); -char *lp_configfile(void); -char *lp_smb_passwd_file(void); -char *lp_serverstring(void); -char *lp_printcapname(void); -char *lp_lockdir(void); -char *lp_rootdir(void); -char *lp_defaultservice(void); -char *lp_msg_command(void); -char *lp_hosts_equiv(void); -char *lp_auto_services(void); -char *lp_passwd_program(void); -char *lp_passwd_chat(void); -char *lp_passwordserver(void); -char *lp_name_resolve_order(void); -char *lp_workgroup(void); -char *lp_username_map(void); -char *lp_groupname_map(void); -char *lp_logon_script(void); -char *lp_logon_path(void); -char *lp_logon_drive(void); -char *lp_logon_home(void); -char *lp_remote_announce(void); -char *lp_remote_browse_sync(void); -char *lp_wins_server(void); -char *lp_interfaces(void); -char *lp_socket_address(void); -char *lp_nis_home_map_name(void); -char *lp_netbios_aliases(void); -char *lp_driverfile(void); -char *lp_panic_action(void); -char *lp_adduser_script(void); -char *lp_deluser_script(void); -char *lp_domain_groups(void); -char *lp_domain_admin_group(void); -char *lp_domain_guest_group(void); -char *lp_domain_admin_users(void); -char *lp_domain_guest_users(void); -char *lp_ldap_server(void); -char *lp_ldap_suffix(void); -char *lp_ldap_filter(void); -char *lp_ldap_root(void); -char *lp_ldap_rootpasswd(void); -int lp_ssl_version(void); -char *lp_ssl_hosts(void); -char *lp_ssl_hosts_resign(void); -char *lp_ssl_cacertdir(void); -char *lp_ssl_cacertfile(void); -char *lp_ssl_cert(void); -char *lp_ssl_privkey(void); -char *lp_ssl_client_cert(void); -char *lp_ssl_client_privkey(void); -char *lp_ssl_ciphers(void); -BOOL lp_ssl_enabled(void); -BOOL lp_ssl_reqClientCert(void); -BOOL lp_ssl_reqServerCert(void); -BOOL lp_ssl_compatibility(void); -BOOL lp_dns_proxy(void); -BOOL lp_wins_support(void); -BOOL lp_we_are_a_wins_server(void); -BOOL lp_wins_proxy(void); -BOOL lp_local_master(void); -BOOL lp_domain_master(void); -BOOL lp_domain_logons(void); -BOOL lp_preferred_master(void); -BOOL lp_load_printers(void); -BOOL lp_use_rhosts(void); -BOOL lp_readprediction(void); -BOOL lp_readbmpx(void); -BOOL lp_readraw(void); -BOOL lp_writeraw(void); -BOOL lp_null_passwords(void); -BOOL lp_strip_dot(void); -BOOL lp_encrypted_passwords(void); -BOOL lp_update_encrypted(void); -BOOL lp_syslog_only(void); -BOOL lp_timestamp_logs(void); -BOOL lp_browse_list(void); -BOOL lp_unix_realname(void); -BOOL lp_nis_home_map(void); -BOOL lp_bind_interfaces_only(void); -BOOL lp_unix_password_sync(void); -BOOL lp_passwd_chat_debug(void); -BOOL lp_ole_locking_compat(void); -BOOL lp_nt_smb_support(void); -BOOL lp_nt_pipe_support(void); -BOOL lp_nt_acl_support(void); -BOOL lp_stat_cache(void); -BOOL lp_allow_trusted_domains(void); -BOOL lp_restrict_anonymous(void); -int lp_os_level(void); -int lp_max_ttl(void); -int lp_max_wins_ttl(void); -int lp_min_wins_ttl(void); -int lp_max_open_files(void); -int lp_maxxmit(void); -int lp_maxmux(void); -int lp_passwordlevel(void); -int lp_usernamelevel(void); -int lp_readsize(void); -int lp_shmem_size(void); -int lp_deadtime(void); -int lp_maxprotocol(void); -int lp_security(void); -int lp_maxdisksize(void); -int lp_lpqcachetime(void); -int lp_syslog(void); -int lp_client_code_page(void); -int lp_lm_announce(void); -int lp_lm_interval(void); -int lp_machine_password_timeout(void); -int lp_change_notify_timeout(void); -int lp_stat_cache_size(void); -int lp_map_to_guest(void); -int lp_min_passwd_length(void); -int lp_oplock_break_wait_time(void); -int lp_ldap_port(void); -char *lp_preexec(int ); -char *lp_postexec(int ); -char *lp_rootpreexec(int ); -char *lp_rootpostexec(int ); -char *lp_servicename(int ); -char *lp_pathname(int ); -char *lp_dontdescend(int ); -char *lp_username(int ); -char *lp_guestaccount(int ); -char *lp_invalid_users(int ); -char *lp_valid_users(int ); -char *lp_admin_users(int ); -char *lp_printcommand(int ); -char *lp_lpqcommand(int ); -char *lp_lprmcommand(int ); -char *lp_lppausecommand(int ); -char *lp_lpresumecommand(int ); -char *lp_queuepausecommand(int ); -char *lp_queueresumecommand(int ); -char *lp_printername(int ); -char *lp_printerdriver(int ); -char *lp_hostsallow(int ); -char *lp_hostsdeny(int ); -char *lp_magicscript(int ); -char *lp_magicoutput(int ); -char *lp_comment(int ); -char *lp_force_user(int ); -char *lp_force_group(int ); -char *lp_readlist(int ); -char *lp_writelist(int ); -char *lp_fstype(int ); -char *lp_mangled_map(int ); -char *lp_veto_files(int ); -char *lp_hide_files(int ); -char *lp_veto_oplocks(int ); -char *lp_driverlocation(int ); -BOOL lp_revalidate(int ); -BOOL lp_casesensitive(int ); -BOOL lp_preservecase(int ); -BOOL lp_shortpreservecase(int ); -BOOL lp_casemangle(int ); -BOOL lp_status(int ); -BOOL lp_hide_dot_files(int ); -BOOL lp_browseable(int ); -BOOL lp_readonly(int ); -BOOL lp_no_set_dir(int ); -BOOL lp_guest_ok(int ); -BOOL lp_guest_only(int ); -BOOL lp_print_ok(int ); -BOOL lp_postscript(int ); -BOOL lp_map_hidden(int ); -BOOL lp_map_archive(int ); -BOOL lp_locking(int ); -BOOL lp_strict_locking(int ); -BOOL lp_share_modes(int ); -BOOL lp_oplocks(int ); -BOOL lp_onlyuser(int ); -BOOL lp_manglednames(int ); -BOOL lp_widelinks(int ); -BOOL lp_symlinks(int ); -BOOL lp_syncalways(int ); -BOOL lp_strict_sync(int ); -BOOL lp_map_system(int ); -BOOL lp_delete_readonly(int ); -BOOL lp_fake_oplocks(int ); -BOOL lp_recursive_veto_delete(int ); -BOOL lp_dos_filetimes(int ); -BOOL lp_dos_filetime_resolution(int ); -BOOL lp_fake_dir_create_times(int ); -BOOL lp_blocking_locks(int ); -BOOL lp_mangle_locks(int ); -int lp_create_mode(int ); -int lp_force_create_mode(int ); -int lp_dir_mode(int ); -int lp_force_dir_mode(int ); -int lp_max_connections(int ); -int lp_defaultcase(int ); -int lp_minprintspace(int ); -int lp_printing(int ); -int lp_oplock_contention_limit(int ); -char lp_magicchar(int ); -BOOL lp_add_home(const char *pszHomename, int iDefaultService, const char *pszHomedir); -int lp_add_service(char *pszService, int iDefaultService); -BOOL lp_add_printer(char *pszPrintername, int iDefaultService); -BOOL lp_file_list_changed(void); -void *lp_local_ptr(int snum, void *ptr); -BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue); -BOOL lp_is_default(int snum, struct parm_struct *parm); -struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters); -BOOL lp_snum_ok(int iService); -void lp_add_one_printer(char *name,char *comment); -BOOL lp_loaded(void); -void lp_killunused(BOOL (*snumused)(int )); -BOOL lp_load(const char *pszFname,BOOL global_only, BOOL save_defaults, BOOL add_ipc); -void lp_resetnumservices(void); -int lp_numservices(void); -int lp_servicenumber(const char *pszServiceName); -char *volume_label(int snum); -int lp_default_server_announce(void); -int lp_major_announce_version(void); -int lp_minor_announce_version(void); -void lp_set_name_resolve_order(char *new_order); -void lp_set_kernel_oplocks(BOOL val); -BOOL lp_kernel_oplocks(void); - -/* The following definitions come from param/params.c */ - -BOOL pm_process( const char *FileName, - BOOL (*sfunc)(const char *), - BOOL (*pfunc)(const char *, const char *) ); -#endif /* _PROTO_H_ */ +#ifndef _PROTO_H_ +#define _PROTO_H_ +/* This file is automatically generated with "make proto". DO NOT EDIT */ + +/* The following definitions come from lib/charcnv.c */ + +char *unix2dos_format (char *str, BOOL overwrite); +char *dos2unix_format (char *str, BOOL overwrite); +void interpret_character_set (const char *str); + +/* The following definitions come from lib/charset.c */ + +void charset_initialise (void); +void codepage_initialise (int client_codepage); +void add_char_string (const char *s); + +/* The following definitions come from lib/debug.c */ + +void setup_logging (const char *pname, BOOL interactive); +void dbgflush (void); +BOOL dbghdr (int level, const char *file, const char *func, int line); + +/* The following definitions come from lib/interface.c */ + +void load_interfaces (void); +void iface_set_default (char *ip, char *bcast, char *nmask); +BOOL ismyip (struct in_addr ip); +BOOL is_local_net (struct in_addr from); +int iface_count (void); +BOOL we_are_multihomed (void); +struct interface *get_interface (int n); +struct in_addr *iface_n_ip (int n); +unsigned iface_hash (void); +struct in_addr *iface_bcast (struct in_addr ip); +struct in_addr *iface_ip (struct in_addr ip); + +/* The following definitions come from lib/kanji.c */ + +void interpret_coding_system (const char *str); +BOOL is_multibyte_codepage (void); +void initialize_multibyte_vectors (int client_codepage); + +/* The following definitions come from lib/md4.c */ + +void mdfour (unsigned char *out, unsigned char *in, int n); + +/* The following definitions come from lib/netmask.c */ + +int get_netmask (struct in_addr *ipaddr, struct in_addr *nmask); + +/* The following definitions come from lib/slprintf.c */ + +int vslprintf (char *str, int n, const char *format, va_list ap); + +/* The following definitions come from lib/system.c */ + +int sys_select (int maxfd, fd_set * fds, struct timeval *tval); +int sys_stat (const char *fname, SMB_STRUCT_STAT * sbuf); +int sys_lstat (const char *fname, SMB_STRUCT_STAT * sbuf); +int sys_fseek (FILE * fp, SMB_OFF_T offset, int whence); +SMB_OFF_T sys_ftell (FILE * fp); +int sys_open (const char *path, int oflag, mode_t mode); +FILE *sys_fopen (const char *path, const char *type); +SMB_STRUCT_DIRENT *sys_readdir (DIR * dirp); +char *sys_getwd (char *s); +int sys_chown (const char *fname, uid_t uid, gid_t gid); +struct hostent *sys_gethostbyname (const char *name); +long sys_random (void); +void sys_srandom (unsigned int seed); + +/* The following definitions come from lib/time.c */ + +void GetTimeOfDay (struct timeval *tval); +void TimeInit (void); +int TimeDiff (time_t t); +struct tm *LocalTime (time_t * t); +time_t nt_time_to_unix (NTTIME * nt); +time_t interpret_long_date (char *p); +void unix_to_nt_time (NTTIME * nt, time_t t); +void put_long_date (char *p, time_t t); +BOOL null_mtime (time_t mtime); +void put_dos_date (char *buf, int offset, time_t unixdate); +void put_dos_date2 (char *buf, int offset, time_t unixdate); +void put_dos_date3 (char *buf, int offset, time_t unixdate); +time_t make_unix_date (void *date_ptr); +time_t make_unix_date2 (void *date_ptr); +time_t make_unix_date3 (void *date_ptr); +char *http_timestring (time_t t); +char *timestring (void); +time_t get_create_time (SMB_STRUCT_STAT * st, BOOL fake_dirs); + +/* The following definitions come from lib/username.c */ + +const char *get_home_dir (char *user); +BOOL map_username (const char *user); +struct passwd *Get_Pwnam (const char *user); +BOOL user_in_list (const char *user, char *list); + +/* The following definitions come from lib/util.c */ + +const char *tmpdir (void); +BOOL in_group (gid_t group, gid_t current_gid, int ngroups, gid_t * groups); +char *Atoic (char *p, int *n, char *c); +char *get_numlist (char *p, uint32 ** num, int *count); +void putip (void *dest, void *src); +char *dns_to_netbios_name (char *dns_name); +int name_mangle (char *In, char *Out, char name_type); +BOOL file_exist (char *fname, SMB_STRUCT_STAT * sbuf); +time_t file_modtime (char *fname); +BOOL directory_exist (char *dname, SMB_STRUCT_STAT * st); +SMB_OFF_T file_size (char *file_name); +char *attrib_string (uint16 mode); +void unix_format (char *fname); +void dos_format (char *fname); +void show_msg (char *buf); +int smb_len (char *buf); +void _smb_setlen (char *buf, int len); +void smb_setlen (char *buf, int len); +int set_message (char *buf, int num_words, int num_bytes, BOOL zero); +int smb_buflen (char *buf); +char *smb_buf (char *buf); +int smb_offset (char *p, char *buf); +void dos_clean_name (char *s); +void unix_clean_name (char *s); +BOOL reduce_name (char *s, char *dir, BOOL widelinks); +void expand_mask (char *Mask, BOOL doext); +void make_dir_struct (char *buf, char *mask, char *fname, SMB_OFF_T size, int mode, time_t date); +void close_low_fds (void); +int set_blocking (int fd, BOOL set); +int TvalDiff (struct timeval *tvalold, struct timeval *tvalnew); +SMB_OFF_T transfer_file (int infd, int outfd, SMB_OFF_T n, char *header, int headlen, int align); +int name_extract (char *buf, int ofs, char *name); +int name_len (char *s1); +void msleep (int t); +BOOL do_match (char *str, char *regexp, int case_sig); +BOOL mask_match (char *str, char *regexp, int case_sig, BOOL trans2); +int set_filelen (int fd, SMB_OFF_T len); +void *Realloc (void *p, size_t size); +BOOL get_myname (char *my_name, struct in_addr *ip); +BOOL ip_equal (struct in_addr ip1, struct in_addr ip2); +int interpret_protocol (char *str, int def); +uint32 interpret_addr (const char *str); +struct in_addr *interpret_addr2 (const char *str); +BOOL zero_ip (struct in_addr ip); +BOOL matchname (char *remotehost, struct in_addr addr); +void standard_sub_basic (char *str); +void standard_sub (connection_struct * conn, char *str); +BOOL same_net (struct in_addr ip1, struct in_addr ip2, struct in_addr mask); +struct hostent *Get_Hostbyname (const char *name); +char *uidtoname (uid_t uid); +char *gidtoname (gid_t gid); +uid_t nametouid (const char *name); +void smb_panic (const char *why); +char *readdirname (DIR * p); +BOOL is_in_path (char *name, name_compare_entry * namelist); +void set_namearray (name_compare_entry ** ppname_array, char *namelist); +void free_namearray (name_compare_entry * name_array); +BOOL fcntl_lock (int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type); +BOOL is_myname (char *s); +void set_remote_arch (enum remote_arch_types type); +enum remote_arch_types get_remote_arch (void); +char *align2 (char *q, char *base); +void out_ascii (FILE * f, unsigned char *buf, int len); +void out_data (FILE * f, char *buf1, int len, int per_line); +void print_asc (int level, unsigned char *buf, int len); +void dump_data (int level, char *buf1, int len); +char *tab_depth (int depth); +int str_checksum (const char *s); +void zero_free (void *p, size_t size); +int set_maxfiles (int requested_max); + +/* The following definitions come from lib/util_file.c */ + +BOOL do_file_lock (int fd, int waitsecs, int type); +BOOL file_lock (int fd, int type, int secs, int *plock_depth); +BOOL file_unlock (int fd, int *plock_depth); +void *startfilepwent (char *pfile, char *s_readbuf, int bufsize, int *file_lock_depth, BOOL update); +void endfilepwent (void *vp, int *file_lock_depth); +SMB_BIG_UINT getfilepwpos (void *vp); +BOOL setfilepwpos (void *vp, SMB_BIG_UINT tok); +int getfileline (void *vp, char *linebuf, int linebuf_size); +char *fgets_slash (char *s2, int maxlen, FILE * f); + +/* The following definitions come from lib/util_sock.c */ + +BOOL is_a_socket (int fd); +void set_socket_options (int fd, char *options); +void close_sockets (void); +ssize_t write_socket (int fd, char *buf, size_t len); +ssize_t read_udp_socket (int fd, char *buf, size_t len); +ssize_t read_with_timeout (int fd, char *buf, size_t mincnt, size_t maxcnt, unsigned int time_out); +BOOL send_keepalive (int client); +ssize_t read_data (int fd, char *buffer, size_t N); +ssize_t write_data (int fd, char *buffer, size_t N); +ssize_t read_smb_length (int fd, char *inbuf, unsigned int timeout); +BOOL receive_smb (int fd, char *buffer, unsigned int timeout); +BOOL client_receive_smb (int fd, char *buffer, unsigned int timeout); +BOOL send_null_session_msg (int fd); +BOOL send_smb (int fd, char *buffer); +BOOL send_one_packet (char *buf, int len, struct in_addr ip, int port, int type); +int open_socket_in (int type, int port, int dlevel, uint32 socket_addr, BOOL rebind); +int open_socket_out (int type, struct in_addr *addr, int port, int timeout); +char *client_name (int fd); +char *client_addr (int fd); + +/* The following definitions come from lib/util_str.c */ + +void set_first_token (char *ptr); +BOOL next_token (char **ptr, char *buff, const char *sep, size_t bufsize); +char **toktocliplist (int *ctok, char *sep); +int StrCaseCmp (const char *s, const char *t); +int StrnCaseCmp (const char *s, const char *t, size_t n); +BOOL strequal (const char *s1, const char *s2); +BOOL strnequal (const char *s1, const char *s2, size_t n); +BOOL strcsequal (const char *s1, const char *s2); +void strlower (char *s); +void strupper (char *s); +void strnorm (char *s); +BOOL strisnormal (char *s); +void string_replace (char *s, char oldc, char newc); +char *skip_string (char *buf, size_t n); +size_t str_charnum (const char *s); +BOOL trim_string (char *s, const char *front, const char *back); +BOOL strhasupper (const char *s); +BOOL strhaslower (const char *s); +size_t count_chars (const char *s, char c); +char *safe_strcpy (char *dest, const char *src, size_t maxlength); +char *safe_strcat (char *dest, const char *src, size_t maxlength); +char *StrCpy (char *dest, const char *src); +char *StrnCpy (char *dest, const char *src, size_t n); +char *strncpyn (char *dest, const char *src, size_t n, char c); +size_t strhex_to_str (char *p, size_t len, const char *strhex); +BOOL in_list (char *s, char *list, BOOL casesensitive); +BOOL string_init (char **dest, const char *src); +void string_free (char **s); +BOOL string_set (char **dest, const char *src); +void string_sub (char *s, const char *pattern, const char *insert); +void all_string_sub (char *s, const char *pattern, const char *insert); +void split_at_last_component (char *path, char *front, char sep, char *back); + +/* The following definitions come from libsmb/clientgen.c */ + +int cli_set_port (struct cli_state *cli, int port); +char *cli_errstr (struct cli_state *cli); +BOOL cli_api_pipe (struct cli_state *cli, char *pipe_name, int pipe_name_len, + uint16 * setup, uint32 setup_count, uint32 max_setup_count, + char *params, uint32 param_count, uint32 max_param_count, + char *data, uint32 data_count, uint32 max_data_count, + char **rparam, uint32 * rparam_count, char **rdata, uint32 * rdata_count); +BOOL cli_api (struct cli_state *cli, + char *param, int prcnt, int mprcnt, + char *data, int drcnt, int mdrcnt, + char **rparam, int *rprcnt, char **rdata, int *rdrcnt); +BOOL cli_NetWkstaUserLogon (struct cli_state *cli, char *user, char *workstation); +int cli_RNetShareEnum (struct cli_state *cli, + void (*fn) (const char *, uint32, const char *, void *), void *state); +BOOL cli_NetServerEnum (struct cli_state *cli, char *workgroup, uint32 stype, + void (*fn) (const char *, uint32, const char *, void *), void *state); +BOOL cli_session_setup (struct cli_state *cli, char *user, char *pass, int passlen, char *ntpass, + int ntpasslen, char *workgroup); +BOOL cli_ulogoff (struct cli_state *cli); +BOOL cli_send_tconX (struct cli_state *cli, + const char *share, const char *dev, const char *pass, int passlen); +BOOL cli_tdis (struct cli_state *cli); +BOOL cli_rename (struct cli_state *cli, char *fname_src, char *fname_dst); +BOOL cli_unlink (struct cli_state *cli, char *fname); +BOOL cli_mkdir (struct cli_state *cli, char *dname); +BOOL cli_rmdir (struct cli_state *cli, char *dname); +int cli_nt_create (struct cli_state *cli, char *fname); +int cli_open (struct cli_state *cli, char *fname, int flags, int share_mode); +BOOL cli_close (struct cli_state *cli, int fnum); +BOOL cli_lock (struct cli_state *cli, int fnum, uint32 offset, uint32 len, int timeout); +BOOL cli_unlock (struct cli_state *cli, int fnum, uint32 offset, uint32 len, int timeout); +size_t cli_read (struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size); +ssize_t cli_write (struct cli_state *cli, + int fnum, uint16 write_mode, const char *buf, off_t offset, size_t size); +ssize_t cli_smbwrite (struct cli_state *cli, int fnum, const char *buf, off_t offset, size_t size); +BOOL cli_getattrE (struct cli_state *cli, int fd, + uint16 * attr, size_t * size, time_t * c_time, time_t * a_time, time_t * m_time); +BOOL cli_getatr (struct cli_state *cli, char *fname, uint16 * attr, size_t * size, time_t * t); +BOOL cli_setatr (struct cli_state *cli, char *fname, uint16 attr, time_t t); +BOOL cli_qpathinfo (struct cli_state *cli, const char *fname, + time_t * c_time, time_t * a_time, time_t * m_time, + size_t * size, uint16 * mode); +BOOL cli_qpathinfo2 (struct cli_state *cli, const char *fname, + time_t * c_time, time_t * a_time, time_t * m_time, + time_t * w_time, size_t * size, uint16 * mode, SMB_INO_T * ino); +BOOL cli_qfileinfo (struct cli_state *cli, int fnum, + uint16 * mode, size_t * size, + time_t * c_time, time_t * a_time, time_t * m_time, + time_t * w_time, SMB_INO_T * ino); +int cli_list (struct cli_state *cli, const char *Mask, uint16 attribute, + void (*fn) (file_info *, const char *, void *), void *state); +BOOL cli_negprot (struct cli_state *cli); +BOOL cli_session_request (struct cli_state *cli, struct nmb_name *calling, struct nmb_name *called); +BOOL cli_connect (struct cli_state *cli, const char *host, struct in_addr *ip); +struct cli_state *cli_initialise (struct cli_state *cli); +void cli_shutdown (struct cli_state *cli); +int cli_error (struct cli_state *cli, uint8 * eclass, uint32 * num, uint32 * nt_rpc_error); +void cli_sockopt (struct cli_state *cli, char *options); +uint16 cli_setpid (struct cli_state *cli, uint16 pid); +BOOL cli_reestablish_connection (struct cli_state *cli); +BOOL cli_establish_connection (struct cli_state *cli, + char *dest_host, struct in_addr *dest_ip, + struct nmb_name *calling, struct nmb_name *called, + char *service, char *service_type, BOOL do_shutdown, BOOL do_tcon); +BOOL cli_chkpath (struct cli_state *cli, char *path); +BOOL cli_message_start (struct cli_state *cli, char *host, char *username, int *grp); +BOOL cli_message_text (struct cli_state *cli, char *msg, int len, int grp); +BOOL cli_message_end (struct cli_state *cli, int grp); +BOOL cli_dskattr (struct cli_state *cli, int *bsize, int *total, int *avail); + +/* The following definitions come from libsmb/namequery.c */ + +struct in_addr *name_query (int fd, const char *name, int name_type, BOOL bcast, BOOL recurse, + struct in_addr to_ip, int *count, void (*fn) (struct packet_struct *)); +FILE *startlmhosts (const char *fname); +BOOL getlmhostsent (FILE * fp, pstring name, int *name_type, struct in_addr *ipaddr); +void endlmhosts (FILE * fp); +BOOL resolve_name (const char *name, struct in_addr *return_ip, int name_type); +BOOL find_master_ip (char *group, struct in_addr *master_ip); + +/* The following definitions come from libsmb/nmblib.c */ + +void debug_nmb_packet (struct packet_struct *p); +char *nmb_namestr (struct nmb_name *n); +struct packet_struct *copy_packet (struct packet_struct *packet); +void free_packet (struct packet_struct *packet); +struct packet_struct *read_packet (int fd, enum packet_type packet_type); +void make_nmb_name (struct nmb_name *n, const char *name, int type); +BOOL nmb_name_equal (struct nmb_name *n1, struct nmb_name *n2); +BOOL send_packet (struct packet_struct *p); +struct packet_struct *receive_packet (int fd, enum packet_type type, int t); +void sort_query_replies (char *data, int n, struct in_addr ip); + +/* The following definitions come from libsmb/nterr.c */ + +const char *get_nt_error_msg (uint32 nt_code); + +/* The following definitions come from libsmb/pwd_cache.c */ + +void pwd_init (struct pwd_info *pwd); +void pwd_obfuscate_key (struct pwd_info *pwd, uint32 int_key, char *str_key); +void pwd_read (struct pwd_info *pwd, char *passwd_report, BOOL do_encrypt); +void pwd_set_nullpwd (struct pwd_info *pwd); +void pwd_set_cleartext (struct pwd_info *pwd, char *clr); +void pwd_get_cleartext (struct pwd_info *pwd, char *clr); +void pwd_set_lm_nt_16 (struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]); +void pwd_get_lm_nt_16 (struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]); +void pwd_make_lm_nt_16 (struct pwd_info *pwd, char *clr); +void pwd_make_lm_nt_owf (struct pwd_info *pwd, uchar cryptkey[8]); +void pwd_get_lm_nt_owf (struct pwd_info *pwd, uchar lm_owf[24], uchar nt_owf[24]); + +/* The following definitions come from libsmb/smbdes.c */ + +void E_P16 (unsigned char *p14, unsigned char *p16); +void E_P24 (unsigned char *p21, unsigned char *c8, unsigned char *p24); +void D_P16 (unsigned char *p14, unsigned char *in, unsigned char *out); +void E_old_pw_hash (unsigned char *p14, unsigned char *in, unsigned char *out); +void cred_hash1 (unsigned char *out, unsigned char *in, unsigned char *key); +void cred_hash2 (unsigned char *out, unsigned char *in, unsigned char *key); +void cred_hash3 (unsigned char *out, unsigned char *in, unsigned char *key, int forw); +void SamOEMhash (unsigned char *data, unsigned char *key, int val); + +/* The following definitions come from libsmb/smbencrypt.c */ + +void SMBencrypt (uchar * passwd, uchar * c8, uchar * p24); +void E_md4hash (uchar * passwd, uchar * p16); +void nt_lm_owf_gen (char *pwd, uchar nt_p16[16], uchar p16[16]); +void SMBOWFencrypt (uchar passwd[16], uchar * c8, uchar p24[24]); +void NTLMSSPOWFencrypt (uchar passwd[8], uchar * ntlmchalresp, uchar p24[24]); +void SMBNTencrypt (uchar * passwd, uchar * c8, uchar * p24); + +/* The following definitions come from libsmb/smberr.c */ + +char *smb_errstr (char *inbuf); + +/* The following definitions come from param/loadparm.c */ + +char *lp_logfile (void); +char *lp_configfile (void); +char *lp_smb_passwd_file (void); +char *lp_serverstring (void); +char *lp_printcapname (void); +char *lp_lockdir (void); +char *lp_rootdir (void); +char *lp_defaultservice (void); +char *lp_msg_command (void); +char *lp_hosts_equiv (void); +char *lp_auto_services (void); +char *lp_passwd_program (void); +char *lp_passwd_chat (void); +char *lp_passwordserver (void); +char *lp_name_resolve_order (void); +char *lp_workgroup (void); +char *lp_username_map (void); +char *lp_groupname_map (void); +char *lp_logon_script (void); +char *lp_logon_path (void); +char *lp_logon_drive (void); +char *lp_logon_home (void); +char *lp_remote_announce (void); +char *lp_remote_browse_sync (void); +char *lp_wins_server (void); +char *lp_interfaces (void); +char *lp_socket_address (void); +char *lp_nis_home_map_name (void); +char *lp_netbios_aliases (void); +char *lp_driverfile (void); +char *lp_panic_action (void); +char *lp_adduser_script (void); +char *lp_deluser_script (void); +char *lp_domain_groups (void); +char *lp_domain_admin_group (void); +char *lp_domain_guest_group (void); +char *lp_domain_admin_users (void); +char *lp_domain_guest_users (void); +char *lp_ldap_server (void); +char *lp_ldap_suffix (void); +char *lp_ldap_filter (void); +char *lp_ldap_root (void); +char *lp_ldap_rootpasswd (void); +int lp_ssl_version (void); +char *lp_ssl_hosts (void); +char *lp_ssl_hosts_resign (void); +char *lp_ssl_cacertdir (void); +char *lp_ssl_cacertfile (void); +char *lp_ssl_cert (void); +char *lp_ssl_privkey (void); +char *lp_ssl_client_cert (void); +char *lp_ssl_client_privkey (void); +char *lp_ssl_ciphers (void); +BOOL lp_ssl_enabled (void); +BOOL lp_ssl_reqClientCert (void); +BOOL lp_ssl_reqServerCert (void); +BOOL lp_ssl_compatibility (void); +BOOL lp_dns_proxy (void); +BOOL lp_wins_support (void); +BOOL lp_we_are_a_wins_server (void); +BOOL lp_wins_proxy (void); +BOOL lp_local_master (void); +BOOL lp_domain_master (void); +BOOL lp_domain_logons (void); +BOOL lp_preferred_master (void); +BOOL lp_load_printers (void); +BOOL lp_use_rhosts (void); +BOOL lp_readprediction (void); +BOOL lp_readbmpx (void); +BOOL lp_readraw (void); +BOOL lp_writeraw (void); +BOOL lp_null_passwords (void); +BOOL lp_strip_dot (void); +BOOL lp_encrypted_passwords (void); +BOOL lp_update_encrypted (void); +BOOL lp_syslog_only (void); +BOOL lp_timestamp_logs (void); +BOOL lp_browse_list (void); +BOOL lp_unix_realname (void); +BOOL lp_nis_home_map (void); +BOOL lp_bind_interfaces_only (void); +BOOL lp_unix_password_sync (void); +BOOL lp_passwd_chat_debug (void); +BOOL lp_ole_locking_compat (void); +BOOL lp_nt_smb_support (void); +BOOL lp_nt_pipe_support (void); +BOOL lp_nt_acl_support (void); +BOOL lp_stat_cache (void); +BOOL lp_allow_trusted_domains (void); +BOOL lp_restrict_anonymous (void); +int lp_os_level (void); +int lp_max_ttl (void); +int lp_max_wins_ttl (void); +int lp_min_wins_ttl (void); +int lp_max_open_files (void); +int lp_maxxmit (void); +int lp_maxmux (void); +int lp_passwordlevel (void); +int lp_usernamelevel (void); +int lp_readsize (void); +int lp_shmem_size (void); +int lp_deadtime (void); +int lp_maxprotocol (void); +int lp_security (void); +int lp_maxdisksize (void); +int lp_lpqcachetime (void); +int lp_syslog (void); +int lp_client_code_page (void); +int lp_lm_announce (void); +int lp_lm_interval (void); +int lp_machine_password_timeout (void); +int lp_change_notify_timeout (void); +int lp_stat_cache_size (void); +int lp_map_to_guest (void); +int lp_min_passwd_length (void); +int lp_oplock_break_wait_time (void); +int lp_ldap_port (void); +char *lp_preexec (int); +char *lp_postexec (int); +char *lp_rootpreexec (int); +char *lp_rootpostexec (int); +char *lp_servicename (int); +char *lp_pathname (int); +char *lp_dontdescend (int); +char *lp_username (int); +char *lp_guestaccount (int); +char *lp_invalid_users (int); +char *lp_valid_users (int); +char *lp_admin_users (int); +char *lp_printcommand (int); +char *lp_lpqcommand (int); +char *lp_lprmcommand (int); +char *lp_lppausecommand (int); +char *lp_lpresumecommand (int); +char *lp_queuepausecommand (int); +char *lp_queueresumecommand (int); +char *lp_printername (int); +char *lp_printerdriver (int); +char *lp_hostsallow (int); +char *lp_hostsdeny (int); +char *lp_magicscript (int); +char *lp_magicoutput (int); +char *lp_comment (int); +char *lp_force_user (int); +char *lp_force_group (int); +char *lp_readlist (int); +char *lp_writelist (int); +char *lp_fstype (int); +char *lp_mangled_map (int); +char *lp_veto_files (int); +char *lp_hide_files (int); +char *lp_veto_oplocks (int); +char *lp_driverlocation (int); +BOOL lp_revalidate (int); +BOOL lp_casesensitive (int); +BOOL lp_preservecase (int); +BOOL lp_shortpreservecase (int); +BOOL lp_casemangle (int); +BOOL lp_status (int); +BOOL lp_hide_dot_files (int); +BOOL lp_browseable (int); +BOOL lp_readonly (int); +BOOL lp_no_set_dir (int); +BOOL lp_guest_ok (int); +BOOL lp_guest_only (int); +BOOL lp_print_ok (int); +BOOL lp_postscript (int); +BOOL lp_map_hidden (int); +BOOL lp_map_archive (int); +BOOL lp_locking (int); +BOOL lp_strict_locking (int); +BOOL lp_share_modes (int); +BOOL lp_oplocks (int); +BOOL lp_onlyuser (int); +BOOL lp_manglednames (int); +BOOL lp_widelinks (int); +BOOL lp_symlinks (int); +BOOL lp_syncalways (int); +BOOL lp_strict_sync (int); +BOOL lp_map_system (int); +BOOL lp_delete_readonly (int); +BOOL lp_fake_oplocks (int); +BOOL lp_recursive_veto_delete (int); +BOOL lp_dos_filetimes (int); +BOOL lp_dos_filetime_resolution (int); +BOOL lp_fake_dir_create_times (int); +BOOL lp_blocking_locks (int); +BOOL lp_mangle_locks (int); +int lp_create_mode (int); +int lp_force_create_mode (int); +int lp_dir_mode (int); +int lp_force_dir_mode (int); +int lp_max_connections (int); +int lp_defaultcase (int); +int lp_minprintspace (int); +int lp_printing (int); +int lp_oplock_contention_limit (int); +char lp_magicchar (int); +BOOL lp_add_home (const char *pszHomename, int iDefaultService, const char *pszHomedir); +int lp_add_service (char *pszService, int iDefaultService); +BOOL lp_add_printer (char *pszPrintername, int iDefaultService); +BOOL lp_file_list_changed (void); +void *lp_local_ptr (int snum, void *ptr); +BOOL lp_do_parameter (int snum, const char *pszParmName, const char *pszParmValue); +BOOL lp_is_default (int snum, struct parm_struct *parm); +struct parm_struct *lp_next_parameter (int snum, int *i, int allparameters); +BOOL lp_snum_ok (int iService); +void lp_add_one_printer (char *name, char *comment); +BOOL lp_loaded (void); +void lp_killunused (BOOL (*snumused) (int)); +BOOL lp_load (const char *pszFname, BOOL global_only, BOOL save_defaults, BOOL add_ipc); +void lp_resetnumservices (void); +int lp_numservices (void); +int lp_servicenumber (const char *pszServiceName); +char *volume_label (int snum); +int lp_default_server_announce (void); +int lp_major_announce_version (void); +int lp_minor_announce_version (void); +void lp_set_name_resolve_order (char *new_order); +void lp_set_kernel_oplocks (BOOL val); +BOOL lp_kernel_oplocks (void); + +/* The following definitions come from param/params.c */ + +BOOL pm_process (const char *FileName, + BOOL (*sfunc) (const char *), BOOL (*pfunc) (const char *, const char *)); +#endif /* _PROTO_H_ */ diff --git a/src/vfs/smbfs/helpers/include/smb.h b/src/vfs/smbfs/helpers/include/smb.h index 5db911d75..ea98e19da 100644 --- a/src/vfs/smbfs/helpers/include/smb.h +++ b/src/vfs/smbfs/helpers/include/smb.h @@ -2,7 +2,7 @@ Unix SMB/Netbios implementation. Version 1.9. SMB parameters and setup -*/ + */ #ifndef _SMB_H #define _SMB_H @@ -51,19 +51,20 @@ typedef int BOOL; arguemnts to DEBUG() right. We have got them wrong too often in the past */ #ifdef HAVE_STDARG_H -int Debug1( const char *, ... ) +int +Debug1 (const char *, ...) #ifdef __GNUC__ - __attribute__ ((format (printf, 1, 2))) + __attribute__ ((format (printf, 1, 2))) #endif -; -BOOL dbgtext( const char *, ... ) + ; + BOOL dbgtext (const char *, ...) #ifdef __GNUC__ - __attribute__ ((format (printf, 1, 2))) + __attribute__ ((format (printf, 1, 2))) #endif -; + ; #else -int Debug1(); -BOOL dbgtext(); +int Debug1 (); +BOOL dbgtext (); #endif /* If we have these macros, we can add additional info to the header. */ @@ -136,8 +137,8 @@ BOOL dbgtext(); #define DIR_STRUCT_SIZE 43 /* these define all the command types recognised by the server - there -are lots of gaps so probably there are some rare commands that are not -implemented */ + are lots of gaps so probably there are some rare commands that are not + implemented */ #define pSETDIR '\377' @@ -211,104 +212,104 @@ implemented */ #define GET_FILE_CREATE_DISPOSITION(x) ((x) & (FILE_CREATE_IF_NOT_EXIST|FILE_FAIL_IF_NOT_EXIST)) /* share types */ -#define STYPE_DISKTREE 0 /* Disk drive */ -#define STYPE_PRINTQ 1 /* Spooler queue */ -#define STYPE_DEVICE 2 /* Serial device */ -#define STYPE_IPC 3 /* Interprocess communication (IPC) */ -#define STYPE_HIDDEN 0x80000000 /* share is a hidden one (ends with $) */ +#define STYPE_DISKTREE 0 /* Disk drive */ +#define STYPE_PRINTQ 1 /* Spooler queue */ +#define STYPE_DEVICE 2 /* Serial device */ +#define STYPE_IPC 3 /* Interprocess communication (IPC) */ +#define STYPE_HIDDEN 0x80000000 /* share is a hidden one (ends with $) */ /* SMB X/Open error codes for the ERRDOS error class */ -#define ERRbadfunc 1 /* Invalid function (or system call) */ -#define ERRbadfile 2 /* File not found (pathname error) */ -#define ERRbadpath 3 /* Directory not found */ -#define ERRnofids 4 /* Too many open files */ -#define ERRnoaccess 5 /* Access denied */ -#define ERRbadfid 6 /* Invalid fid */ -#define ERRnomem 8 /* Out of memory */ -#define ERRbadmem 9 /* Invalid memory block address */ -#define ERRbadenv 10 /* Invalid environment */ -#define ERRbadaccess 12 /* Invalid open mode */ -#define ERRbaddata 13 /* Invalid data (only from ioctl call) */ -#define ERRres 14 /* reserved */ -#define ERRbaddrive 15 /* Invalid drive */ -#define ERRremcd 16 /* Attempt to delete current directory */ -#define ERRdiffdevice 17 /* rename/move across different filesystems */ -#define ERRnofiles 18 /* no more files found in file search */ -#define ERRbadshare 32 /* Share mode on file conflict with open mode */ -#define ERRlock 33 /* Lock request conflicts with existing lock */ -#define ERRunsup 50 /* Request unsupported, returned by Win 95, RJS 20Jun98 */ -#define ERRfilexists 80 /* File in operation already exists */ -#define ERRcannotopen 110 /* Cannot open the file specified */ +#define ERRbadfunc 1 /* Invalid function (or system call) */ +#define ERRbadfile 2 /* File not found (pathname error) */ +#define ERRbadpath 3 /* Directory not found */ +#define ERRnofids 4 /* Too many open files */ +#define ERRnoaccess 5 /* Access denied */ +#define ERRbadfid 6 /* Invalid fid */ +#define ERRnomem 8 /* Out of memory */ +#define ERRbadmem 9 /* Invalid memory block address */ +#define ERRbadenv 10 /* Invalid environment */ +#define ERRbadaccess 12 /* Invalid open mode */ +#define ERRbaddata 13 /* Invalid data (only from ioctl call) */ +#define ERRres 14 /* reserved */ +#define ERRbaddrive 15 /* Invalid drive */ +#define ERRremcd 16 /* Attempt to delete current directory */ +#define ERRdiffdevice 17 /* rename/move across different filesystems */ +#define ERRnofiles 18 /* no more files found in file search */ +#define ERRbadshare 32 /* Share mode on file conflict with open mode */ +#define ERRlock 33 /* Lock request conflicts with existing lock */ +#define ERRunsup 50 /* Request unsupported, returned by Win 95, RJS 20Jun98 */ +#define ERRfilexists 80 /* File in operation already exists */ +#define ERRcannotopen 110 /* Cannot open the file specified */ #define ERRunknownlevel 124 #define ERRrename 183 -#define ERRbadpipe 230 /* Named pipe invalid */ -#define ERRpipebusy 231 /* All instances of pipe are busy */ -#define ERRpipeclosing 232 /* named pipe close in progress */ -#define ERRnotconnected 233 /* No process on other end of named pipe */ -#define ERRmoredata 234 /* More data to be returned */ -#define ERRbaddirectory 267 /* Invalid directory name in a path. */ +#define ERRbadpipe 230 /* Named pipe invalid */ +#define ERRpipebusy 231 /* All instances of pipe are busy */ +#define ERRpipeclosing 232 /* named pipe close in progress */ +#define ERRnotconnected 233 /* No process on other end of named pipe */ +#define ERRmoredata 234 /* More data to be returned */ +#define ERRbaddirectory 267 /* Invalid directory name in a path. */ #define ERROR_EAS_DIDNT_FIT 275 /* Extended attributes didn't fit */ -#define ERROR_EAS_NOT_SUPPORTED 282 /* Extended attributes not supported */ -#define ERROR_NOTIFY_ENUM_DIR 1022 /* Buffer too small to return change notify. */ +#define ERROR_EAS_NOT_SUPPORTED 282 /* Extended attributes not supported */ +#define ERROR_NOTIFY_ENUM_DIR 1022 /* Buffer too small to return change notify. */ #define ERRunknownipc 2142 /* here's a special one from observing NT */ -#define ERRnoipc 66 /* don't support ipc */ +#define ERRnoipc 66 /* don't support ipc */ /* Error codes for the ERRSRV class */ -#define ERRerror 1 /* Non specific error code */ -#define ERRbadpw 2 /* Bad password */ -#define ERRbadtype 3 /* reserved */ -#define ERRaccess 4 /* No permissions to do the requested operation */ -#define ERRinvnid 5 /* tid invalid */ -#define ERRinvnetname 6 /* Invalid servername */ -#define ERRinvdevice 7 /* Invalid device */ -#define ERRqfull 49 /* Print queue full */ -#define ERRqtoobig 50 /* Queued item too big */ -#define ERRinvpfid 52 /* Invalid print file in smb_fid */ -#define ERRsmbcmd 64 /* Unrecognised command */ -#define ERRsrverror 65 /* smb server internal error */ -#define ERRfilespecs 67 /* fid and pathname invalid combination */ -#define ERRbadlink 68 /* reserved */ -#define ERRbadpermits 69 /* Access specified for a file is not valid */ -#define ERRbadpid 70 /* reserved */ -#define ERRsetattrmode 71 /* attribute mode invalid */ -#define ERRpaused 81 /* Message server paused */ -#define ERRmsgoff 82 /* Not receiving messages */ -#define ERRnoroom 83 /* No room for message */ -#define ERRrmuns 87 /* too many remote usernames */ -#define ERRtimeout 88 /* operation timed out */ -#define ERRnoresource 89 /* No resources currently available for request. */ -#define ERRtoomanyuids 90 /* too many userids */ -#define ERRbaduid 91 /* bad userid */ -#define ERRuseMPX 250 /* temporarily unable to use raw mode, use MPX mode */ -#define ERRuseSTD 251 /* temporarily unable to use raw mode, use standard mode */ -#define ERRcontMPX 252 /* resume MPX mode */ -#define ERRbadPW /* reserved */ +#define ERRerror 1 /* Non specific error code */ +#define ERRbadpw 2 /* Bad password */ +#define ERRbadtype 3 /* reserved */ +#define ERRaccess 4 /* No permissions to do the requested operation */ +#define ERRinvnid 5 /* tid invalid */ +#define ERRinvnetname 6 /* Invalid servername */ +#define ERRinvdevice 7 /* Invalid device */ +#define ERRqfull 49 /* Print queue full */ +#define ERRqtoobig 50 /* Queued item too big */ +#define ERRinvpfid 52 /* Invalid print file in smb_fid */ +#define ERRsmbcmd 64 /* Unrecognised command */ +#define ERRsrverror 65 /* smb server internal error */ +#define ERRfilespecs 67 /* fid and pathname invalid combination */ +#define ERRbadlink 68 /* reserved */ +#define ERRbadpermits 69 /* Access specified for a file is not valid */ +#define ERRbadpid 70 /* reserved */ +#define ERRsetattrmode 71 /* attribute mode invalid */ +#define ERRpaused 81 /* Message server paused */ +#define ERRmsgoff 82 /* Not receiving messages */ +#define ERRnoroom 83 /* No room for message */ +#define ERRrmuns 87 /* too many remote usernames */ +#define ERRtimeout 88 /* operation timed out */ +#define ERRnoresource 89 /* No resources currently available for request. */ +#define ERRtoomanyuids 90 /* too many userids */ +#define ERRbaduid 91 /* bad userid */ +#define ERRuseMPX 250 /* temporarily unable to use raw mode, use MPX mode */ +#define ERRuseSTD 251 /* temporarily unable to use raw mode, use standard mode */ +#define ERRcontMPX 252 /* resume MPX mode */ +#define ERRbadPW /* reserved */ #define ERRnosupport 0xFFFF -#define ERRunknownsmb 22 /* from NT 3.5 response */ +#define ERRunknownsmb 22 /* from NT 3.5 response */ /* Error codes for the ERRHRD class */ -#define ERRnowrite 19 /* read only media */ -#define ERRbadunit 20 /* Unknown device */ -#define ERRnotready 21 /* Drive not ready */ -#define ERRbadcmd 22 /* Unknown command */ -#define ERRdata 23 /* Data (CRC) error */ -#define ERRbadreq 24 /* Bad request structure length */ +#define ERRnowrite 19 /* read only media */ +#define ERRbadunit 20 /* Unknown device */ +#define ERRnotready 21 /* Drive not ready */ +#define ERRbadcmd 22 /* Unknown command */ +#define ERRdata 23 /* Data (CRC) error */ +#define ERRbadreq 24 /* Bad request structure length */ #define ERRseek 25 #define ERRbadmedia 26 #define ERRbadsector 27 #define ERRnopaper 28 -#define ERRwrite 29 /* write fault */ -#define ERRread 30 /* read fault */ -#define ERRgeneral 31 /* General hardware failure */ +#define ERRwrite 29 /* write fault */ +#define ERRread 30 /* read fault */ +#define ERRgeneral 31 /* General hardware failure */ #define ERRwrongdisk 34 #define ERRFCBunavail 35 -#define ERRsharebufexc 36 /* share buffer exceeded */ +#define ERRsharebufexc 36 /* share buffer exceeded */ #define ERRdiskfull 39 @@ -331,98 +332,98 @@ typedef char fstring[128]; /* 64 bit time (100usec) since ????? - cifs6.txt, section 3.5, page 30 */ typedef struct nttime_info { - uint32 low; - uint32 high; + uint32 low; + uint32 high; } NTTIME; /* Allowable account control bits */ -#define ACB_DISABLED 0x0001 /* 1 = User account disabled */ -#define ACB_HOMDIRREQ 0x0002 /* 1 = Home directory required */ -#define ACB_PWNOTREQ 0x0004 /* 1 = User password not required */ -#define ACB_TEMPDUP 0x0008 /* 1 = Temporary duplicate account */ -#define ACB_NORMAL 0x0010 /* 1 = Normal user account */ -#define ACB_MNS 0x0020 /* 1 = MNS logon user account */ -#define ACB_DOMTRUST 0x0040 /* 1 = Interdomain trust account */ -#define ACB_WSTRUST 0x0080 /* 1 = Workstation trust account */ -#define ACB_SVRTRUST 0x0100 /* 1 = Server trust account */ -#define ACB_PWNOEXP 0x0200 /* 1 = User password does not expire */ -#define ACB_AUTOLOCK 0x0400 /* 1 = Account auto locked */ - +#define ACB_DISABLED 0x0001 /* 1 = User account disabled */ +#define ACB_HOMDIRREQ 0x0002 /* 1 = Home directory required */ +#define ACB_PWNOTREQ 0x0004 /* 1 = User password not required */ +#define ACB_TEMPDUP 0x0008 /* 1 = Temporary duplicate account */ +#define ACB_NORMAL 0x0010 /* 1 = Normal user account */ +#define ACB_MNS 0x0020 /* 1 = MNS logon user account */ +#define ACB_DOMTRUST 0x0040 /* 1 = Interdomain trust account */ +#define ACB_WSTRUST 0x0080 /* 1 = Workstation trust account */ +#define ACB_SVRTRUST 0x0100 /* 1 = Server trust account */ +#define ACB_PWNOEXP 0x0200 /* 1 = User password does not expire */ +#define ACB_AUTOLOCK 0x0400 /* 1 = Account auto locked */ + #define MAX_HOURS_LEN 32 struct sam_passwd { - time_t logon_time; /* logon time */ - time_t logoff_time; /* logoff time */ - time_t kickoff_time; /* kickoff time */ - time_t pass_last_set_time; /* password last set time */ - time_t pass_can_change_time; /* password can change time */ - time_t pass_must_change_time; /* password must change time */ - - char *smb_name; /* username string */ - char *full_name; /* user's full name string */ - char *home_dir; /* home directory string */ - char *dir_drive; /* home directory drive string */ - char *logon_script; /* logon script string */ - char *profile_path; /* profile path string */ - char *acct_desc ; /* user description string */ - char *workstations; /* login from workstations string */ - char *unknown_str ; /* don't know what this is, yet. */ - char *munged_dial ; /* munged path name and dial-back tel number */ - - uid_t smb_userid; /* this is actually the unix uid_t */ - gid_t smb_grpid; /* this is actually the unix gid_t */ - uint32 user_rid; /* Primary User ID */ - uint32 group_rid; /* Primary Group ID */ - - unsigned char *smb_passwd; /* Null if no password */ - unsigned char *smb_nt_passwd; /* Null if no password */ - - uint16 acct_ctrl; /* account info (ACB_xxxx bit-mask) */ - uint32 unknown_3; /* 0x00ff ffff */ - - uint16 logon_divs; /* 168 - number of hours in a week */ - uint32 hours_len; /* normally 21 bytes */ - uint8 hours[MAX_HOURS_LEN]; - - uint32 unknown_5; /* 0x0002 0000 */ - uint32 unknown_6; /* 0x0000 04ec */ + time_t logon_time; /* logon time */ + time_t logoff_time; /* logoff time */ + time_t kickoff_time; /* kickoff time */ + time_t pass_last_set_time; /* password last set time */ + time_t pass_can_change_time; /* password can change time */ + time_t pass_must_change_time; /* password must change time */ + + char *smb_name; /* username string */ + char *full_name; /* user's full name string */ + char *home_dir; /* home directory string */ + char *dir_drive; /* home directory drive string */ + char *logon_script; /* logon script string */ + char *profile_path; /* profile path string */ + char *acct_desc; /* user description string */ + char *workstations; /* login from workstations string */ + char *unknown_str; /* don't know what this is, yet. */ + char *munged_dial; /* munged path name and dial-back tel number */ + + uid_t smb_userid; /* this is actually the unix uid_t */ + gid_t smb_grpid; /* this is actually the unix gid_t */ + uint32 user_rid; /* Primary User ID */ + uint32 group_rid; /* Primary Group ID */ + + unsigned char *smb_passwd; /* Null if no password */ + unsigned char *smb_nt_passwd; /* Null if no password */ + + uint16 acct_ctrl; /* account info (ACB_xxxx bit-mask) */ + uint32 unknown_3; /* 0x00ff ffff */ + + uint16 logon_divs; /* 168 - number of hours in a week */ + uint32 hours_len; /* normally 21 bytes */ + uint8 hours[MAX_HOURS_LEN]; + + uint32 unknown_5; /* 0x0002 0000 */ + uint32 unknown_6; /* 0x0000 04ec */ }; struct smb_passwd { - uid_t smb_userid; /* this is actually the unix uid_t */ - char *smb_name; /* username string */ + uid_t smb_userid; /* this is actually the unix uid_t */ + char *smb_name; /* username string */ - unsigned char *smb_passwd; /* Null if no password */ - unsigned char *smb_nt_passwd; /* Null if no password */ + unsigned char *smb_passwd; /* Null if no password */ + unsigned char *smb_nt_passwd; /* Null if no password */ - uint16 acct_ctrl; /* account info (ACB_xxxx bit-mask) */ - time_t pass_last_set_time; /* password last set time */ + uint16 acct_ctrl; /* account info (ACB_xxxx bit-mask) */ + time_t pass_last_set_time; /* password last set time */ }; struct sam_disp_info { - uint32 user_rid; /* Primary User ID */ - char *smb_name; /* username string */ - char *full_name; /* user's full name string */ + uint32 user_rid; /* Primary User ID */ + char *smb_name; /* username string */ + char *full_name; /* user's full name string */ }; -#define MAXSUBAUTHS 15 /* max sub authorities in a SID */ +#define MAXSUBAUTHS 15 /* max sub authorities in a SID */ /* DOM_SID - security id */ typedef struct sid_info { - uint8 sid_rev_num; /* SID revision number */ - uint8 num_auths; /* number of sub-authorities */ - uint8 id_auth[6]; /* Identifier Authority */ - /* - * Note that the values in these uint32's are in *native* byteorder, - * not neccessarily little-endian...... JRA. - */ - uint32 sub_auths[MAXSUBAUTHS]; /* pointer to sub-authorities. */ + uint8 sid_rev_num; /* SID revision number */ + uint8 num_auths; /* number of sub-authorities */ + uint8 id_auth[6]; /* Identifier Authority */ + /* + * Note that the values in these uint32's are in *native* byteorder, + * not neccessarily little-endian...... JRA. + */ + uint32 sub_auths[MAXSUBAUTHS]; /* pointer to sub-authorities. */ } DOM_SID; @@ -432,9 +433,9 @@ typedef struct sid_info /* local group member info */ typedef struct local_grp_member_info { - DOM_SID sid ; /* matches with name */ - uint8 sid_use; /* usr=1 grp=2 dom=3 alias=4 wkng=5 del=6 inv=7 unk=8 */ - fstring name ; /* matches with sid: must be of the form "DOMAIN\account" */ + DOM_SID sid; /* matches with name */ + uint8 sid_use; /* usr=1 grp=2 dom=3 alias=4 wkng=5 del=6 inv=7 unk=8 */ + fstring name; /* matches with sid: must be of the form "DOMAIN\account" */ } LOCAL_GRP_MEMBER; @@ -443,8 +444,8 @@ typedef struct local_grp_member_info /* local group info */ typedef struct local_grp_info { - fstring name; - fstring comment; + fstring name; + fstring comment; } LOCAL_GRP; @@ -453,10 +454,10 @@ typedef struct local_grp_info /* domain group member info */ typedef struct domain_grp_info { - fstring name; - fstring comment; - uint32 rid; /* group rid */ - uint8 attr; /* attributes forced to be set to 0x7: SE_GROUP_xxx */ + fstring name; + fstring comment; + uint32 rid; /* group rid */ + uint8 attr; /* attributes forced to be set to 0x7: SE_GROUP_xxx */ } DOMAIN_GRP; @@ -465,39 +466,39 @@ typedef struct domain_grp_info /* domain group info */ typedef struct domain_grp_member_info { - fstring name; - uint8 attr; /* attributes forced to be set to 0x7: SE_GROUP_xxx */ + fstring name; + uint8 attr; /* attributes forced to be set to 0x7: SE_GROUP_xxx */ } DOMAIN_GRP_MEMBER; /* DOM_CHAL - challenge info */ typedef struct chal_info { - uchar data[8]; /* credentials */ + uchar data[8]; /* credentials */ } DOM_CHAL; /* 32 bit time (sec) since 01jan1970 - cifs6.txt, section 3.5, page 30 */ typedef struct time_info { - uint32 time; + uint32 time; } UTIME; /* DOM_CREDs - timestamped client or server credentials */ typedef struct cred_info -{ - DOM_CHAL challenge; /* credentials */ - UTIME timestamp; /* credential time-stamp */ +{ + DOM_CHAL challenge; /* credentials */ + UTIME timestamp; /* credential time-stamp */ } DOM_CRED; /* Structure used when SMBwritebmpx is active */ typedef struct { - size_t wr_total_written; /* So we know when to discard this */ - int32 wr_timeout; - int32 wr_errclass; - int32 wr_error; /* Cached errors */ - BOOL wr_mode; /* write through mode) */ - BOOL wr_discard; /* discard all further data */ + size_t wr_total_written; /* So we know when to discard this */ + int32 wr_timeout; + int32 wr_errclass; + int32 wr_error; /* Cached errors */ + BOOL wr_mode; /* write through mode) */ + BOOL wr_discard; /* discard all further data */ } write_bmpx_struct; /* @@ -508,17 +509,17 @@ typedef struct typedef struct file_fd_struct { - struct file_fd_struct *next, *prev; - uint16 ref_count; - uint16 uid_cache_count; - uid_t uid_users_cache[10]; - SMB_DEV_T dev; - SMB_INO_T inode; - int fd; - int fd_readonly; - int fd_writeonly; - int real_open_flags; - BOOL delete_on_close; + struct file_fd_struct *next, *prev; + uint16 ref_count; + uint16 uid_cache_count; + uid_t uid_users_cache[10]; + SMB_DEV_T dev; + SMB_INO_T inode; + int fd; + int fd_readonly; + int fd_writeonly; + int real_open_flags; + BOOL delete_on_close; } file_fd_struct; /* @@ -528,212 +529,218 @@ typedef struct file_fd_struct typedef struct { - time_t modify_time; - time_t status_time; + time_t modify_time; + time_t status_time; } dir_status_struct; -struct uid_cache { - int entries; - uid_t list[UID_CACHE_SIZE]; +struct uid_cache +{ + int entries; + uid_t list[UID_CACHE_SIZE]; }; typedef struct { - char *name; - BOOL is_wild; + char *name; + BOOL is_wild; } name_compare_entry; typedef struct connection_struct { - struct connection_struct *next, *prev; - unsigned cnum; /* an index passed over the wire */ - int service; - BOOL force_user; - struct uid_cache uid_cache; - void *dirptr; - BOOL printer; - BOOL ipc; - BOOL read_only; - BOOL admin_user; - char *dirpath; - char *connectpath; - char *origpath; - char *user; /* name of user who *opened* this connection */ - uid_t uid; /* uid of user who *opened* this connection */ - gid_t gid; /* gid of user who *opened* this connection */ - - uint16 vuid; /* vuid of user who *opened* this connection, or UID_FIELD_INVALID */ - - /* following groups stuff added by ih */ - - /* This groups info is valid for the user that *opened* the connection */ - int ngroups; - gid_t *groups; - - time_t lastused; - BOOL used; - int num_files_open; - name_compare_entry *hide_list; /* Per-share list of files to return as hidden. */ - name_compare_entry *veto_list; /* Per-share list of files to veto (never show). */ - name_compare_entry *veto_oplock_list; /* Per-share list of files to refuse oplocks on. */ + struct connection_struct *next, *prev; + unsigned cnum; /* an index passed over the wire */ + int service; + BOOL force_user; + struct uid_cache uid_cache; + void *dirptr; + BOOL printer; + BOOL ipc; + BOOL read_only; + BOOL admin_user; + char *dirpath; + char *connectpath; + char *origpath; + char *user; /* name of user who *opened* this connection */ + uid_t uid; /* uid of user who *opened* this connection */ + gid_t gid; /* gid of user who *opened* this connection */ + + uint16 vuid; /* vuid of user who *opened* this connection, or UID_FIELD_INVALID */ + + /* following groups stuff added by ih */ + + /* This groups info is valid for the user that *opened* the connection */ + int ngroups; + gid_t *groups; + + time_t lastused; + BOOL used; + int num_files_open; + name_compare_entry *hide_list; /* Per-share list of files to return as hidden. */ + name_compare_entry *veto_list; /* Per-share list of files to veto (never show). */ + name_compare_entry *veto_oplock_list; /* Per-share list of files to refuse oplocks on. */ } connection_struct; struct current_user { - connection_struct *conn; - uint16 vuid; - uid_t uid; - gid_t gid; - int ngroups; - gid_t *groups; + connection_struct *conn; + uint16 vuid; + uid_t uid; + gid_t gid; + int ngroups; + gid_t *groups; }; typedef struct files_struct { - struct files_struct *next, *prev; - int fnum; - connection_struct *conn; - file_fd_struct *fd_ptr; - SMB_OFF_T pos; - SMB_OFF_T size; - mode_t mode; - uint16 vuid; - char *mmap_ptr; - SMB_OFF_T mmap_size; - write_bmpx_struct *wbmpx_ptr; - struct timeval open_time; - int share_mode; - time_t pending_modtime; - BOOL open; - BOOL can_lock; - BOOL can_read; - BOOL can_write; - BOOL print_file; - BOOL modified; - BOOL granted_oplock; - BOOL sent_oplock_break; - BOOL is_directory; - BOOL directory_delete_on_close; - BOOL stat_open; - char *fsp_name; + struct files_struct *next, *prev; + int fnum; + connection_struct *conn; + file_fd_struct *fd_ptr; + SMB_OFF_T pos; + SMB_OFF_T size; + mode_t mode; + uint16 vuid; + char *mmap_ptr; + SMB_OFF_T mmap_size; + write_bmpx_struct *wbmpx_ptr; + struct timeval open_time; + int share_mode; + time_t pending_modtime; + BOOL open; + BOOL can_lock; + BOOL can_read; + BOOL can_write; + BOOL print_file; + BOOL modified; + BOOL granted_oplock; + BOOL sent_oplock_break; + BOOL is_directory; + BOOL directory_delete_on_close; + BOOL stat_open; + char *fsp_name; } files_struct; /* Domain controller authentication protocol info */ struct dcinfo { - DOM_CHAL clnt_chal; /* Initial challenge received from client */ - DOM_CHAL srv_chal; /* Initial server challenge */ - DOM_CRED clnt_cred; /* Last client credential */ - DOM_CRED srv_cred; /* Last server credential */ + DOM_CHAL clnt_chal; /* Initial challenge received from client */ + DOM_CHAL srv_chal; /* Initial server challenge */ + DOM_CRED clnt_cred; /* Last client credential */ + DOM_CRED srv_cred; /* Last server credential */ - uchar sess_key[8]; /* Session key */ - uchar md4pw[16]; /* md4(machine password) */ + uchar sess_key[8]; /* Session key */ + uchar md4pw[16]; /* md4(machine password) */ }; typedef struct { - uid_t uid; /* uid of a validated user */ - gid_t gid; /* gid of a validated user */ + uid_t uid; /* uid of a validated user */ + gid_t gid; /* gid of a validated user */ - fstring requested_name; /* user name from the client */ - fstring name; /* unix user name of a validated user */ - fstring real_name; /* to store real name from password file - simeon */ - BOOL guest; + fstring requested_name; /* user name from the client */ + fstring name; /* unix user name of a validated user */ + fstring real_name; /* to store real name from password file - simeon */ + BOOL guest; - /* following groups stuff added by ih */ - /* This groups info is needed for when we become_user() for this uid */ - int n_groups; - gid_t *groups; + /* following groups stuff added by ih */ + /* This groups info is needed for when we become_user() for this uid */ + int n_groups; + gid_t *groups; - int n_sids; - int *sids; + int n_sids; + int *sids; - /* per-user authentication information on NT RPCs */ - struct dcinfo dc; + /* per-user authentication information on NT RPCs */ + struct dcinfo dc; } user_struct; -enum {LPQ_QUEUED,LPQ_PAUSED,LPQ_SPOOLING,LPQ_PRINTING}; +enum +{ LPQ_QUEUED, LPQ_PAUSED, LPQ_SPOOLING, LPQ_PRINTING }; typedef struct { - int job; - int size; - int status; - int priority; - time_t time; - char user[30]; - char file[100]; + int job; + int size; + int status; + int priority; + time_t time; + char user[30]; + char file[100]; } print_queue_struct; -enum {LPSTAT_OK, LPSTAT_STOPPED, LPSTAT_ERROR}; +enum +{ LPSTAT_OK, LPSTAT_STOPPED, LPSTAT_ERROR }; typedef struct { - fstring message; - int status; -} print_status_struct; + fstring message; + int status; +} print_status_struct; /* used for server information: client, nameserv and ipc */ struct server_info_struct { - fstring name; - uint32 type; - fstring comment; - fstring domain; /* used ONLY in ipc.c NOT namework.c */ - BOOL server_added; /* used ONLY in ipc.c NOT namework.c */ + fstring name; + uint32 type; + fstring comment; + fstring domain; /* used ONLY in ipc.c NOT namework.c */ + BOOL server_added; /* used ONLY in ipc.c NOT namework.c */ }; /* used for network interfaces */ struct interface { - struct interface *next; - struct in_addr ip; - struct in_addr bcast; - struct in_addr nmask; + struct interface *next; + struct in_addr ip; + struct in_addr bcast; + struct in_addr nmask; }; /* struct returned by get_share_modes */ typedef struct { - int pid; - uint16 op_port; - uint16 op_type; - int share_mode; - struct timeval time; + int pid; + uint16 op_port; + uint16 op_type; + int share_mode; + struct timeval time; } share_mode_entry; /* each implementation of the share mode code needs to support the following operations */ -struct share_ops { - BOOL (*stop_mgmt)(void); - BOOL (*lock_entry)(connection_struct *, SMB_DEV_T , SMB_INO_T , int *); - BOOL (*unlock_entry)(connection_struct *, SMB_DEV_T , SMB_INO_T , int ); - int (*get_entries)(connection_struct *, int , SMB_DEV_T , SMB_INO_T , share_mode_entry **); - void (*del_entry)(int , files_struct *); - BOOL (*set_entry)(int, files_struct *, uint16 , uint16 ); - BOOL (*mod_entry)(int, files_struct *, void (*)(share_mode_entry *, SMB_DEV_T, SMB_INO_T, void *), void *); - int (*forall)(void (*)(share_mode_entry *, char *)); - void (*status)(FILE *); +struct share_ops +{ + BOOL (*stop_mgmt) (void); + BOOL (*lock_entry) (connection_struct *, SMB_DEV_T, SMB_INO_T, int *); + BOOL (*unlock_entry) (connection_struct *, SMB_DEV_T, SMB_INO_T, int); + int (*get_entries) (connection_struct *, int, SMB_DEV_T, SMB_INO_T, share_mode_entry **); + void (*del_entry) (int, files_struct *); + BOOL (*set_entry) (int, files_struct *, uint16, uint16); + BOOL (*mod_entry) (int, files_struct *, + void (*)(share_mode_entry *, SMB_DEV_T, SMB_INO_T, void *), void *); + int (*forall) (void (*)(share_mode_entry *, char *)); + void (*status) (FILE *); }; /* each implementation of the shared memory code needs to support the following operations */ -struct shmem_ops { - BOOL (*shm_close)( void ); - int (*shm_alloc)(int ); - BOOL (*shm_free)(int ); - int (*get_userdef_off)(void); - void *(*offset2addr)(int ); - int (*addr2offset)(void *addr); - BOOL (*lock_hash_entry)(unsigned int); - BOOL (*unlock_hash_entry)( unsigned int ); - BOOL (*get_usage)(int *,int *,int *); - unsigned (*hash_size)(void); +struct shmem_ops +{ + BOOL (*shm_close) (void); + int (*shm_alloc) (int); + BOOL (*shm_free) (int); + int (*get_userdef_off) (void); + void *(*offset2addr) (int); + int (*addr2offset) (void *addr); + BOOL (*lock_hash_entry) (unsigned int); + BOOL (*unlock_hash_entry) (unsigned int); + BOOL (*get_usage) (int *, int *, int *); + unsigned (*hash_size) (void); }; /* @@ -741,61 +748,63 @@ struct shmem_ops { * to support the following operations. */ -struct passdb_ops { - /* - * Password database ops. - */ - void *(*startsmbpwent)(BOOL); - void (*endsmbpwent)(void *); - SMB_BIG_UINT (*getsmbpwpos)(void *); - BOOL (*setsmbpwpos)(void *, SMB_BIG_UINT); - - /* - * smb password database query functions. - */ - struct smb_passwd *(*getsmbpwnam)(char *); - struct smb_passwd *(*getsmbpwuid)(uid_t); - struct smb_passwd *(*getsmbpwrid)(uint32); - struct smb_passwd *(*getsmbpwent)(void *); - - /* - * smb password database modification functions. - */ - BOOL (*add_smbpwd_entry)(struct smb_passwd *); - BOOL (*mod_smbpwd_entry)(struct smb_passwd *, BOOL); - - /* - * Functions that manipulate a struct sam_passwd. - */ - struct sam_passwd *(*getsam21pwent)(void *); - - /* - * sam password database query functions. - */ - struct sam_passwd *(*getsam21pwnam)(char *); - struct sam_passwd *(*getsam21pwuid)(uid_t); - struct sam_passwd *(*getsam21pwrid)(uint32); - - /* - * sam password database modification functions. - */ - BOOL (*add_sam21pwd_entry)(struct sam_passwd *); - BOOL (*mod_sam21pwd_entry)(struct sam_passwd *, BOOL); - - /* - * sam query display info functions. - */ - struct sam_disp_info *(*getsamdispnam)(char *); - struct sam_disp_info *(*getsamdisprid)(uint32); - struct sam_disp_info *(*getsamdispent)(void *); +struct passdb_ops +{ + /* + * Password database ops. + */ + void *(*startsmbpwent) (BOOL); + void (*endsmbpwent) (void *); + SMB_BIG_UINT (*getsmbpwpos) (void *); + BOOL (*setsmbpwpos) (void *, SMB_BIG_UINT); + + /* + * smb password database query functions. + */ + struct smb_passwd *(*getsmbpwnam) (char *); + struct smb_passwd *(*getsmbpwuid) (uid_t); + struct smb_passwd *(*getsmbpwrid) (uint32); + struct smb_passwd *(*getsmbpwent) (void *); + + /* + * smb password database modification functions. + */ + BOOL (*add_smbpwd_entry) (struct smb_passwd *); + BOOL (*mod_smbpwd_entry) (struct smb_passwd *, BOOL); + + /* + * Functions that manipulate a struct sam_passwd. + */ + struct sam_passwd *(*getsam21pwent) (void *); + + /* + * sam password database query functions. + */ + struct sam_passwd *(*getsam21pwnam) (char *); + struct sam_passwd *(*getsam21pwuid) (uid_t); + struct sam_passwd *(*getsam21pwrid) (uint32); + + /* + * sam password database modification functions. + */ + BOOL (*add_sam21pwd_entry) (struct sam_passwd *); + BOOL (*mod_sam21pwd_entry) (struct sam_passwd *, BOOL); + + /* + * sam query display info functions. + */ + struct sam_disp_info *(*getsamdispnam) (char *); + struct sam_disp_info *(*getsamdisprid) (uint32); + struct sam_disp_info *(*getsamdispent) (void *); #if 0 - /* - * password checking functions - */ - struct smb_passwd *(*smb_password_chal )(char *username, char lm_pass[24], char nt_pass[24], char chal[8]); - struct smb_passwd *(*smb_password_check )(char *username, char lm_hash[16], char nt_hash[16]); - struct passwd *(*unix_password_check)(char *username, char *pass, int pass_len); + /* + * password checking functions + */ + struct smb_passwd *(*smb_password_chal) (char *username, char lm_pass[24], char nt_pass[24], + char chal[8]); + struct smb_passwd *(*smb_password_check) (char *username, char lm_hash[16], char nt_hash[16]); + struct passwd *(*unix_password_check) (char *username, char *pass, int pass_len); #endif }; @@ -803,81 +812,85 @@ struct passdb_ops { struct connect_record { - int magic; - int pid; - int cnum; - uid_t uid; - gid_t gid; - char name[24]; - char addr[24]; - char machine[128]; - time_t start; + int magic; + int pid; + int cnum; + uid_t uid; + gid_t gid; + char name[24]; + char addr[24]; + char machine[128]; + time_t start; }; /* This is used by smbclient to send it to a smbfs mount point */ -struct connection_options { - int protocol; - /* Connection-Options */ - uint32 max_xmit; - uint16 server_vuid; - uint16 tid; - /* The following are LANMAN 1.0 options */ - uint16 sec_mode; - uint16 max_mux; - uint16 max_vcs; - uint16 rawmode; - uint32 sesskey; - /* The following are NT LM 0.12 options */ - uint32 maxraw; - uint32 capabilities; - uint16 serverzone; +struct connection_options +{ + int protocol; + /* Connection-Options */ + uint32 max_xmit; + uint16 server_vuid; + uint16 tid; + /* The following are LANMAN 1.0 options */ + uint16 sec_mode; + uint16 max_mux; + uint16 max_vcs; + uint16 rawmode; + uint32 sesskey; + /* The following are NT LM 0.12 options */ + uint32 maxraw; + uint32 capabilities; + uint16 serverzone; }; /* the following are used by loadparm for option lists */ typedef enum { - P_BOOL,P_BOOLREV,P_CHAR,P_INTEGER,P_OCTAL, - P_STRING,P_USTRING,P_GSTRING,P_UGSTRING,P_ENUM,P_SEP + P_BOOL, P_BOOLREV, P_CHAR, P_INTEGER, P_OCTAL, + P_STRING, P_USTRING, P_GSTRING, P_UGSTRING, P_ENUM, P_SEP } parm_type; typedef enum { - P_LOCAL,P_GLOBAL,P_SEPARATOR,P_NONE + P_LOCAL, P_GLOBAL, P_SEPARATOR, P_NONE } parm_class; -struct enum_list { - int value; - const char *name; +struct enum_list +{ + int value; + const char *name; }; struct parm_struct { - const char *label; - parm_type type; - parm_class class; - void *ptr; - BOOL (*special)(const char *, char **); - const struct enum_list *enum_list; - unsigned flags; - union { - BOOL bvalue; - int ivalue; - char *svalue; - char cvalue; - } def; + const char *label; + parm_type type; + parm_class class; + void *ptr; + BOOL (*special) (const char *, char **); + const struct enum_list *enum_list; + unsigned flags; + union + { + BOOL bvalue; + int ivalue; + char *svalue; + char cvalue; + } def; }; -struct bitmap { - uint32 *b; - int n; +struct bitmap +{ + uint32 *b; + int n; }; -#define FLAG_BASIC 0x01 /* fundamental options */ -#define FLAG_SHARE 0x02 /* file sharing options */ -#define FLAG_PRINT 0x04 /* printing options */ -#define FLAG_GLOBAL 0x08 /* local options that should be globally settable in SWAT */ -#define FLAG_DEPRECATED 0x10 /* options that should no longer be used */ -#define FLAG_HIDE 0x20 /* options that should be hidden in SWAT */ +#define FLAG_BASIC 0x01 /* fundamental options */ +#define FLAG_SHARE 0x02 /* file sharing options */ +#define FLAG_PRINT 0x04 /* printing options */ +#define FLAG_GLOBAL 0x08 /* local options that should be globally settable in SWAT */ +#define FLAG_DEPRECATED 0x10 /* options that should no longer be used */ +#define FLAG_HIDE 0x20 /* options that should be hidden in SWAT */ #ifndef LOCKING_VERSION #define LOCKING_VERSION 4 @@ -928,7 +941,7 @@ struct bitmap { * stat structure is valid. */ -#define VALID_STAT(st) (st.st_nlink != 0) +#define VALID_STAT(st) (st.st_nlink != 0) #define VALID_STAT_OF_DIR(st) (VALID_STAT(st) && S_ISDIR(st.st_mode)) #define SMBENCRYPT() (lp_encrypted_passwords()) @@ -980,51 +993,51 @@ struct bitmap { #define FLAG_REPLY 0x80 /* the complete */ -#define SMBmkdir 0x00 /* create directory */ -#define SMBrmdir 0x01 /* delete directory */ -#define SMBopen 0x02 /* open file */ -#define SMBcreate 0x03 /* create file */ -#define SMBclose 0x04 /* close file */ -#define SMBflush 0x05 /* flush file */ -#define SMBunlink 0x06 /* delete file */ -#define SMBmv 0x07 /* rename file */ -#define SMBgetatr 0x08 /* get file attributes */ -#define SMBsetatr 0x09 /* set file attributes */ -#define SMBread 0x0A /* read from file */ -#define SMBwrite 0x0B /* write to file */ -#define SMBlock 0x0C /* lock byte range */ -#define SMBunlock 0x0D /* unlock byte range */ -#define SMBctemp 0x0E /* create temporary file */ -#define SMBmknew 0x0F /* make new file */ -#define SMBchkpth 0x10 /* check directory path */ -#define SMBexit 0x11 /* process exit */ -#define SMBlseek 0x12 /* seek */ -#define SMBtcon 0x70 /* tree connect */ -#define SMBtconX 0x75 /* tree connect and X*/ -#define SMBtdis 0x71 /* tree disconnect */ -#define SMBnegprot 0x72 /* negotiate protocol */ -#define SMBdskattr 0x80 /* get disk attributes */ -#define SMBsearch 0x81 /* search directory */ -#define SMBsplopen 0xC0 /* open print spool file */ -#define SMBsplwr 0xC1 /* write to print spool file */ -#define SMBsplclose 0xC2 /* close print spool file */ -#define SMBsplretq 0xC3 /* return print queue */ -#define SMBsends 0xD0 /* send single block message */ -#define SMBsendb 0xD1 /* send broadcast message */ -#define SMBfwdname 0xD2 /* forward user name */ -#define SMBcancelf 0xD3 /* cancel forward */ -#define SMBgetmac 0xD4 /* get machine name */ -#define SMBsendstrt 0xD5 /* send start of multi-block message */ -#define SMBsendend 0xD6 /* send end of multi-block message */ -#define SMBsendtxt 0xD7 /* send text of multi-block message */ +#define SMBmkdir 0x00 /* create directory */ +#define SMBrmdir 0x01 /* delete directory */ +#define SMBopen 0x02 /* open file */ +#define SMBcreate 0x03 /* create file */ +#define SMBclose 0x04 /* close file */ +#define SMBflush 0x05 /* flush file */ +#define SMBunlink 0x06 /* delete file */ +#define SMBmv 0x07 /* rename file */ +#define SMBgetatr 0x08 /* get file attributes */ +#define SMBsetatr 0x09 /* set file attributes */ +#define SMBread 0x0A /* read from file */ +#define SMBwrite 0x0B /* write to file */ +#define SMBlock 0x0C /* lock byte range */ +#define SMBunlock 0x0D /* unlock byte range */ +#define SMBctemp 0x0E /* create temporary file */ +#define SMBmknew 0x0F /* make new file */ +#define SMBchkpth 0x10 /* check directory path */ +#define SMBexit 0x11 /* process exit */ +#define SMBlseek 0x12 /* seek */ +#define SMBtcon 0x70 /* tree connect */ +#define SMBtconX 0x75 /* tree connect and X */ +#define SMBtdis 0x71 /* tree disconnect */ +#define SMBnegprot 0x72 /* negotiate protocol */ +#define SMBdskattr 0x80 /* get disk attributes */ +#define SMBsearch 0x81 /* search directory */ +#define SMBsplopen 0xC0 /* open print spool file */ +#define SMBsplwr 0xC1 /* write to print spool file */ +#define SMBsplclose 0xC2 /* close print spool file */ +#define SMBsplretq 0xC3 /* return print queue */ +#define SMBsends 0xD0 /* send single block message */ +#define SMBsendb 0xD1 /* send broadcast message */ +#define SMBfwdname 0xD2 /* forward user name */ +#define SMBcancelf 0xD3 /* cancel forward */ +#define SMBgetmac 0xD4 /* get machine name */ +#define SMBsendstrt 0xD5 /* send start of multi-block message */ +#define SMBsendend 0xD6 /* send end of multi-block message */ +#define SMBsendtxt 0xD7 /* send text of multi-block message */ /* Core+ protocol */ -#define SMBlockread 0x13 /* Lock a range and read */ -#define SMBwriteunlock 0x14 /* Unlock a range then write */ -#define SMBreadbraw 0x1a /* read a block of data with no smb header */ -#define SMBwritebraw 0x1d /* write a block of data with no smb header */ -#define SMBwritec 0x20 /* secondary write request */ -#define SMBwriteclose 0x2c /* write a file then close it */ +#define SMBlockread 0x13 /* Lock a range and read */ +#define SMBwriteunlock 0x14 /* Unlock a range then write */ +#define SMBreadbraw 0x1a /* read a block of data with no smb header */ +#define SMBwritebraw 0x1d /* write a block of data with no smb header */ +#define SMBwritec 0x20 /* secondary write request */ +#define SMBwriteclose 0x2c /* write a file then close it */ /* dos extended protocol */ #define SMBreadBraw 0x1A /* read block raw */ @@ -1195,7 +1208,7 @@ struct bitmap { #define FILE_WRITE_ATTRIBUTES 0x100 #define FILE_ALL_ATTRIBUTES 0x1FF - + /* Generic access masks & rights. */ #define SPECIFIC_RIGHTS_MASK 0x00FFFFL #define STANDARD_RIGHTS_MASK 0xFF0000L @@ -1214,7 +1227,7 @@ struct bitmap { #define FILE_ALL_STANDARD_ACCESS 0x1F0000 /* Mapping of access rights to UNIX perms. */ -#if 0 /* Don't use all here... JRA. */ +#if 0 /* Don't use all here... JRA. */ #define UNIX_ACCESS_RWX (FILE_ALL_ATTRIBUTES|FILE_ALL_STANDARD_ACCESS) #else #define UNIX_ACCESS_RWX (UNIX_ACCESS_R|UNIX_ACCESS_W|UNIX_ACCESS_X) @@ -1236,7 +1249,7 @@ struct bitmap { #define OPEN_DIRECTORY 8 /* ShareAccess field. */ -#define FILE_SHARE_NONE 0 /* Cannot be used in bitmask. */ +#define FILE_SHARE_NONE 0 /* Cannot be used in bitmask. */ #define FILE_SHARE_READ 1 #define FILE_SHARE_WRITE 2 #define FILE_SHARE_DELETE 4 @@ -1316,24 +1329,25 @@ struct bitmap { #define smb_base(buf) (((char *)(buf))+4) -#define SMB_SUCCESS 0 /* The request was successful. */ -#define ERRDOS 0x01 /* Error is from the core DOS operating system set. */ -#define ERRSRV 0x02 /* Error is generated by the server network file manager.*/ -#define ERRHRD 0x03 /* Error is an hardware error. */ -#define ERRCMD 0xFF /* Command was not in the "SMB" format. */ +#define SMB_SUCCESS 0 /* The request was successful. */ +#define ERRDOS 0x01 /* Error is from the core DOS operating system set. */ +#define ERRSRV 0x02 /* Error is generated by the server network file manager. */ +#define ERRHRD 0x03 /* Error is an hardware error. */ +#define ERRCMD 0xFF /* Command was not in the "SMB" format. */ #ifdef HAVE_STDARG_H -int slprintf(char *str, int n, const char *format, ...) +int +slprintf (char *str, int n, const char *format, ...) #ifdef __GNUC__ - __attribute__ ((format (printf, 3, 4))) + __attribute__ ((format (printf, 3, 4))) #endif -; + ; #else -int slprintf(); +int slprintf (); #endif #ifdef WITH_DFS -void dfs_unlogin(void); +void dfs_unlogin (void); extern int dcelogin_atmost_once; #endif @@ -1358,7 +1372,7 @@ extern int dcelogin_atmost_once; /* Some POSIX definitions for those without */ - + #ifndef S_IFDIR #define S_IFDIR 0x4000 #endif @@ -1427,10 +1441,10 @@ extern int dcelogin_atmost_once; #define SV_TYPE_SERVER_OSF 0x00100000 #define SV_TYPE_SERVER_VMS 0x00200000 #define SV_TYPE_WIN95_PLUS 0x00400000 -#define SV_TYPE_ALTERNATE_XPORT 0x20000000 -#define SV_TYPE_LOCAL_LIST_ONLY 0x40000000 +#define SV_TYPE_ALTERNATE_XPORT 0x20000000 +#define SV_TYPE_LOCAL_LIST_ONLY 0x40000000 #define SV_TYPE_DOMAIN_ENUM 0x80000000 -#define SV_TYPE_ALL 0xFFFFFFFF +#define SV_TYPE_ALL 0xFFFFFFFF /* what server type are we currently - JHT Says we ARE 4.20 */ /* this was set by JHT in liaison with Jeremy Allison early 1997 */ @@ -1438,7 +1452,7 @@ extern int dcelogin_atmost_once; /* History: */ /* Version 4.0 - never made public */ /* Version 4.10 - New to 1.9.16p2, lost in space 1.9.16p3 to 1.9.16p9 */ -/* - Reappeared in 1.9.16p11 with fixed smbd services */ +/* - Reappeared in 1.9.16p11 with fixed smbd services */ /* Version 4.20 - To indicate that nmbd and browsing now works better */ #define DEFAULT_MAJOR_VERSION 0x04 @@ -1449,12 +1463,12 @@ extern int dcelogin_atmost_once; #define BROWSER_CONSTANT 0xaa55 /* NT Flags2 bits - cifs6.txt section 3.1.2 */ - + #define FLAGS2_LONG_PATH_COMPONENTS 0x0001 #define FLAGS2_EXTENDED_ATTRIBUTES 0x0002 #define FLAGS2_DFS_PATHNAMES 0x1000 #define FLAGS2_READ_PERMIT_NO_EXECUTE 0x2000 -#define FLAGS2_32_BIT_ERROR_CODES 0x4000 +#define FLAGS2_32_BIT_ERROR_CODES 0x4000 #define FLAGS2_UNICODE_STRINGS 0x8000 /* Capabilities. see ftp.microsoft.com/developr/drg/cifs/cifs/cifs4.txt */ @@ -1474,24 +1488,33 @@ extern int dcelogin_atmost_once; /* protocol types. It assumes that higher protocols include lower protocols as subsets */ -enum protocol_types {PROTOCOL_NONE,PROTOCOL_CORE,PROTOCOL_COREPLUS,PROTOCOL_LANMAN1,PROTOCOL_LANMAN2,PROTOCOL_NT1}; +enum protocol_types +{ PROTOCOL_NONE, PROTOCOL_CORE, PROTOCOL_COREPLUS, PROTOCOL_LANMAN1, PROTOCOL_LANMAN2, + PROTOCOL_NT1 +}; /* security levels */ -enum security_types {SEC_SHARE,SEC_USER,SEC_SERVER,SEC_DOMAIN}; +enum security_types +{ SEC_SHARE, SEC_USER, SEC_SERVER, SEC_DOMAIN }; /* printing types */ -enum printing_types {PRINT_BSD,PRINT_SYSV,PRINT_AIX,PRINT_HPUX, - PRINT_QNX,PRINT_PLP,PRINT_LPRNG,PRINT_SOFTQ}; +enum printing_types +{ PRINT_BSD, PRINT_SYSV, PRINT_AIX, PRINT_HPUX, + PRINT_QNX, PRINT_PLP, PRINT_LPRNG, PRINT_SOFTQ +}; /* Remote architectures we know about. */ -enum remote_arch_types {RA_UNKNOWN, RA_WFWG, RA_OS2, RA_WIN95, RA_WINNT, RA_SAMBA}; +enum remote_arch_types +{ RA_UNKNOWN, RA_WFWG, RA_OS2, RA_WIN95, RA_WINNT, RA_SAMBA }; /* case handling */ -enum case_handling {CASE_LOWER,CASE_UPPER}; +enum case_handling +{ CASE_LOWER, CASE_UPPER }; #ifdef WITH_SSL /* SSL version options */ -enum ssl_version_enum {SMB_SSL_V2,SMB_SSL_V3,SMB_SSL_V23,SMB_SSL_TLS1}; +enum ssl_version_enum +{ SMB_SSL_V2, SMB_SSL_V3, SMB_SSL_V23, SMB_SSL_TLS1 }; #endif /* WITH_SSL */ /* Macros to get at offsets within smb_lkrng and smb_unlkrng @@ -1532,7 +1555,7 @@ enum ssl_version_enum {SMB_SSL_V2,SMB_SSL_V3,SMB_SSL_V23,SMB_SSL_TLS1}; */ #define UID_FIELD_INVALID 0 -#define VUID_OFFSET 100 /* Amount to bias returned vuid numbers */ +#define VUID_OFFSET 100 /* Amount to bias returned vuid numbers */ /* Defines needed for multi-codepage support. */ #define MSDOS_LATIN_1_CODEPAGE 850 @@ -1677,10 +1700,11 @@ extern int unix_ERR_code; #define SMB_ASSERT_ARRAY(a,n) SMB_ASSERT((sizeof(a)/sizeof((a)[0])) >= (n)) /* A netbios name structure. */ -struct nmb_name { - char name[17]; - char scope[64]; - unsigned int name_type; +struct nmb_name +{ + char name[17]; + char scope[64]; + unsigned int name_type; }; #include "client.h" @@ -1710,7 +1734,7 @@ struct nmb_name { Note that map_to_guest only has an effect in user or server level security. -*/ + */ #define NEVER_MAP_TO_GUEST 0 #define MAP_TO_GUEST_ON_BAD_USER 1 diff --git a/src/vfs/smbfs/helpers/include/trans2.h b/src/vfs/smbfs/helpers/include/trans2.h index 26bca6c76..c57d7330a 100644 --- a/src/vfs/smbfs/helpers/include/trans2.h +++ b/src/vfs/smbfs/helpers/include/trans2.h @@ -2,7 +2,7 @@ Unix SMB/Netbios implementation. Version 1.9. SMB transaction2 handling -*/ + */ #ifndef _TRANS2_H_ #define _TRANS2_H_ @@ -243,6 +243,3 @@ Byte offset Type name description #define TYPE_VIRTUAL 0x40 #endif - - - diff --git a/src/vfs/smbfs/helpers/lib/charcnv.c b/src/vfs/smbfs/helpers/lib/charcnv.c dissimilarity index 77% index 5f7cd9b26..efae52d24 100644 --- a/src/vfs/smbfs/helpers/lib/charcnv.c +++ b/src/vfs/smbfs/helpers/lib/charcnv.c @@ -1,237 +1,277 @@ -/* - Unix SMB/Netbios implementation. - Version 1.9. - Character set conversion Extensions - - Copyright (C) Andrew Tridgell 1992-1998 - - Copyright (C) 2011 - The Free Software Foundation, Inc. - - This file is part of the Midnight Commander. - - The Midnight Commander is free software: you can redistribute it - and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of the License, - or (at your option) any later version. - - The Midnight Commander is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "includes.h" -#define CTRLZ 26 -extern int DEBUGLEVEL; - -static char cvtbuf[1024]; - -static BOOL mapsinited = 0; - -static char unix2dos[256]; -static char dos2unix[256]; - -static void initmaps(void) { - int k; - - for (k = 0; k < 256; k++) unix2dos[k] = k; - for (k = 0; k < 256; k++) dos2unix[k] = k; - - mapsinited = True; -} - -static void update_map(const char * str) { - const char *p; - - for (p = str; *p; p++) { - if (p[1]) { - unix2dos[(unsigned char)*p] = p[1]; - dos2unix[(unsigned char)p[1]] = *p; - p++; - } - } -} - -static void init_iso8859_1(void) { - - int i; - if (!mapsinited) initmaps(); - - /* Do not map undefined characters to some accidental code */ - for (i = 128; i < 256; i++) - { - unix2dos[i] = CTRLZ; - dos2unix[i] = CTRLZ; - } - -/* MSDOS Code Page 850 -> ISO-8859 */ -update_map("\240\377\241\255\242\275\243\234\244\317\245\276\246\335\247\365"); -update_map("\250\371\251\270\252\246\253\256\254\252\255\360\256\251\257\356"); -update_map("\260\370\261\361\262\375\263\374\264\357\265\346\266\364\267\372"); -update_map("\270\367\271\373\272\247\273\257\274\254\275\253\276\363\277\250"); -update_map("\300\267\301\265\302\266\303\307\304\216\305\217\306\222\307\200"); -update_map("\310\324\311\220\312\322\313\323\314\336\315\326\316\327\317\330"); -update_map("\320\321\321\245\322\343\323\340\324\342\325\345\326\231\327\236"); -update_map("\330\235\331\353\332\351\333\352\334\232\335\355\336\350\337\341"); -update_map("\340\205\341\240\342\203\343\306\344\204\345\206\346\221\347\207"); -update_map("\350\212\351\202\352\210\353\211\354\215\355\241\356\214\357\213"); -update_map("\360\320\361\244\362\225\363\242\364\223\365\344\366\224\367\366"); -update_map("\370\233\371\227\372\243\373\226\374\201\375\354\376\347\377\230"); - -} - -/* Init for eastern european languages. */ - -static void init_iso8859_2(void) { - - int i; - if (!mapsinited) initmaps(); - - /* Do not map undefined characters to some accidental code */ - for (i = 128; i < 256; i++) - { - unix2dos[i] = CTRLZ; - dos2unix[i] = CTRLZ; - } - -/* - * Tranlation table created by Petr Hubeny - * Requires client code page = 852 - * and character set = ISO8859-2 in smb.conf - */ - -/* MSDOS Code Page 852 -> ISO-8859-2 */ -update_map("\241\244\242\364\243\235\244\317\245\225\246\227\247\365"); -update_map("\250\371\251\346\252\270\253\233\254\215\256\246\257\275"); -update_map("\261\245\262\362\263\210\264\357\265\226\266\230\267\363"); -update_map("\270\367\271\347\272\255\273\234\274\253\275\361\276\247\277\276"); -update_map("\300\350\301\265\302\266\303\306\304\216\305\221\306\217\307\200"); -update_map("\310\254\311\220\312\250\313\323\314\267\315\326\316\327\317\322"); -update_map("\320\321\321\343\322\325\323\340\324\342\325\212\326\231\327\236"); -update_map("\330\374\331\336\332\351\333\353\334\232\335\355\336\335\337\341"); -update_map("\340\352\341\240\342\203\343\307\344\204\345\222\346\206\347\207"); -update_map("\350\237\351\202\352\251\353\211\354\330\355\241\356\214\357\324"); -update_map("\360\320\361\344\362\345\363\242\364\223\365\213\366\224\367\366"); -update_map("\370\375\371\205\372\243\373\373\374\201\375\354\376\356\377\372"); -} - -/* Init for russian language (iso8859-5) */ - -/* Added by Max Khon */ - -static void init_iso8859_5(void) -{ - int i; - if (!mapsinited) initmaps(); - - /* Do not map undefined characters to some accidental code */ - for (i = 128; i < 256; i++) - { - unix2dos[i] = CTRLZ; - dos2unix[i] = CTRLZ; - } - -/* MSDOS Code Page 866 -> ISO8859-5 */ -update_map("\260\200\261\201\262\202\263\203\264\204\265\205\266\206\267\207"); -update_map("\270\210\271\211\272\212\273\213\274\214\275\215\276\216\277\217"); -update_map("\300\220\301\221\302\222\303\223\304\224\305\225\306\226\307\227"); -update_map("\310\230\311\231\312\232\313\233\314\234\315\235\316\236\317\237"); -update_map("\320\240\321\241\322\242\323\243\324\244\325\245\326\246\327\247"); -update_map("\330\250\331\251\332\252\333\253\334\254\335\255\336\256\337\257"); -update_map("\340\340\341\341\342\342\343\343\344\344\345\345\346\346\347\347"); -update_map("\350\350\351\351\352\352\353\353\354\354\355\355\356\356\357\357"); -update_map("\241\360\361\361\244\362\364\363\247\364\367\365\256\366\376\367"); -update_map("\360\374\240\377"); -} - -/* Init for russian language (koi8) */ - -static void init_koi8_r(void) -{ - if (!mapsinited) initmaps(); - - /* There aren't undefined characters between 128 and 255 */ - -/* MSDOS Code Page 866 -> KOI8-R */ -update_map("\200\304\201\263\202\332\203\277\204\300\205\331\206\303\207\264"); -update_map("\210\302\211\301\212\305\213\337\214\334\215\333\216\335\217\336"); -update_map("\220\260\221\261\222\262\223\364\224\376\225\371\226\373\227\367"); -update_map("\230\363\231\362\232\377\233\365\234\370\235\375\236\372\237\366"); -update_map("\240\315\241\272\242\325\243\361\244\326\245\311\246\270\247\267"); -update_map("\250\273\251\324\252\323\253\310\254\276\255\275\256\274\257\306"); -update_map("\260\307\261\314\262\265\263\360\264\266\265\271\266\321\267\322"); -update_map("\270\313\271\317\272\320\273\312\274\330\275\327\276\316\277\374"); -update_map("\300\356\301\240\302\241\303\346\304\244\305\245\306\344\307\243"); -update_map("\310\345\311\250\312\251\313\252\314\253\315\254\316\255\317\256"); -update_map("\320\257\321\357\322\340\323\341\324\342\325\343\326\246\327\242"); -update_map("\330\354\331\353\332\247\333\350\334\355\335\351\336\347\337\352"); -update_map("\340\236\341\200\342\201\343\226\344\204\345\205\346\224\347\203"); -update_map("\350\225\351\210\352\211\353\212\354\213\355\214\356\215\357\216"); -update_map("\360\217\361\237\362\220\363\221\364\222\365\223\366\206\367\202"); -update_map("\370\234\371\233\372\207\373\230\374\235\375\231\376\227\377\232"); -} - -/* - * Convert unix to dos - */ -char *unix2dos_format(char *str,BOOL overwrite) -{ - char *p; - char *dp; - - if (!mapsinited) initmaps(); - - if (overwrite) { - for (p = str; *p; p++) *p = unix2dos[(unsigned char)*p]; - return str; - } else { - for (p = str, dp = cvtbuf; *p && dp < &(cvtbuf[sizeof(cvtbuf) - 1]); p++,dp++) - *dp = unix2dos[(unsigned char)*p]; - *dp = 0; - return cvtbuf; - } -} - -/* - * Convert dos to unix - */ -char *dos2unix_format(char *str, BOOL overwrite) -{ - char *p; - char *dp; - - if (!mapsinited) initmaps(); - - if (overwrite) { - for (p = str; *p; p++) *p = dos2unix[(unsigned char)*p]; - return str; - } else { - for (p = str, dp = cvtbuf; *p && dp < &(cvtbuf[sizeof(cvtbuf) - 1]); p++,dp++) - *dp = dos2unix[(unsigned char)*p]; - *dp = 0; - return cvtbuf; - } -} - - -/* - * Interpret character set. - */ -void interpret_character_set(const char *str) -{ - if (strequal (str, "iso8859-1")) { - init_iso8859_1(); - } else if (strequal (str, "iso8859-2")) { - init_iso8859_2(); - } else if (strequal (str, "iso8859-5")) { - init_iso8859_5(); - } else if (strequal (str, "koi8-r")) { - init_koi8_r(); - } else { - DEBUG(0,("unrecognized character set %s\n", str)); - } -} +/* + Unix SMB/Netbios implementation. + Version 1.9. + Character set conversion Extensions + + Copyright (C) Andrew Tridgell 1992-1998 + + Copyright (C) 2011 + The Free Software Foundation, Inc. + + This file is part of the Midnight Commander. + + The Midnight Commander is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + The Midnight Commander is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + */ + +#include "includes.h" +#define CTRLZ 26 +extern int DEBUGLEVEL; + +static char cvtbuf[1024]; + +static BOOL mapsinited = 0; + +static char unix2dos[256]; +static char dos2unix[256]; + +static void +initmaps (void) +{ + int k; + + for (k = 0; k < 256; k++) + unix2dos[k] = k; + for (k = 0; k < 256; k++) + dos2unix[k] = k; + + mapsinited = True; +} + +static void +update_map (const char *str) +{ + const char *p; + + for (p = str; *p; p++) + { + if (p[1]) + { + unix2dos[(unsigned char) *p] = p[1]; + dos2unix[(unsigned char) p[1]] = *p; + p++; + } + } +} + +static void +init_iso8859_1 (void) +{ + + int i; + if (!mapsinited) + initmaps (); + + /* Do not map undefined characters to some accidental code */ + for (i = 128; i < 256; i++) + { + unix2dos[i] = CTRLZ; + dos2unix[i] = CTRLZ; + } + + /* MSDOS Code Page 850 -> ISO-8859 */ + update_map ("\240\377\241\255\242\275\243\234\244\317\245\276\246\335\247\365"); + update_map ("\250\371\251\270\252\246\253\256\254\252\255\360\256\251\257\356"); + update_map ("\260\370\261\361\262\375\263\374\264\357\265\346\266\364\267\372"); + update_map ("\270\367\271\373\272\247\273\257\274\254\275\253\276\363\277\250"); + update_map ("\300\267\301\265\302\266\303\307\304\216\305\217\306\222\307\200"); + update_map ("\310\324\311\220\312\322\313\323\314\336\315\326\316\327\317\330"); + update_map ("\320\321\321\245\322\343\323\340\324\342\325\345\326\231\327\236"); + update_map ("\330\235\331\353\332\351\333\352\334\232\335\355\336\350\337\341"); + update_map ("\340\205\341\240\342\203\343\306\344\204\345\206\346\221\347\207"); + update_map ("\350\212\351\202\352\210\353\211\354\215\355\241\356\214\357\213"); + update_map ("\360\320\361\244\362\225\363\242\364\223\365\344\366\224\367\366"); + update_map ("\370\233\371\227\372\243\373\226\374\201\375\354\376\347\377\230"); + +} + +/* Init for eastern european languages. */ + +static void +init_iso8859_2 (void) +{ + + int i; + if (!mapsinited) + initmaps (); + + /* Do not map undefined characters to some accidental code */ + for (i = 128; i < 256; i++) + { + unix2dos[i] = CTRLZ; + dos2unix[i] = CTRLZ; + } + + /* + * Tranlation table created by Petr Hubeny + * Requires client code page = 852 + * and character set = ISO8859-2 in smb.conf + */ + + /* MSDOS Code Page 852 -> ISO-8859-2 */ + update_map ("\241\244\242\364\243\235\244\317\245\225\246\227\247\365"); + update_map ("\250\371\251\346\252\270\253\233\254\215\256\246\257\275"); + update_map ("\261\245\262\362\263\210\264\357\265\226\266\230\267\363"); + update_map ("\270\367\271\347\272\255\273\234\274\253\275\361\276\247\277\276"); + update_map ("\300\350\301\265\302\266\303\306\304\216\305\221\306\217\307\200"); + update_map ("\310\254\311\220\312\250\313\323\314\267\315\326\316\327\317\322"); + update_map ("\320\321\321\343\322\325\323\340\324\342\325\212\326\231\327\236"); + update_map ("\330\374\331\336\332\351\333\353\334\232\335\355\336\335\337\341"); + update_map ("\340\352\341\240\342\203\343\307\344\204\345\222\346\206\347\207"); + update_map ("\350\237\351\202\352\251\353\211\354\330\355\241\356\214\357\324"); + update_map ("\360\320\361\344\362\345\363\242\364\223\365\213\366\224\367\366"); + update_map ("\370\375\371\205\372\243\373\373\374\201\375\354\376\356\377\372"); +} + +/* Init for russian language (iso8859-5) */ + +/* Added by Max Khon */ + +static void +init_iso8859_5 (void) +{ + int i; + if (!mapsinited) + initmaps (); + + /* Do not map undefined characters to some accidental code */ + for (i = 128; i < 256; i++) + { + unix2dos[i] = CTRLZ; + dos2unix[i] = CTRLZ; + } + + /* MSDOS Code Page 866 -> ISO8859-5 */ + update_map ("\260\200\261\201\262\202\263\203\264\204\265\205\266\206\267\207"); + update_map ("\270\210\271\211\272\212\273\213\274\214\275\215\276\216\277\217"); + update_map ("\300\220\301\221\302\222\303\223\304\224\305\225\306\226\307\227"); + update_map ("\310\230\311\231\312\232\313\233\314\234\315\235\316\236\317\237"); + update_map ("\320\240\321\241\322\242\323\243\324\244\325\245\326\246\327\247"); + update_map ("\330\250\331\251\332\252\333\253\334\254\335\255\336\256\337\257"); + update_map ("\340\340\341\341\342\342\343\343\344\344\345\345\346\346\347\347"); + update_map ("\350\350\351\351\352\352\353\353\354\354\355\355\356\356\357\357"); + update_map ("\241\360\361\361\244\362\364\363\247\364\367\365\256\366\376\367"); + update_map ("\360\374\240\377"); +} + +/* Init for russian language (koi8) */ + +static void +init_koi8_r (void) +{ + if (!mapsinited) + initmaps (); + + /* There aren't undefined characters between 128 and 255 */ + + /* MSDOS Code Page 866 -> KOI8-R */ + update_map ("\200\304\201\263\202\332\203\277\204\300\205\331\206\303\207\264"); + update_map ("\210\302\211\301\212\305\213\337\214\334\215\333\216\335\217\336"); + update_map ("\220\260\221\261\222\262\223\364\224\376\225\371\226\373\227\367"); + update_map ("\230\363\231\362\232\377\233\365\234\370\235\375\236\372\237\366"); + update_map ("\240\315\241\272\242\325\243\361\244\326\245\311\246\270\247\267"); + update_map ("\250\273\251\324\252\323\253\310\254\276\255\275\256\274\257\306"); + update_map ("\260\307\261\314\262\265\263\360\264\266\265\271\266\321\267\322"); + update_map ("\270\313\271\317\272\320\273\312\274\330\275\327\276\316\277\374"); + update_map ("\300\356\301\240\302\241\303\346\304\244\305\245\306\344\307\243"); + update_map ("\310\345\311\250\312\251\313\252\314\253\315\254\316\255\317\256"); + update_map ("\320\257\321\357\322\340\323\341\324\342\325\343\326\246\327\242"); + update_map ("\330\354\331\353\332\247\333\350\334\355\335\351\336\347\337\352"); + update_map ("\340\236\341\200\342\201\343\226\344\204\345\205\346\224\347\203"); + update_map ("\350\225\351\210\352\211\353\212\354\213\355\214\356\215\357\216"); + update_map ("\360\217\361\237\362\220\363\221\364\222\365\223\366\206\367\202"); + update_map ("\370\234\371\233\372\207\373\230\374\235\375\231\376\227\377\232"); +} + +/* + * Convert unix to dos + */ +char * +unix2dos_format (char *str, BOOL overwrite) +{ + char *p; + char *dp; + + if (!mapsinited) + initmaps (); + + if (overwrite) + { + for (p = str; *p; p++) + *p = unix2dos[(unsigned char) *p]; + return str; + } + else + { + for (p = str, dp = cvtbuf; *p && dp < &(cvtbuf[sizeof (cvtbuf) - 1]); p++, dp++) + *dp = unix2dos[(unsigned char) *p]; + *dp = 0; + return cvtbuf; + } +} + +/* + * Convert dos to unix + */ +char * +dos2unix_format (char *str, BOOL overwrite) +{ + char *p; + char *dp; + + if (!mapsinited) + initmaps (); + + if (overwrite) + { + for (p = str; *p; p++) + *p = dos2unix[(unsigned char) *p]; + return str; + } + else + { + for (p = str, dp = cvtbuf; *p && dp < &(cvtbuf[sizeof (cvtbuf) - 1]); p++, dp++) + *dp = dos2unix[(unsigned char) *p]; + *dp = 0; + return cvtbuf; + } +} + + +/* + * Interpret character set. + */ +void +interpret_character_set (const char *str) +{ + if (strequal (str, "iso8859-1")) + { + init_iso8859_1 (); + } + else if (strequal (str, "iso8859-2")) + { + init_iso8859_2 (); + } + else if (strequal (str, "iso8859-5")) + { + init_iso8859_5 (); + } + else if (strequal (str, "koi8-r")) + { + init_koi8_r (); + } + else + { + DEBUG (0, ("unrecognized character set %s\n", str)); + } +} diff --git a/src/vfs/smbfs/helpers/lib/charset.c b/src/vfs/smbfs/helpers/lib/charset.c dissimilarity index 77% index e698826c2..5330d04f7 100644 --- a/src/vfs/smbfs/helpers/lib/charset.c +++ b/src/vfs/smbfs/helpers/lib/charset.c @@ -1,402 +1,409 @@ -/* - Unix SMB/Netbios implementation. - Version 1.9. - Character set handling - - Copyright (C) Andrew Tridgell 1992-1998 - - Copyright (C) 2011 - The Free Software Foundation, Inc. - - This file is part of the Midnight Commander. - - The Midnight Commander is free software: you can redistribute it - and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of the License, - or (at your option) any later version. - - The Midnight Commander is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#define CHARSET_C -#include "includes.h" - -const char *unix_error_string (int error_num); -extern int DEBUGLEVEL; - -/* - * Codepage definitions. - */ - -#if !defined(KANJI) -/* lower->upper mapping for IBM Code Page 850 - MS-DOS Latin 1 */ -unsigned char const cp_850[][4] = { -/* dec col/row oct hex description */ -/* 133 08/05 205 85 a grave */ -/* 183 11/07 267 B7 A grave */ {0x85,0xB7,1,1}, -/* 160 10/00 240 A0 a acute */ -/* 181 11/05 265 B5 A acute */ {0xA0,0xB5,1,1}, -/* 131 08/03 203 83 a circumflex */ -/* 182 11/06 266 B6 A circumflex */ {0x83,0xB6,1,1}, -/* 198 12/06 306 C6 a tilde */ -/* 199 12/07 307 C7 A tilde */ {0xC6,0xC7,1,1}, -/* 132 08/04 204 84 a diaeresis */ -/* 142 08/14 216 8E A diaeresis */ {0x84,0x8E,1,1}, -/* 134 08/06 206 86 a ring */ -/* 143 08/15 217 8F A ring */ {0x86,0x8F,1,1}, -/* 145 09/01 221 91 ae diphthong */ -/* 146 09/02 222 92 AE diphthong */ {0x91,0x92,1,1}, -/* 135 08/07 207 87 c cedilla */ -/* 128 08/00 200 80 C cedilla */ {0x87,0x80,1,1}, -/* 138 08/10 212 8A e grave */ -/* 212 13/04 324 D4 E grave */ {0x8A,0xD4,1,1}, -/* 130 08/02 202 82 e acute */ -/* 144 09/00 220 90 E acute */ {0x82,0x90,1,1}, -/* 136 08/08 210 88 e circumflex */ -/* 210 13/02 322 D2 E circumflex */ {0x88,0xD2,1,1}, -/* 137 08/09 211 89 e diaeresis */ -/* 211 13/03 323 D3 E diaeresis */ {0x89,0xD3,1,1}, -/* 141 08/13 215 8D i grave */ -/* 222 13/14 336 DE I grave */ {0x8D,0xDE,1,1}, -/* 161 10/01 241 A1 i acute */ -/* 214 13/06 326 D6 I acute */ {0xA1,0xD6,1,1}, -/* 140 08/12 214 8C i circumflex */ -/* 215 13/07 327 D7 I circumflex */ {0x8C,0xD7,1,1}, -/* 139 08/11 213 8B i diaeresis */ -/* 216 13/08 330 D8 I diaeresis */ {0x8B,0xD8,1,1}, -/* 208 13/00 320 D0 Icelandic eth */ -/* 209 13/01 321 D1 Icelandic Eth */ {0xD0,0xD1,1,1}, -/* 164 10/04 244 A4 n tilde */ -/* 165 10/05 245 A5 N tilde */ {0xA4,0xA5,1,1}, -/* 149 09/05 225 95 o grave */ -/* 227 14/03 343 E3 O grave */ {0x95,0xE3,1,1}, -/* 162 10/02 242 A2 o acute */ -/* 224 14/00 340 E0 O acute */ {0xA2,0xE0,1,1}, -/* 147 09/03 223 93 o circumflex */ -/* 226 14/02 342 E2 O circumflex */ {0x93,0xE2,1,1}, -/* 228 14/04 344 E4 o tilde */ -/* 229 14/05 345 E5 O tilde */ {0xE4,0xE5,1,1}, -/* 148 09/04 224 94 o diaeresis */ -/* 153 09/09 231 99 O diaeresis */ {0x94,0x99,1,1}, -/* 155 09/11 233 9B o slash */ -/* 157 09/13 235 9D O slash */ {0x9B,0x9D,1,1}, -/* 151 09/07 227 97 u grave */ -/* 235 14/11 353 EB U grave */ {0x97,0xEB,1,1}, -/* 163 10/03 243 A3 u acute */ -/* 233 14/09 351 E9 U acute */ {0xA3,0xE9,1,1}, -/* 150 09/06 226 96 u circumflex */ -/* 234 14/10 352 EA U circumflex */ {0x96,0xEA,1,1}, -/* 129 08/01 201 81 u diaeresis */ -/* 154 09/10 232 9A U diaeresis */ {0x81,0x9A,1,1}, -/* 236 14/12 354 EC y acute */ -/* 237 14/13 355 ED Y acute */ {0xEC,0xED,1,1}, -/* 231 14/07 347 E7 Icelandic thorn */ -/* 232 14/08 350 E8 Icelandic Thorn */ {0xE7,0xE8,1,1}, - - {0x9C,0,0,0}, /* Pound */ - {0,0,0,0} -}; -#else /* KANJI */ -/* lower->upper mapping for IBM Code Page 932 - MS-DOS Japanese SJIS */ -unsigned char const cp_932[][4] = { - {0,0,0,0} -}; -#endif /* KANJI */ - -char xx_dos_char_map[256]; -char xx_upper_char_map[256]; -char xx_lower_char_map[256]; - -char *dos_char_map = xx_dos_char_map; -char *upper_char_map = xx_upper_char_map; -char *lower_char_map = xx_lower_char_map; - -/* - * This code has been extended to deal with ascynchronous mappings - * like MS-DOS Latin US (Code page 437) where things like : - * a acute are capitalized to 'A', but the reverse mapping - * must not hold true. This allows the filename case insensitive - * matching in do_match() to work, as the DOS/Win95/NT client - * uses 'A' as a mask to match against characters like a acute. - * This is the meaning behind the parameters that allow a - * mapping from lower to upper, but not upper to lower. - */ - -static void add_dos_char(int lower, BOOL map_lower_to_upper, - int upper, BOOL map_upper_to_lower) -{ - lower &= 0xff; - upper &= 0xff; - DEBUGADD( 6, ( "Adding chars 0x%x 0x%x (l->u = %s) (u->l = %s)\n", - lower, upper, - map_lower_to_upper ? "True" : "False", - map_upper_to_lower ? "True" : "False" ) ); - if (lower) dos_char_map[lower] = 1; - if (upper) dos_char_map[upper] = 1; - lower_char_map[lower] = (char)lower; /* Define tolower(lower) */ - upper_char_map[upper] = (char)upper; /* Define toupper(upper) */ - if (lower && upper) { - if(map_upper_to_lower) - lower_char_map[upper] = (char)lower; - if(map_lower_to_upper) - upper_char_map[lower] = (char)upper; - } -} - -/**************************************************************************** -initialise the charset arrays -****************************************************************************/ -void charset_initialise(void) -{ - int i; - -#ifdef LC_ALL - /* include in includes.h if available for OS */ - /* we take only standard 7-bit ASCII definitions from ctype */ - setlocale(LC_ALL,"C"); -#endif - - for (i= 0;i<=255;i++) { - dos_char_map[i] = 0; - } - - for (i=0;i<=127;i++) { - if (isalnum(i) || strchr("._^$~!#%&-{}()@'`",(char)i)) - add_dos_char(i,False,0,False); - } - - for (i=0; i<=255; i++) { - char c = (char)i; - upper_char_map[i] = lower_char_map[i] = c; - - /* Some systems have buggy isupper/islower for characters - above 127. Best not to rely on them. */ - if(i < 128) { - if (isupper((int)c)) lower_char_map[i] = tolower(c); - if (islower((int)c)) upper_char_map[i] = toupper(c); - } - } -} - -/**************************************************************************** -load the client codepage. -****************************************************************************/ - -typedef const unsigned char (*codepage_p)[4]; - -static codepage_p load_client_codepage( int client_codepage ) -{ - pstring codepage_file_name; - unsigned char buf[8]; - FILE *fp = NULL; - SMB_OFF_T size; - codepage_p cp_p = NULL; - SMB_STRUCT_STAT st; - - DEBUG(5, ("load_client_codepage: loading codepage %d.\n", client_codepage)); - - if(strlen(CODEPAGEDIR) + 14 > sizeof(codepage_file_name)) - { - DEBUG(0,("load_client_codepage: filename too long to load\n")); - return NULL; - } - - pstrcpy(codepage_file_name, CODEPAGEDIR); - pstrcat(codepage_file_name, "/"); - pstrcat(codepage_file_name, "codepage."); - slprintf(&codepage_file_name[strlen(codepage_file_name)], - sizeof(pstring)-(strlen(codepage_file_name)+1), - "%03d", - client_codepage); - - if(sys_stat(codepage_file_name,&st)!=0) - { - DEBUG(0,("load_client_codepage: filename %s does not exist.\n", - codepage_file_name)); - return NULL; - } - - /* Check if it is at least big enough to hold the required - data. Should be 2 byte version, 2 byte codepage, 4 byte length, - plus zero or more bytes of data. Note that the data cannot be more - than 4 * MAXCODEPAGELINES bytes. - */ - size = st.st_size; - - if( size < CODEPAGE_HEADER_SIZE || size > (CODEPAGE_HEADER_SIZE + 4 * MAXCODEPAGELINES)) - { - DEBUG(0,("load_client_codepage: file %s is an incorrect size for a \ -code page file (size=%d).\n", codepage_file_name, (int)size)); - return NULL; - } - - /* Read the first 8 bytes of the codepage file - check - the version number and code page number. All the data - is held in little endian format. - */ - - if((fp = sys_fopen( codepage_file_name, "r")) == NULL) - { - DEBUG(0,("load_client_codepage: cannot open file %s. Error was %s\n", - codepage_file_name, unix_error_string (errno))); - return NULL; - } - - if(fread( buf, 1, CODEPAGE_HEADER_SIZE, fp)!=CODEPAGE_HEADER_SIZE) - { - DEBUG(0,("load_client_codepage: cannot read header from file %s. Error was %s\n", - codepage_file_name, unix_error_string (errno))); - goto clean_and_exit; - } - - /* Check the version value */ - if(SVAL(buf,CODEPAGE_VERSION_OFFSET) != CODEPAGE_FILE_VERSION_ID) - { - DEBUG(0,("load_client_codepage: filename %s has incorrect version id. \ -Needed %hu, got %hu.\n", - codepage_file_name, (uint16)CODEPAGE_FILE_VERSION_ID, - SVAL(buf,CODEPAGE_VERSION_OFFSET))); - goto clean_and_exit; - } - - /* Check the codepage matches */ - if(SVAL(buf,CODEPAGE_CLIENT_CODEPAGE_OFFSET) != (uint16)client_codepage) - { - DEBUG(0,("load_client_codepage: filename %s has incorrect codepage. \ -Needed %hu, got %hu.\n", - codepage_file_name, (uint16)client_codepage, - SVAL(buf,CODEPAGE_CLIENT_CODEPAGE_OFFSET))); - goto clean_and_exit; - } - - /* Check the length is correct. */ - if(IVAL(buf,CODEPAGE_LENGTH_OFFSET) != (size - CODEPAGE_HEADER_SIZE)) - { - DEBUG(0,("load_client_codepage: filename %s has incorrect size headers. \ -Needed %u, got %u.\n", codepage_file_name, (uint32)(size - CODEPAGE_HEADER_SIZE), - IVAL(buf,CODEPAGE_LENGTH_OFFSET))); - goto clean_and_exit; - } - - size -= CODEPAGE_HEADER_SIZE; /* Remove header */ - - /* Make sure the size is a multiple of 4. */ - if((size % 4 ) != 0) - { - DEBUG(0,("load_client_codepage: filename %s has a codepage size not a \ -multiple of 4.\n", codepage_file_name)); - goto clean_and_exit; - } - - /* Allocate space for the code page file and read it all in. */ - if((cp_p = (codepage_p)malloc( size + 4 )) == NULL) - { - DEBUG(0,("load_client_codepage: malloc fail.\n")); - goto clean_and_exit; - } - - if(fread( (char *)cp_p, 1, size, fp)!=size) - { - DEBUG(0,("load_client_codepage: read fail on file %s. Error was %s.\n", - codepage_file_name, unix_error_string (errno))); - goto clean_and_exit; - } - - /* Ensure array is correctly terminated. */ - memset(((char *)cp_p) + size, '\0', 4); - - fclose(fp); - return cp_p; - -clean_and_exit: - - /* pseudo destructor :-) */ - - if(fp != NULL) - fclose(fp); - if(cp_p) - free((char *)cp_p); - return NULL; -} - -/**************************************************************************** -initialise the client codepage. -****************************************************************************/ -void codepage_initialise(int client_codepage) -{ - int i; - static codepage_p cp = NULL; - - if(cp != NULL) - { - DEBUG(6, - ("codepage_initialise: called twice - ignoring second client code page = %d\n", - client_codepage)); - return; - } - - DEBUG(6,("codepage_initialise: client code page = %d\n", client_codepage)); - - /* - * Known client codepages - these can be added to. - */ - cp = load_client_codepage( client_codepage ); - - if(cp == NULL) - { -#ifdef KANJI - DEBUG(6,("codepage_initialise: loading dynamic codepage file %s/codepage.%d \ -for code page %d failed. Using default client codepage 932\n", - CODEPAGEDIR, client_codepage, client_codepage)); - cp = cp_932; - client_codepage = KANJI_CODEPAGE; -#else /* KANJI */ - DEBUG(6,("codepage_initialise: loading dynamic codepage file %s/codepage.%d \ -for code page %d failed. Using default client codepage 850\n", - CODEPAGEDIR, client_codepage, client_codepage)); - cp = cp_850; - client_codepage = MSDOS_LATIN_1_CODEPAGE; -#endif /* KANJI */ - } - - /* - * Setup the function pointers for the loaded codepage. - */ - initialize_multibyte_vectors( client_codepage ); - - if(cp) - { - for(i = 0; !((cp[i][0] == '\0') && (cp[i][1] == '\0')); i++) - add_dos_char(cp[i][0], (BOOL)cp[i][2], cp[i][1], (BOOL)cp[i][3]); - } -} - -/******************************************************************* -add characters depending on a string passed by the user -********************************************************************/ -void add_char_string(const char *s) -{ - char *extra_chars = (char *)strdup(s); - char *t; - if (!extra_chars) return; - - for (t=strtok(extra_chars," \t\r\n"); t; t=strtok(NULL," \t\r\n")) { - char c1=0,c2=0; - int i1=0,i2=0; - if (isdigit((unsigned char)*t) || (*t)=='-') { - sscanf(t,"%i:%i",&i1,&i2); - add_dos_char(i1,True,i2,True); - } else { - sscanf(t,"%c:%c",&c1,&c2); - add_dos_char((unsigned char)c1,True,(unsigned char)c2, True); - } - } - - free(extra_chars); -} +/* + Unix SMB/Netbios implementation. + Version 1.9. + Character set handling + + Copyright (C) Andrew Tridgell 1992-1998 + + Copyright (C) 2011 + The Free Software Foundation, Inc. + + This file is part of the Midnight Commander. + + The Midnight Commander is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + The Midnight Commander is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + */ + +#define CHARSET_C +#include "includes.h" + +const char *unix_error_string (int error_num); +extern int DEBUGLEVEL; + +/* + * Codepage definitions. + */ + +#if !defined(KANJI) +/* lower->upper mapping for IBM Code Page 850 - MS-DOS Latin 1 */ +unsigned char const cp_850[][4] = { + /* dec col/row oct hex description */ + /* 133 08/05 205 85 a grave */ + /* 183 11/07 267 B7 A grave */ {0x85, 0xB7, 1, 1}, + /* 160 10/00 240 A0 a acute */ + /* 181 11/05 265 B5 A acute */ {0xA0, 0xB5, 1, 1}, + /* 131 08/03 203 83 a circumflex */ + /* 182 11/06 266 B6 A circumflex */ {0x83, 0xB6, 1, 1}, + /* 198 12/06 306 C6 a tilde */ + /* 199 12/07 307 C7 A tilde */ {0xC6, 0xC7, 1, 1}, + /* 132 08/04 204 84 a diaeresis */ + /* 142 08/14 216 8E A diaeresis */ {0x84, 0x8E, 1, 1}, + /* 134 08/06 206 86 a ring */ + /* 143 08/15 217 8F A ring */ {0x86, 0x8F, 1, 1}, + /* 145 09/01 221 91 ae diphthong */ + /* 146 09/02 222 92 AE diphthong */ {0x91, 0x92, 1, 1}, + /* 135 08/07 207 87 c cedilla */ + /* 128 08/00 200 80 C cedilla */ {0x87, 0x80, 1, 1}, + /* 138 08/10 212 8A e grave */ + /* 212 13/04 324 D4 E grave */ {0x8A, 0xD4, 1, 1}, + /* 130 08/02 202 82 e acute */ + /* 144 09/00 220 90 E acute */ {0x82, 0x90, 1, 1}, + /* 136 08/08 210 88 e circumflex */ + /* 210 13/02 322 D2 E circumflex */ {0x88, 0xD2, 1, 1}, + /* 137 08/09 211 89 e diaeresis */ + /* 211 13/03 323 D3 E diaeresis */ {0x89, 0xD3, 1, 1}, + /* 141 08/13 215 8D i grave */ + /* 222 13/14 336 DE I grave */ {0x8D, 0xDE, 1, 1}, + /* 161 10/01 241 A1 i acute */ + /* 214 13/06 326 D6 I acute */ {0xA1, 0xD6, 1, 1}, + /* 140 08/12 214 8C i circumflex */ + /* 215 13/07 327 D7 I circumflex */ {0x8C, 0xD7, 1, 1}, + /* 139 08/11 213 8B i diaeresis */ + /* 216 13/08 330 D8 I diaeresis */ {0x8B, 0xD8, 1, 1}, + /* 208 13/00 320 D0 Icelandic eth */ + /* 209 13/01 321 D1 Icelandic Eth */ {0xD0, 0xD1, 1, 1}, + /* 164 10/04 244 A4 n tilde */ + /* 165 10/05 245 A5 N tilde */ {0xA4, 0xA5, 1, 1}, + /* 149 09/05 225 95 o grave */ + /* 227 14/03 343 E3 O grave */ {0x95, 0xE3, 1, 1}, + /* 162 10/02 242 A2 o acute */ + /* 224 14/00 340 E0 O acute */ {0xA2, 0xE0, 1, 1}, + /* 147 09/03 223 93 o circumflex */ + /* 226 14/02 342 E2 O circumflex */ {0x93, 0xE2, 1, 1}, + /* 228 14/04 344 E4 o tilde */ + /* 229 14/05 345 E5 O tilde */ {0xE4, 0xE5, 1, 1}, + /* 148 09/04 224 94 o diaeresis */ + /* 153 09/09 231 99 O diaeresis */ {0x94, 0x99, 1, 1}, + /* 155 09/11 233 9B o slash */ + /* 157 09/13 235 9D O slash */ {0x9B, 0x9D, 1, 1}, + /* 151 09/07 227 97 u grave */ + /* 235 14/11 353 EB U grave */ {0x97, 0xEB, 1, 1}, + /* 163 10/03 243 A3 u acute */ + /* 233 14/09 351 E9 U acute */ {0xA3, 0xE9, 1, 1}, + /* 150 09/06 226 96 u circumflex */ + /* 234 14/10 352 EA U circumflex */ {0x96, 0xEA, 1, 1}, + /* 129 08/01 201 81 u diaeresis */ + /* 154 09/10 232 9A U diaeresis */ {0x81, 0x9A, 1, 1}, + /* 236 14/12 354 EC y acute */ + /* 237 14/13 355 ED Y acute */ {0xEC, 0xED, 1, 1}, + /* 231 14/07 347 E7 Icelandic thorn */ + /* 232 14/08 350 E8 Icelandic Thorn */ {0xE7, 0xE8, 1, 1}, + + {0x9C, 0, 0, 0}, /* Pound */ + {0, 0, 0, 0} +}; +#else /* KANJI */ +/* lower->upper mapping for IBM Code Page 932 - MS-DOS Japanese SJIS */ +unsigned char const cp_932[][4] = { + {0, 0, 0, 0} +}; +#endif /* KANJI */ + +char xx_dos_char_map[256]; +char xx_upper_char_map[256]; +char xx_lower_char_map[256]; + +char *dos_char_map = xx_dos_char_map; +char *upper_char_map = xx_upper_char_map; +char *lower_char_map = xx_lower_char_map; + +/* + * This code has been extended to deal with ascynchronous mappings + * like MS-DOS Latin US (Code page 437) where things like : + * a acute are capitalized to 'A', but the reverse mapping + * must not hold true. This allows the filename case insensitive + * matching in do_match() to work, as the DOS/Win95/NT client + * uses 'A' as a mask to match against characters like a acute. + * This is the meaning behind the parameters that allow a + * mapping from lower to upper, but not upper to lower. + */ + +static void +add_dos_char (int lower, BOOL map_lower_to_upper, int upper, BOOL map_upper_to_lower) +{ + lower &= 0xff; + upper &= 0xff; + DEBUGADD (6, ("Adding chars 0x%x 0x%x (l->u = %s) (u->l = %s)\n", + lower, upper, + map_lower_to_upper ? "True" : "False", map_upper_to_lower ? "True" : "False")); + if (lower) + dos_char_map[lower] = 1; + if (upper) + dos_char_map[upper] = 1; + lower_char_map[lower] = (char) lower; /* Define tolower(lower) */ + upper_char_map[upper] = (char) upper; /* Define toupper(upper) */ + if (lower && upper) + { + if (map_upper_to_lower) + lower_char_map[upper] = (char) lower; + if (map_lower_to_upper) + upper_char_map[lower] = (char) upper; + } +} + +/**************************************************************************** +initialise the charset arrays +****************************************************************************/ +void +charset_initialise (void) +{ + int i; + +#ifdef LC_ALL + /* include in includes.h if available for OS */ + /* we take only standard 7-bit ASCII definitions from ctype */ + setlocale (LC_ALL, "C"); +#endif + + for (i = 0; i <= 255; i++) + { + dos_char_map[i] = 0; + } + + for (i = 0; i <= 127; i++) + { + if (isalnum (i) || strchr ("._^$~!#%&-{}()@'`", (char) i)) + add_dos_char (i, False, 0, False); + } + + for (i = 0; i <= 255; i++) + { + char c = (char) i; + upper_char_map[i] = lower_char_map[i] = c; + + /* Some systems have buggy isupper/islower for characters + above 127. Best not to rely on them. */ + if (i < 128) + { + if (isupper ((int) c)) + lower_char_map[i] = tolower (c); + if (islower ((int) c)) + upper_char_map[i] = toupper (c); + } + } +} + +/**************************************************************************** +load the client codepage. +****************************************************************************/ + +typedef const unsigned char (*codepage_p)[4]; + +static codepage_p +load_client_codepage (int client_codepage) +{ + pstring codepage_file_name; + unsigned char buf[8]; + FILE *fp = NULL; + SMB_OFF_T size; + codepage_p cp_p = NULL; + SMB_STRUCT_STAT st; + + DEBUG (5, ("load_client_codepage: loading codepage %d.\n", client_codepage)); + + if (strlen (CODEPAGEDIR) + 14 > sizeof (codepage_file_name)) + { + DEBUG (0, ("load_client_codepage: filename too long to load\n")); + return NULL; + } + + pstrcpy (codepage_file_name, CODEPAGEDIR); + pstrcat (codepage_file_name, "/"); + pstrcat (codepage_file_name, "codepage."); + slprintf (&codepage_file_name[strlen (codepage_file_name)], + sizeof (pstring) - (strlen (codepage_file_name) + 1), "%03d", client_codepage); + + if (sys_stat (codepage_file_name, &st) != 0) + { + DEBUG (0, ("load_client_codepage: filename %s does not exist.\n", codepage_file_name)); + return NULL; + } + + /* Check if it is at least big enough to hold the required + data. Should be 2 byte version, 2 byte codepage, 4 byte length, + plus zero or more bytes of data. Note that the data cannot be more + than 4 * MAXCODEPAGELINES bytes. + */ + size = st.st_size; + + if (size < CODEPAGE_HEADER_SIZE || size > (CODEPAGE_HEADER_SIZE + 4 * MAXCODEPAGELINES)) + { + DEBUG (0, ("load_client_codepage: file %s is an incorrect size for a \ +code page file (size=%d).\n", codepage_file_name, (int) size)); + return NULL; + } + + /* Read the first 8 bytes of the codepage file - check + the version number and code page number. All the data + is held in little endian format. + */ + + if ((fp = sys_fopen (codepage_file_name, "r")) == NULL) + { + DEBUG (0, ("load_client_codepage: cannot open file %s. Error was %s\n", + codepage_file_name, unix_error_string (errno))); + return NULL; + } + + if (fread (buf, 1, CODEPAGE_HEADER_SIZE, fp) != CODEPAGE_HEADER_SIZE) + { + DEBUG (0, ("load_client_codepage: cannot read header from file %s. Error was %s\n", + codepage_file_name, unix_error_string (errno))); + goto clean_and_exit; + } + + /* Check the version value */ + if (SVAL (buf, CODEPAGE_VERSION_OFFSET) != CODEPAGE_FILE_VERSION_ID) + { + DEBUG (0, ("load_client_codepage: filename %s has incorrect version id. \ +Needed %hu, got %hu.\n", codepage_file_name, (uint16) CODEPAGE_FILE_VERSION_ID, SVAL (buf, CODEPAGE_VERSION_OFFSET))); + goto clean_and_exit; + } + + /* Check the codepage matches */ + if (SVAL (buf, CODEPAGE_CLIENT_CODEPAGE_OFFSET) != (uint16) client_codepage) + { + DEBUG (0, ("load_client_codepage: filename %s has incorrect codepage. \ +Needed %hu, got %hu.\n", codepage_file_name, (uint16) client_codepage, SVAL (buf, CODEPAGE_CLIENT_CODEPAGE_OFFSET))); + goto clean_and_exit; + } + + /* Check the length is correct. */ + if (IVAL (buf, CODEPAGE_LENGTH_OFFSET) != (size - CODEPAGE_HEADER_SIZE)) + { + DEBUG (0, ("load_client_codepage: filename %s has incorrect size headers. \ +Needed %u, got %u.\n", codepage_file_name, (uint32) (size - CODEPAGE_HEADER_SIZE), IVAL (buf, CODEPAGE_LENGTH_OFFSET))); + goto clean_and_exit; + } + + size -= CODEPAGE_HEADER_SIZE; /* Remove header */ + + /* Make sure the size is a multiple of 4. */ + if ((size % 4) != 0) + { + DEBUG (0, ("load_client_codepage: filename %s has a codepage size not a \ +multiple of 4.\n", codepage_file_name)); + goto clean_and_exit; + } + + /* Allocate space for the code page file and read it all in. */ + if ((cp_p = (codepage_p) malloc (size + 4)) == NULL) + { + DEBUG (0, ("load_client_codepage: malloc fail.\n")); + goto clean_and_exit; + } + + if (fread ((char *) cp_p, 1, size, fp) != size) + { + DEBUG (0, ("load_client_codepage: read fail on file %s. Error was %s.\n", + codepage_file_name, unix_error_string (errno))); + goto clean_and_exit; + } + + /* Ensure array is correctly terminated. */ + memset (((char *) cp_p) + size, '\0', 4); + + fclose (fp); + return cp_p; + + clean_and_exit: + + /* pseudo destructor :-) */ + + if (fp != NULL) + fclose (fp); + if (cp_p) + free ((char *) cp_p); + return NULL; +} + +/**************************************************************************** +initialise the client codepage. +****************************************************************************/ +void +codepage_initialise (int client_codepage) +{ + int i; + static codepage_p cp = NULL; + + if (cp != NULL) + { + DEBUG (6, + ("codepage_initialise: called twice - ignoring second client code page = %d\n", + client_codepage)); + return; + } + + DEBUG (6, ("codepage_initialise: client code page = %d\n", client_codepage)); + + /* + * Known client codepages - these can be added to. + */ + cp = load_client_codepage (client_codepage); + + if (cp == NULL) + { +#ifdef KANJI + DEBUG (6, ("codepage_initialise: loading dynamic codepage file %s/codepage.%d \ +for code page %d failed. Using default client codepage 932\n", CODEPAGEDIR, client_codepage, client_codepage)); + cp = cp_932; + client_codepage = KANJI_CODEPAGE; +#else /* KANJI */ + DEBUG (6, ("codepage_initialise: loading dynamic codepage file %s/codepage.%d \ +for code page %d failed. Using default client codepage 850\n", CODEPAGEDIR, client_codepage, client_codepage)); + cp = cp_850; + client_codepage = MSDOS_LATIN_1_CODEPAGE; +#endif /* KANJI */ + } + + /* + * Setup the function pointers for the loaded codepage. + */ + initialize_multibyte_vectors (client_codepage); + + if (cp) + { + for (i = 0; !((cp[i][0] == '\0') && (cp[i][1] == '\0')); i++) + add_dos_char (cp[i][0], (BOOL) cp[i][2], cp[i][1], (BOOL) cp[i][3]); + } +} + +/******************************************************************* +add characters depending on a string passed by the user +********************************************************************/ +void +add_char_string (const char *s) +{ + char *extra_chars = (char *) strdup (s); + char *t; + if (!extra_chars) + return; + + for (t = strtok (extra_chars, " \t\r\n"); t; t = strtok (NULL, " \t\r\n")) + { + char c1 = 0, c2 = 0; + int i1 = 0, i2 = 0; + if (isdigit ((unsigned char) *t) || (*t) == '-') + { + sscanf (t, "%i:%i", &i1, &i2); + add_dos_char (i1, True, i2, True); + } + else + { + sscanf (t, "%c:%c", &c1, &c2); + add_dos_char ((unsigned char) c1, True, (unsigned char) c2, True); + } + } + + free (extra_chars); +} diff --git a/src/vfs/smbfs/helpers/lib/debug.c b/src/vfs/smbfs/helpers/lib/debug.c index 6b5e3586d..f8f676372 100644 --- a/src/vfs/smbfs/helpers/lib/debug.c +++ b/src/vfs/smbfs/helpers/lib/debug.c @@ -22,7 +22,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . -*/ + */ #include "includes.h" @@ -84,10 +84,10 @@ * levels higher than DEBUGLEVEL will not be processed. */ -FILE *dbf = NULL; -pstring debugf = ""; -BOOL append_log = False; -int DEBUGLEVEL = 1; +FILE *dbf = NULL; +pstring debugf = ""; +BOOL append_log = False; +int DEBUGLEVEL = 1; /* -------------------------------------------------------------------------- ** @@ -108,9 +108,10 @@ int DEBUGLEVEL = 1; * format_pos - Marks the first free byte of the format_bufr. */ -static BOOL stdout_logging = False; -static pstring format_bufr = { '\0' }; -static size_t format_pos = 0; +static BOOL stdout_logging = False; +static pstring format_bufr = { '\0' }; + +static size_t format_pos = 0; /* -------------------------------------------------------------------------- ** @@ -121,15 +122,16 @@ static size_t format_pos = 0; * get ready for syslog stuff * ************************************************************************** ** */ -void setup_logging( const char *pname, BOOL interactive ) - { - (void) pname; - if( interactive ) +void +setup_logging (const char *pname, BOOL interactive) +{ + (void) pname; + if (interactive) { - stdout_logging = True; - dbf = stderr; + stdout_logging = True; + dbf = stderr; } - } /* setup_logging */ +} /* setup_logging */ /* ************************************************************************** ** * Write an debug message on the debugfile. @@ -137,68 +139,70 @@ void setup_logging( const char *pname, BOOL interactive ) * ************************************************************************** ** */ #ifdef HAVE_STDARG_H - int Debug1( const char *format_str, ... ) +int +Debug1 (const char *format_str, ...) { #else - int Debug1(va_alist) -va_dcl -{ - const char *format_str; +int +Debug1 (va_alist) + va_dcl +{ + const char *format_str; #endif - va_list ap; - int old_errno = errno; + va_list ap; + int old_errno = errno; - if( stdout_logging ) + if (stdout_logging) { #ifdef HAVE_STDARG_H - va_start( ap, format_str ); + va_start (ap, format_str); #else - va_start( ap ); - format_str = va_arg( ap, const char * ); + va_start (ap); + format_str = va_arg (ap, const char *); #endif - (void)vfprintf( dbf, format_str, ap ); - va_end( ap ); - errno = old_errno; - return( 0 ); + (void) vfprintf (dbf, format_str, ap); + va_end (ap); + errno = old_errno; + return (0); } - - if( !dbf && *debugf) - { - mode_t oldumask = umask( 022 ); - - if( append_log ) - dbf = sys_fopen( debugf, "a" ); - else - dbf = sys_fopen( debugf, "w" ); - (void)umask( oldumask ); - if( dbf ) + + if (!dbf && *debugf) + { + mode_t oldumask = umask (022); + + if (append_log) + dbf = sys_fopen (debugf, "a"); + else + dbf = sys_fopen (debugf, "w"); + (void) umask (oldumask); + if (dbf) { - setbuf( dbf, NULL ); + setbuf (dbf, NULL); } - else + else { - errno = old_errno; - return(0); + errno = old_errno; + return (0); } - } + } if (dbf) { #ifdef HAVE_STDARG_H - va_start( ap, format_str ); + va_start (ap, format_str); #else - va_start( ap ); - format_str = va_arg( ap, const char * ); + va_start (ap); + format_str = va_arg (ap, const char *); #endif - (void)vfprintf( dbf, format_str, ap ); - va_end( ap ); - (void)fflush( dbf ); + (void) vfprintf (dbf, format_str, ap); + va_end (ap); + (void) fflush (dbf); } - errno = old_errno; + errno = old_errno; - return( 0 ); - } /* Debug1 */ + return (0); +} /* Debug1 */ /* ************************************************************************** ** @@ -209,12 +213,13 @@ va_dcl * * ************************************************************************** ** */ -static void bufr_print( void ) - { - format_bufr[format_pos] = '\0'; - (void)Debug1( "%s", format_bufr ); - format_pos = 0; - } /* bufr_print */ +static void +bufr_print (void) +{ + format_bufr[format_pos] = '\0'; + (void) Debug1 ("%s", format_bufr); + format_pos = 0; +} /* bufr_print */ /* ************************************************************************** ** * Format the debug message text. @@ -233,42 +238,42 @@ static void bufr_print( void ) * * ************************************************************************** ** */ -static void format_debug_text( char *msg ) - { - size_t i; - BOOL timestamp = (!stdout_logging && (lp_timestamp_logs() || - !(lp_loaded()))); +static void +format_debug_text (char *msg) +{ + size_t i; + BOOL timestamp = (!stdout_logging && (lp_timestamp_logs () || !(lp_loaded ()))); - for( i = 0; msg[i]; i++ ) + for (i = 0; msg[i]; i++) { - /* Indent two spaces at each new line. */ - if(timestamp && 0 == format_pos) - { - format_bufr[0] = format_bufr[1] = ' '; - format_pos = 2; - } - - /* If there's room, copy the character to the format buffer. */ - if( format_pos < FORMAT_BUFR_MAX ) - format_bufr[format_pos++] = msg[i]; - - /* If a newline is encountered, print & restart. */ - if( '\n' == msg[i] ) - bufr_print(); - - /* If the buffer is full dump it out, reset it, and put out a line - * continuation indicator. - */ - if( format_pos >= FORMAT_BUFR_MAX ) - { - bufr_print(); - (void)Debug1( " +>\n" ); - } + /* Indent two spaces at each new line. */ + if (timestamp && 0 == format_pos) + { + format_bufr[0] = format_bufr[1] = ' '; + format_pos = 2; + } + + /* If there's room, copy the character to the format buffer. */ + if (format_pos < FORMAT_BUFR_MAX) + format_bufr[format_pos++] = msg[i]; + + /* If a newline is encountered, print & restart. */ + if ('\n' == msg[i]) + bufr_print (); + + /* If the buffer is full dump it out, reset it, and put out a line + * continuation indicator. + */ + if (format_pos >= FORMAT_BUFR_MAX) + { + bufr_print (); + (void) Debug1 (" +>\n"); + } } - /* Just to be safe... */ - format_bufr[format_pos] = '\0'; - } /* format_debug_text */ + /* Just to be safe... */ + format_bufr[format_pos] = '\0'; +} /* format_debug_text */ /* ************************************************************************** ** * Flush debug output, including the format buffer content. @@ -278,11 +283,12 @@ static void format_debug_text( char *msg ) * * ************************************************************************** ** */ -void dbgflush( void ) - { - bufr_print(); - (void)fflush( dbf ); - } /* dbgflush */ +void +dbgflush (void) +{ + bufr_print (); + (void) fflush (dbf); +} /* dbgflush */ /* ************************************************************************** ** * Print a Debug Header. @@ -306,38 +312,38 @@ void dbgflush( void ) * * ************************************************************************** ** */ -BOOL dbghdr( int level, const char *file, const char *func, int line ) - { - if( format_pos ) +BOOL +dbghdr (int level, const char *file, const char *func, int line) +{ + if (format_pos) { - /* This is a fudge. If there is stuff sitting in the format_bufr, then - * the *right* thing to do is to call - * format_debug_text( "\n" ); - * to write the remainder, and then proceed with the new header. - * Unfortunately, there are several places in the code at which - * the DEBUG() macro is used to build partial lines. That in mind, - * we'll work under the assumption that an incomplete line indicates - * that a new header is *not* desired. - */ - return( True ); + /* This is a fudge. If there is stuff sitting in the format_bufr, then + * the *right* thing to do is to call + * format_debug_text( "\n" ); + * to write the remainder, and then proceed with the new header. + * Unfortunately, there are several places in the code at which + * the DEBUG() macro is used to build partial lines. That in mind, + * we'll work under the assumption that an incomplete line indicates + * that a new header is *not* desired. + */ + return (True); } - /* Don't print a header if we're logging to stdout. */ - if( stdout_logging ) - return( True ); + /* Don't print a header if we're logging to stdout. */ + if (stdout_logging) + return (True); - /* Print the header if timestamps are turned on. If parameters are - * not yet loaded, then default to timestamps on. - */ - if( lp_timestamp_logs() || !(lp_loaded()) ) + /* Print the header if timestamps are turned on. If parameters are + * not yet loaded, then default to timestamps on. + */ + if (lp_timestamp_logs () || !(lp_loaded ())) { - /* Print it all out at once to prevent split syslog output. */ - (void)Debug1( "[%s, %d] %s:%s(%d)\n", - timestring(), level, file, func, line ); + /* Print it all out at once to prevent split syslog output. */ + (void) Debug1 ("[%s, %d] %s:%s(%d)\n", timestring (), level, file, func, line); } - return( True ); - } /* dbghdr */ + return (True); +} /* dbghdr */ /* ************************************************************************** ** * Add text to the body of the "current" debug message via the format buffer. @@ -353,37 +359,39 @@ BOOL dbghdr( int level, const char *file, const char *func, int line ) * ************************************************************************** ** */ #ifdef HAVE_STDARG_H - BOOL dbgtext( const char *format_str, ... ) - { - va_list ap; - pstring msgbuf; +BOOL +dbgtext (const char *format_str, ...) +{ + va_list ap; + pstring msgbuf; - va_start( ap, format_str ); - vslprintf( msgbuf, sizeof(msgbuf)-1, format_str, ap ); - va_end( ap ); + va_start (ap, format_str); + vslprintf (msgbuf, sizeof (msgbuf) - 1, format_str, ap); + va_end (ap); - format_debug_text( msgbuf ); + format_debug_text (msgbuf); - return( True ); - } /* dbgtext */ + return (True); +} /* dbgtext */ #else - BOOL dbgtext( va_alist ) - va_dcl - { - char *format_str; - va_list ap; - pstring msgbuf; - - va_start( ap ); - format_str = va_arg( ap, char * ); - vslprintf( msgbuf, sizeof(msgbuf)-1, format_str, ap ); - va_end( ap ); - - format_debug_text( msgbuf ); - - return( True ); - } /* dbgtext */ +BOOL +dbgtext (va_alist) + va_dcl +{ + char *format_str; + va_list ap; + pstring msgbuf; + + va_start (ap); + format_str = va_arg (ap, char *); + vslprintf (msgbuf, sizeof (msgbuf) - 1, format_str, ap); + va_end (ap); + + format_debug_text (msgbuf); + + return (True); +} /* dbgtext */ #endif diff --git a/src/vfs/smbfs/helpers/lib/interface.c b/src/vfs/smbfs/helpers/lib/interface.c index 6c79b8f35..9244f6a9d 100644 --- a/src/vfs/smbfs/helpers/lib/interface.c +++ b/src/vfs/smbfs/helpers/lib/interface.c @@ -22,7 +22,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . -*/ + */ #include "includes.h" @@ -34,11 +34,11 @@ struct in_addr loopback_ip; static struct in_addr default_ip; static struct in_addr default_bcast; static struct in_addr default_nmask; -static BOOL got_ip=False; -static BOOL got_bcast=False; -static BOOL got_nmask=False; +static BOOL got_ip = False; +static BOOL got_bcast = False; +static BOOL got_nmask = False; -static struct interface *local_interfaces = NULL; +static struct interface *local_interfaces = NULL; struct interface *last_iface; @@ -47,31 +47,33 @@ struct interface *last_iface; /**************************************************************************** calculate the default netmask for an address ****************************************************************************/ -static void default_netmask(struct in_addr *inm, struct in_addr *iad) +static void +default_netmask (struct in_addr *inm, struct in_addr *iad) { - /* - ** Guess a netmask based on the class of the IP address given. - */ - switch((ntohl(iad->s_addr) & 0xE0000000)) { - case 0x00000000: /* Class A addr */ - case 0x20000000: - case 0x40000000: - case 0x60000000: - inm->s_addr = htonl(0xFF000000); - break; - - case 0x80000000: /* Class B addr */ - case 0xA0000000: - inm->s_addr = htonl(0xFFFF0000); - break; - - case 0xC0000000: /* Class C addr */ - inm->s_addr = htonl(0xFFFFFF00); - break; - - default: /* ??? */ - inm->s_addr = htonl(0xFFFFFFF0); - } + /* + ** Guess a netmask based on the class of the IP address given. + */ + switch ((ntohl (iad->s_addr) & 0xE0000000)) + { + case 0x00000000: /* Class A addr */ + case 0x20000000: + case 0x40000000: + case 0x60000000: + inm->s_addr = htonl (0xFF000000); + break; + + case 0x80000000: /* Class B addr */ + case 0xA0000000: + inm->s_addr = htonl (0xFFFF0000); + break; + + case 0xC0000000: /* Class C addr */ + inm->s_addr = htonl (0xFFFFFF00); + break; + + default: /* ??? */ + inm->s_addr = htonl (0xFFFFFFF0); + } } @@ -79,48 +81,52 @@ static void default_netmask(struct in_addr *inm, struct in_addr *iad) get the broadcast address for our address (troyer@saifr00.ateng.az.honeywell.com) ****************************************************************************/ -static void get_broadcast(struct in_addr *if_ipaddr, - struct in_addr *if_bcast, - struct in_addr *if_nmask) -{ - uint32 nm; - short onbc; - short offbc; - - /* get a default netmask and broadcast */ - default_netmask(if_nmask, if_ipaddr); - - get_netmask(if_ipaddr, if_nmask); - - /* sanity check on the netmask */ - nm = ntohl(if_nmask->s_addr); - onbc = 0; - offbc = 0; - while((onbc + offbc) < 32) { - if(nm & 0x80000000) { - onbc++; - if(offbc) { - /* already found an off bit, so mask - is wrong */ - onbc = 34; - } - } else { - offbc++; - } - nm <<= 1; - } - if ((onbc < 8)||(onbc == 34)) { - DEBUG(0,("Impossible netmask %s - using defaults\n", - inet_ntoa(*if_nmask))); - default_netmask(if_nmask, if_ipaddr); - } - - /* derive the broadcast assuming a 1's broadcast, as this is what - all MS operating systems do, we have to comply even if the unix - box is setup differently */ - if_bcast->s_addr = MKBCADDR(if_ipaddr->s_addr, if_nmask->s_addr); - - DEBUG(4,("Derived broadcast address %s\n", inet_ntoa(*if_bcast))); +static void +get_broadcast (struct in_addr *if_ipaddr, struct in_addr *if_bcast, struct in_addr *if_nmask) +{ + uint32 nm; + short onbc; + short offbc; + + /* get a default netmask and broadcast */ + default_netmask (if_nmask, if_ipaddr); + + get_netmask (if_ipaddr, if_nmask); + + /* sanity check on the netmask */ + nm = ntohl (if_nmask->s_addr); + onbc = 0; + offbc = 0; + while ((onbc + offbc) < 32) + { + if (nm & 0x80000000) + { + onbc++; + if (offbc) + { + /* already found an off bit, so mask + is wrong */ + onbc = 34; + } + } + else + { + offbc++; + } + nm <<= 1; + } + if ((onbc < 8) || (onbc == 34)) + { + DEBUG (0, ("Impossible netmask %s - using defaults\n", inet_ntoa (*if_nmask))); + default_netmask (if_nmask, if_ipaddr); + } + + /* derive the broadcast assuming a 1's broadcast, as this is what + all MS operating systems do, we have to comply even if the unix + box is setup differently */ + if_bcast->s_addr = MKBCADDR (if_ipaddr->s_addr, if_nmask->s_addr); + + DEBUG (4, ("Derived broadcast address %s\n", inet_ntoa (*if_bcast))); } @@ -128,220 +134,258 @@ static void get_broadcast(struct in_addr *if_ipaddr, /**************************************************************************** load a list of network interfaces ****************************************************************************/ -static void interpret_interfaces(char *s, struct interface **interfaces, - const char *description) +static void +interpret_interfaces (char *s, struct interface **interfaces, const char *description) { - char *ptr; - fstring token; - struct interface *iface; - struct in_addr ip; + char *ptr; + fstring token; + struct interface *iface; + struct in_addr ip; - ptr = s; - ipzero = *interpret_addr2("0.0.0.0"); - allones_ip = *interpret_addr2("255.255.255.255"); - loopback_ip = *interpret_addr2("127.0.0.1"); + ptr = s; + ipzero = *interpret_addr2 ("0.0.0.0"); + allones_ip = *interpret_addr2 ("255.255.255.255"); + loopback_ip = *interpret_addr2 ("127.0.0.1"); - while (next_token(&ptr,token,NULL,sizeof(token))) { - /* parse it into an IP address/netmasklength pair */ - char *p = strchr(token,'/'); - if (p) *p++ = 0; + while (next_token (&ptr, token, NULL, sizeof (token))) + { + /* parse it into an IP address/netmasklength pair */ + char *p = strchr (token, '/'); + if (p) + *p++ = 0; + + ip = *interpret_addr2 (token); + + /* maybe we already have it listed */ + { + struct interface *i; + for (i = (*interfaces); i; i = i->next) + if (ip_equal (ip, i->ip)) + break; + if (i) + continue; + } + + iface = (struct interface *) malloc (sizeof (*iface)); + if (!iface) + return; + + iface->ip = ip; + + if (p) + { + if (strlen (p) > 2) + iface->nmask = *interpret_addr2 (p); + else + iface->nmask.s_addr = htonl (((ALLONES >> atoi (p)) ^ ALLONES)); + } + else + { + default_netmask (&iface->nmask, &iface->ip); + } + iface->bcast.s_addr = MKBCADDR (iface->ip.s_addr, iface->nmask.s_addr); + iface->next = NULL; - ip = *interpret_addr2(token); + if (!(*interfaces)) + { + (*interfaces) = iface; + } + else + { + last_iface->next = iface; + } + last_iface = iface; + DEBUG (2, ("Added %s ip=%s ", description, inet_ntoa (iface->ip))); + DEBUG (2, ("bcast=%s ", inet_ntoa (iface->bcast))); + DEBUG (2, ("nmask=%s\n", inet_ntoa (iface->nmask))); + } + + if (*interfaces) + return; + + /* setup a default interface */ + iface = (struct interface *) malloc (sizeof (*iface)); + if (!iface) + return; + + iface->next = NULL; - /* maybe we already have it listed */ + if (got_ip) { - struct interface *i; - for (i=(*interfaces);i;i=i->next) - if (ip_equal(ip,i->ip)) break; - if (i) continue; + iface->ip = default_ip; + } + else + { + get_myname (NULL, &iface->ip); } - iface = (struct interface *)malloc(sizeof(*iface)); - if (!iface) return; + if (got_bcast) + { + iface->bcast = default_bcast; + } + else + { + get_broadcast (&iface->ip, &iface->bcast, &iface->nmask); + } - iface->ip = ip; + if (got_nmask) + { + iface->nmask = default_nmask; + iface->bcast.s_addr = MKBCADDR (iface->ip.s_addr, iface->nmask.s_addr); + } - if (p) { - if (strlen(p) > 2) - iface->nmask = *interpret_addr2(p); - else - iface->nmask.s_addr = htonl(((ALLONES >> atoi(p)) ^ ALLONES)); - } else { - default_netmask(&iface->nmask,&iface->ip); + if (iface->bcast.s_addr != MKBCADDR (iface->ip.s_addr, iface->nmask.s_addr)) + { + DEBUG (2, ("Warning: inconsistant interface %s\n", inet_ntoa (iface->ip))); } - iface->bcast.s_addr = MKBCADDR(iface->ip.s_addr, iface->nmask.s_addr); + iface->next = NULL; + (*interfaces) = last_iface = iface; - if (!(*interfaces)) { - (*interfaces) = iface; - } else { - last_iface->next = iface; - } - last_iface = iface; - DEBUG(2,("Added %s ip=%s ",description,inet_ntoa(iface->ip))); - DEBUG(2,("bcast=%s ",inet_ntoa(iface->bcast))); - DEBUG(2,("nmask=%s\n",inet_ntoa(iface->nmask))); - } - - if (*interfaces) return; - - /* setup a default interface */ - iface = (struct interface *)malloc(sizeof(*iface)); - if (!iface) return; - - iface->next = NULL; - - if (got_ip) { - iface->ip = default_ip; - } else { - get_myname(NULL,&iface->ip); - } - - if (got_bcast) { - iface->bcast = default_bcast; - } else { - get_broadcast(&iface->ip,&iface->bcast,&iface->nmask); - } - - if (got_nmask) { - iface->nmask = default_nmask; - iface->bcast.s_addr = MKBCADDR(iface->ip.s_addr, iface->nmask.s_addr); - } - - if (iface->bcast.s_addr != MKBCADDR(iface->ip.s_addr, iface->nmask.s_addr)) { - DEBUG(2,("Warning: inconsistant interface %s\n",inet_ntoa(iface->ip))); - } - - iface->next = NULL; - (*interfaces) = last_iface = iface; - - DEBUG(2,("Added interface ip=%s ",inet_ntoa(iface->ip))); - DEBUG(2,("bcast=%s ",inet_ntoa(iface->bcast))); - DEBUG(2,("nmask=%s\n",inet_ntoa(iface->nmask))); + DEBUG (2, ("Added interface ip=%s ", inet_ntoa (iface->ip))); + DEBUG (2, ("bcast=%s ", inet_ntoa (iface->bcast))); + DEBUG (2, ("nmask=%s\n", inet_ntoa (iface->nmask))); } /**************************************************************************** load the remote and local interfaces ****************************************************************************/ -void load_interfaces(void) +void +load_interfaces (void) { - /* add the machine's interfaces to local interface structure*/ - interpret_interfaces(lp_interfaces(), &local_interfaces,"interface"); + /* add the machine's interfaces to local interface structure */ + interpret_interfaces (lp_interfaces (), &local_interfaces, "interface"); } /**************************************************************************** override the defaults **************************************************************************/ -void iface_set_default(char *ip,char *bcast,char *nmask) +void +iface_set_default (char *ip, char *bcast, char *nmask) { - if (ip) { - got_ip = True; - default_ip = *interpret_addr2(ip); - } - - if (bcast) { - got_bcast = True; - default_bcast = *interpret_addr2(bcast); - } - - if (nmask) { - got_nmask = True; - default_nmask = *interpret_addr2(nmask); - } + if (ip) + { + got_ip = True; + default_ip = *interpret_addr2 (ip); + } + + if (bcast) + { + got_bcast = True; + default_bcast = *interpret_addr2 (bcast); + } + + if (nmask) + { + got_nmask = True; + default_nmask = *interpret_addr2 (nmask); + } } /**************************************************************************** check if an IP is one of mine **************************************************************************/ -BOOL ismyip(struct in_addr ip) +BOOL +ismyip (struct in_addr ip) { - struct interface *i; - for (i=local_interfaces;i;i=i->next) - if (ip_equal(i->ip,ip)) return True; - return False; + struct interface *i; + for (i = local_interfaces; i; i = i->next) + if (ip_equal (i->ip, ip)) + return True; + return False; } /**************************************************************************** check if a packet is from a local (known) net **************************************************************************/ -BOOL is_local_net(struct in_addr from) +BOOL +is_local_net (struct in_addr from) { - struct interface *i; - for (i=local_interfaces;i;i=i->next) - if((from.s_addr & i->nmask.s_addr) == (i->ip.s_addr & i->nmask.s_addr)) - return True; - return False; + struct interface *i; + for (i = local_interfaces; i; i = i->next) + if ((from.s_addr & i->nmask.s_addr) == (i->ip.s_addr & i->nmask.s_addr)) + return True; + return False; } /**************************************************************************** how many interfaces do we have **************************************************************************/ -int iface_count(void) +int +iface_count (void) { - int ret = 0; - struct interface *i; + int ret = 0; + struct interface *i; - for (i=local_interfaces;i;i=i->next) - ret++; - return ret; + for (i = local_interfaces; i; i = i->next) + ret++; + return ret; } /**************************************************************************** True if we have two or more interfaces. **************************************************************************/ -BOOL we_are_multihomed(void) +BOOL +we_are_multihomed (void) { - static int multi = -1; + static int multi = -1; - if(multi == -1) - multi = (iface_count() > 1 ? True : False); + if (multi == -1) + multi = (iface_count () > 1 ? True : False); - return multi; + return multi; } /**************************************************************************** return the Nth interface **************************************************************************/ -struct interface *get_interface(int n) -{ - struct interface *i; - - for (i=local_interfaces;i && n;i=i->next) - n--; - - if (i) return i; - return NULL; +struct interface * +get_interface (int n) +{ + struct interface *i; + + for (i = local_interfaces; i && n; i = i->next) + n--; + + if (i) + return i; + return NULL; } /**************************************************************************** return IP of the Nth interface **************************************************************************/ -struct in_addr *iface_n_ip(int n) +struct in_addr * +iface_n_ip (int n) { - struct interface *i; - - for (i=local_interfaces;i && n;i=i->next) - n--; + struct interface *i; + + for (i = local_interfaces; i && n; i = i->next) + n--; - if (i) return &i->ip; - return NULL; + if (i) + return &i->ip; + return NULL; } /**************************************************************************** Try and find an interface that matches an ip. If we cannot, return NULL **************************************************************************/ -static struct interface *iface_find(struct in_addr ip) +static struct interface * +iface_find (struct in_addr ip) { - struct interface *i; - if (zero_ip(ip)) return local_interfaces; + struct interface *i; + if (zero_ip (ip)) + return local_interfaces; - for (i=local_interfaces;i;i=i->next) - if (same_net(i->ip,ip,i->nmask)) return i; + for (i = local_interfaces; i; i = i->next) + if (same_net (i->ip, ip, i->nmask)) + return i; - return NULL; + return NULL; } @@ -351,18 +395,20 @@ used to detect a change in interfaces to tell us whether to discard the current wins.dat file. Note that the result is independent of the order of the interfaces **************************************************************************/ -unsigned iface_hash(void) +unsigned +iface_hash (void) { - unsigned ret = 0; - struct interface *i; + unsigned ret = 0; + struct interface *i; - for (i=local_interfaces;i;i=i->next) { - unsigned x1 = (unsigned)str_checksum(inet_ntoa(i->ip)); - unsigned x2 = (unsigned)str_checksum(inet_ntoa(i->nmask)); - ret ^= (x1 ^ x2); - } + for (i = local_interfaces; i; i = i->next) + { + unsigned x1 = (unsigned) str_checksum (inet_ntoa (i->ip)); + unsigned x2 = (unsigned) str_checksum (inet_ntoa (i->nmask)); + ret ^= (x1 ^ x2); + } - return ret; + return ret; } @@ -371,17 +417,16 @@ unsigned iface_hash(void) an appropriate interface they return the requested field of the first known interface. */ -struct in_addr *iface_bcast(struct in_addr ip) +struct in_addr * +iface_bcast (struct in_addr ip) { - struct interface *i = iface_find(ip); - return(i ? &i->bcast : &local_interfaces->bcast); + struct interface *i = iface_find (ip); + return (i ? &i->bcast : &local_interfaces->bcast); } -struct in_addr *iface_ip(struct in_addr ip) +struct in_addr * +iface_ip (struct in_addr ip) { - struct interface *i = iface_find(ip); - return(i ? &i->ip : &local_interfaces->ip); + struct interface *i = iface_find (ip); + return (i ? &i->ip : &local_interfaces->ip); } - - - diff --git a/src/vfs/smbfs/helpers/lib/kanji.c b/src/vfs/smbfs/helpers/lib/kanji.c dissimilarity index 60% index 9695c125a..05dda1fd0 100644 --- a/src/vfs/smbfs/helpers/lib/kanji.c +++ b/src/vfs/smbfs/helpers/lib/kanji.c @@ -1,1240 +1,1501 @@ -/* - Unix SMB/Netbios implementation. - Version 1.9. - Kanji Extensions - - Copyright (C) Andrew Tridgell 1992-1998 - - Copyright (C) 2011 - The Free Software Foundation, Inc. - - Adding for Japanese language by 1994.9.5 - and extend coding system to EUC/SJIS/JIS/HEX at 1994.10.11 - and add all jis codes sequence type at 1995.8.16 - Notes: Hexadecimal code by - - This file is part of the Midnight Commander. - - The Midnight Commander is free software: you can redistribute it - and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of the License, - or (at your option) any later version. - - The Midnight Commander is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#define _KANJI_C_ -#include "includes.h" - -/* - * Function pointers that get overridden when multi-byte code pages - * are loaded. - */ - -const char *(*multibyte_strchr)(const char *, int ) = (const char *(*)(const char *, int )) strchr; -const char *(*multibyte_strrchr)(const char *, int ) = (const char *(*)(const char *, int )) strrchr; -const char *(*multibyte_strstr)(const char *, const char *) = (const char *(*)(const char *, const char *)) strstr; -char *(*multibyte_strtok)(char *, const char *) = (char *(*)(char *, const char *)) strtok; - -/* - * Kanji is treated differently here due to historical accident of - * it being the first non-English codepage added to Samba. - * The define 'KANJI' is being overloaded to mean 'use kanji codepage - * by default' and also 'this is the filename-to-disk conversion - * method to use'. This really should be removed and all control - * over this left in the smb.conf parameters 'client codepage' - * and 'coding system'. - */ - -#ifndef KANJI - -/* - * Set the default conversion to be the functions in - * charcnv.c. - */ - -static size_t skip_non_multibyte_char(char); -static BOOL not_multibyte_char_1(char); - -char *(*_dos_to_unix)(char *, BOOL) = dos2unix_format; -char *(*_unix_to_dos)(char *, BOOL) = unix2dos_format; -size_t (*_skip_multibyte_char)(char) = skip_non_multibyte_char; -BOOL (*is_multibyte_char_1)(char) = not_multibyte_char_1; - -#else /* KANJI */ - -/* - * Set the default conversion to be the function - * sj_to_sj in this file. - */ - -static char *sj_to_sj(char *from, BOOL overwrite); -static size_t skip_kanji_multibyte_char(char); -static BOOL is_kanji_multibyte_char_1(char); - -char *(*_dos_to_unix)(char *, BOOL) = sj_to_sj; -char *(*_unix_to_dos)(char *, BOOL) = sj_to_sj; -size_t (*_skip_multibyte_char)(char) = skip_kanji_multibyte_char; -int (*is_multibyte_char_1)(char) = is_kanji_multibyte_char_1; - -#endif /* KANJI */ - -/* jis si/so sequence */ -static char jis_kso = JIS_KSO; -static char jis_ksi = JIS_KSI; -static char hex_tag = HEXTAG; - -/******************************************************************* - SHIFT JIS functions -********************************************************************/ - -/******************************************************************* - search token from S1 separated any char of S2 - S1 contains SHIFT JIS chars. -********************************************************************/ - -static char *sj_strtok(char *s1, const char *s2) -{ - static char *s = NULL; - char *q; - if (!s1) { - if (!s) { - return NULL; - } - s1 = s; - } - for (q = s1; *s1; ) { - if (is_shift_jis (*s1)) { - s1 += 2; - } else if (is_kana (*s1)) { - s1++; - } else { - char *p = strchr (s2, *s1); - if (p) { - if (s1 != q) { - s = s1 + 1; - *s1 = '\0'; - return q; - } - q = s1 + 1; - } - s1++; - } - } - s = NULL; - if (*q) { - return q; - } - return NULL; -} - -/******************************************************************* - search string S2 from S1 - S1 contains SHIFT JIS chars. -********************************************************************/ - -static const char *sj_strstr(const char *s1, const char *s2) -{ - size_t len = strlen (s2); - if (!*s2) - return (const char *) s1; - for (;*s1;) { - if (*s1 == *s2) { - if (strncmp (s1, s2, len) == 0) - return (const char *) s1; - } - if (is_shift_jis (*s1)) { - s1 += 2; - } else { - s1++; - } - } - return NULL; -} - -/******************************************************************* - Search char C from beginning of S. - S contains SHIFT JIS chars. -********************************************************************/ - -static const char *sj_strchr (const char *s, int c) -{ - for (; *s; ) { - if (*s == c) - return (const char *) s; - if (is_shift_jis (*s)) { - s += 2; - } else { - s++; - } - } - return NULL; -} - -/******************************************************************* - Search char C end of S. - S contains SHIFT JIS chars. -********************************************************************/ - -static const char *sj_strrchr(const char *s, int c) -{ - const char *q; - - for (q = 0; *s; ) { - if (*s == c) { - q = (const char *) s; - } - if (is_shift_jis (*s)) { - s += 2; - } else { - s++; - } - } - return q; -} - -/******************************************************************* - Kanji multibyte char skip function. -*******************************************************************/ - -static size_t skip_kanji_multibyte_char(char c) -{ - if(is_shift_jis(c)) { - return 2; - } else if (is_kana(c)) { - return 1; - } - return 0; -} - -/******************************************************************* - Kanji multibyte char identification. -*******************************************************************/ - -static BOOL is_kanji_multibyte_char_1(char c) -{ - return is_shift_jis(c); -} - -/******************************************************************* - The following functions are the only ones needed to do multibyte - support for Hangul, Big5 and Simplified Chinese. Most of the - real work for these codepages is done in the generic multibyte - functions. The only reason these functions are needed at all - is that the is_xxx(c) calls are really preprocessor macros. -********************************************************************/ - -/******************************************************************* - Hangul (Korean - code page 949) function. -********************************************************************/ - -static BOOL hangul_is_multibyte_char_1(char c) -{ - return is_hangul(c); -} - -/******************************************************************* - Big5 Traditional Chinese (code page 950) function. -********************************************************************/ - -static BOOL big5_is_multibyte_char_1(char c) -{ - return is_big5_c1(c); -} - -/******************************************************************* - Simplified Chinese (code page 936) function. -********************************************************************/ - -static BOOL simpch_is_multibyte_char_1(char c) -{ - return is_simpch_c1(c); -} - -/******************************************************************* - Generic multibyte functions - used by Hangul, Big5 and Simplified - Chinese codepages. -********************************************************************/ - -/******************************************************************* - search token from S1 separated any char of S2 - S1 contains generic multibyte chars. -********************************************************************/ - -static char *generic_multibyte_strtok(char *s1, const char *s2) -{ - static char *s = NULL; - char *q; - if (!s1) { - if (!s) { - return NULL; - } - s1 = s; - } - for (q = s1; *s1; ) { - if ((*is_multibyte_char_1)(*s1)) { - s1 += 2; - } else { - char *p = strchr (s2, *s1); - if (p) { - if (s1 != q) { - s = s1 + 1; - *s1 = '\0'; - return q; - } - q = s1 + 1; - } - s1++; - } - } - s = NULL; - if (*q) { - return q; - } - return NULL; -} - -/******************************************************************* - search string S2 from S1 - S1 contains generic multibyte chars. -********************************************************************/ - -static const char *generic_multibyte_strstr(const char *s1, const char *s2) -{ - size_t len = strlen (s2); - if (!*s2) - return (const char *) s1; - for (;*s1;) { - if (*s1 == *s2) { - if (strncmp (s1, s2, len) == 0) - return (const char *) s1; - } - if ((*is_multibyte_char_1)(*s1)) { - s1 += 2; - } else { - s1++; - } - } - return NULL; -} - -/******************************************************************* - Search char C from beginning of S. - S contains generic multibyte chars. -********************************************************************/ - -static const char *generic_multibyte_strchr(const char *s, int c) -{ - for (; *s; ) { - if (*s == c) - return (const char *) s; - if ((*is_multibyte_char_1)(*s)) { - s += 2; - } else { - s++; - } - } - return NULL; -} - -/******************************************************************* - Search char C end of S. - S contains generic multibyte chars. -********************************************************************/ - -static const char *generic_multibyte_strrchr(const char *s, int c) -{ - const char *q; - - for (q = 0; *s; ) { - if (*s == c) { - q = (const char *) s; - } - if ((*is_multibyte_char_1)(*s)) { - s += 2; - } else { - s++; - } - } - return q; -} - -/******************************************************************* - Generic multibyte char skip function. -*******************************************************************/ - -static size_t skip_generic_multibyte_char(char c) -{ - if( (*is_multibyte_char_1)(c)) { - return 2; - } - return 0; -} - -/******************************************************************* - Code conversion -********************************************************************/ - -/* convesion buffer */ -static char cvtbuf[1024]; - -/******************************************************************* - EUC <-> SJIS -********************************************************************/ - -static int euc2sjis (int hi, int lo) -{ - if (hi & 1) - return ((hi / 2 + (hi < 0xdf ? 0x31 : 0x71)) << 8) | - (lo - (lo >= 0xe0 ? 0x60 : 0x61)); - else - return ((hi / 2 + (hi < 0xdf ? 0x30 : 0x70)) << 8) | (lo - 2); -} - -static int sjis2euc (int hi, int lo) -{ - if (lo >= 0x9f) - return ((hi * 2 - (hi >= 0xe0 ? 0xe0 : 0x60)) << 8) | (lo + 2); - else - return ((hi * 2 - (hi >= 0xe0 ? 0xe1 : 0x61)) << 8) | - (lo + (lo >= 0x7f ? 0x60 : 0x61)); -} - -/******************************************************************* - Convert FROM contain SHIFT JIS codes to EUC codes - return converted buffer -********************************************************************/ - -static char *sj_to_euc(char *from, BOOL overwrite) -{ - char *out; - char *save; - - save = (char *) from; - for (out = cvtbuf; *from;) { - if (is_shift_jis (*from)) { - int code = sjis2euc ((int) from[0] & 0xff, (int) from[1] & 0xff); - *out++ = (code >> 8) & 0xff; - *out++ = code; - from += 2; - } else if (is_kana (*from)) { - *out++ = (char)euc_kana; - *out++ = *from++; - } else { - *out++ = *from++; - } - } - *out = 0; - if (overwrite) { - pstrcpy((char *) save, (char *) cvtbuf); - return (char *) save; - } else { - return cvtbuf; - } -} - -/******************************************************************* - Convert FROM contain EUC codes to SHIFT JIS codes - return converted buffer -********************************************************************/ - -static char *euc_to_sj(char *from, BOOL overwrite) -{ - char *out; - char *save; - - save = (char *) from; - for (out = cvtbuf; *from; ) { - if (is_euc (*from)) { - int code = euc2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff); - *out++ = (code >> 8) & 0xff; - *out++ = code; - from += 2; - } else if (is_euc_kana (*from)) { - *out++ = from[1]; - from += 2; - } else { - *out++ = *from++; - } - } - *out = 0; - if (overwrite) { - pstrcpy(save, (char *) cvtbuf); - return save; - } else { - return cvtbuf; - } -} - -/******************************************************************* - JIS7,JIS8,JUNET <-> SJIS -********************************************************************/ - -static int sjis2jis(int hi, int lo) -{ - if (lo >= 0x9f) - return ((hi * 2 - (hi >= 0xe0 ? 0x160 : 0xe0)) << 8) | (lo - 0x7e); - else - return ((hi * 2 - (hi >= 0xe0 ? 0x161 : 0xe1)) << 8) | - (lo - (lo >= 0x7f ? 0x20 : 0x1f)); -} - -static int jis2sjis(int hi, int lo) -{ - if (hi & 1) - return ((hi / 2 + (hi < 0x5f ? 0x71 : 0xb1)) << 8) | - (lo + (lo >= 0x60 ? 0x20 : 0x1f)); - else - return ((hi / 2 + (hi < 0x5f ? 0x70 : 0xb0)) << 8) | (lo + 0x7e); -} - -/******************************************************************* - Convert FROM contain JIS codes to SHIFT JIS codes - return converted buffer -********************************************************************/ - -static char *jis8_to_sj(char *from, BOOL overwrite) -{ - char *out; - int shifted; - char *save; - - shifted = _KJ_ROMAN; - save = (char *) from; - for (out = cvtbuf; *from;) { - if (is_esc (*from)) { - if (is_so1 (from[1]) && is_so2 (from[2])) { - shifted = _KJ_KANJI; - from += 3; - } else if (is_si1 (from[1]) && is_si2 (from[2])) { - shifted = _KJ_ROMAN; - from += 3; - } else { /* sequence error */ - goto normal; - } - } else { - normal: - switch (shifted) { - default: - case _KJ_ROMAN: - *out++ = *from++; - break; - case _KJ_KANJI: - { - int code = jis2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff); - *out++ = (code >> 8) & 0xff; - *out++ = code; - from += 2; - } - break; - } - } - } - *out = 0; - if (overwrite) { - pstrcpy (save, (char *) cvtbuf); - return save; - } else { - return cvtbuf; - } -} - -/******************************************************************* - Convert FROM contain SHIFT JIS codes to JIS codes - return converted buffer -********************************************************************/ - -static char *sj_to_jis8(char *from, BOOL overwrite) -{ - char *out; - int shifted; - char *save; - - shifted = _KJ_ROMAN; - save = (char *) from; - for (out = cvtbuf; *from; ) { - if (is_shift_jis (*from)) { - int code; - switch (shifted) { - case _KJ_ROMAN: /* to KANJI */ - *out++ = jis_esc; - *out++ = jis_so1; - *out++ = jis_kso; - shifted = _KJ_KANJI; - break; - } - code = sjis2jis ((int) from[0] & 0xff, (int) from[1] & 0xff); - *out++ = (code >> 8) & 0xff; - *out++ = code; - from += 2; - } else { - switch (shifted) { - case _KJ_KANJI: /* to ROMAN/KANA */ - *out++ = jis_esc; - *out++ = jis_si1; - *out++ = jis_ksi; - shifted = _KJ_ROMAN; - break; - } - *out++ = *from++; - } - } - switch (shifted) { - case _KJ_KANJI: /* to ROMAN/KANA */ - *out++ = jis_esc; - *out++ = jis_si1; - *out++ = jis_ksi; - shifted = _KJ_ROMAN; - break; - } - *out = 0; - if (overwrite) { - pstrcpy (save, (char *) cvtbuf); - return save; - } else { - return cvtbuf; - } -} - -/******************************************************************* - Convert FROM contain 7 bits JIS codes to SHIFT JIS codes - return converted buffer -********************************************************************/ -static char *jis7_to_sj(char *from, BOOL overwrite) -{ - char *out; - int shifted; - char *save; - - shifted = _KJ_ROMAN; - save = (char *) from; - for (out = cvtbuf; *from;) { - if (is_esc (*from)) { - if (is_so1 (from[1]) && is_so2 (from[2])) { - shifted = _KJ_KANJI; - from += 3; - } else if (is_si1 (from[1]) && is_si2 (from[2])) { - shifted = _KJ_ROMAN; - from += 3; - } else { /* sequence error */ - goto normal; - } - } else if (is_so (*from)) { - shifted = _KJ_KANA; /* to KANA */ - from++; - } else if (is_si (*from)) { - shifted = _KJ_ROMAN; /* to ROMAN */ - from++; - } else { - normal: - switch (shifted) { - default: - case _KJ_ROMAN: - *out++ = *from++; - break; - case _KJ_KANJI: - { - int code = jis2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff); - *out++ = (code >> 8) & 0xff; - *out++ = code; - from += 2; - } - break; - case _KJ_KANA: - *out++ = ((int) from[0]) + 0x80; - break; - } - } - } - *out = 0; - if (overwrite) { - pstrcpy (save, (char *) cvtbuf); - return save; - } else { - return cvtbuf; - } -} - -/******************************************************************* - Convert FROM contain SHIFT JIS codes to 7 bits JIS codes - return converted buffer -********************************************************************/ -static char *sj_to_jis7(char *from, BOOL overwrite) -{ - char *out; - int shifted; - char *save; - - shifted = _KJ_ROMAN; - save = (char *) from; - for (out = cvtbuf; *from; ) { - if (is_shift_jis (*from)) { - int code; - switch (shifted) { - case _KJ_KANA: - *out++ = jis_si; /* to ROMAN and through down */ - case _KJ_ROMAN: /* to KANJI */ - *out++ = jis_esc; - *out++ = jis_so1; - *out++ = jis_kso; - shifted = _KJ_KANJI; - break; - } - code = sjis2jis ((int) from[0] & 0xff, (int) from[1] & 0xff); - *out++ = (code >> 8) & 0xff; - *out++ = code; - from += 2; - } else if (is_kana (from[0])) { - switch (shifted) { - case _KJ_KANJI: /* to ROMAN */ - *out++ = jis_esc; - *out++ = jis_si1; - *out++ = jis_ksi; - case _KJ_ROMAN: /* to KANA */ - *out++ = jis_so; - shifted = _KJ_KANA; - break; - } - *out++ = ((int) *from++) - 0x80; - } else { - switch (shifted) { - case _KJ_KANA: - *out++ = jis_si; /* to ROMAN */ - shifted = _KJ_ROMAN; - break; - case _KJ_KANJI: /* to ROMAN */ - *out++ = jis_esc; - *out++ = jis_si1; - *out++ = jis_ksi; - shifted = _KJ_ROMAN; - break; - } - *out++ = *from++; - } - } - switch (shifted) { - case _KJ_KANA: - *out++ = jis_si; /* to ROMAN */ - break; - case _KJ_KANJI: /* to ROMAN */ - *out++ = jis_esc; - *out++ = jis_si1; - *out++ = jis_ksi; - break; - } - *out = 0; - if (overwrite) { - pstrcpy (save, (char *) cvtbuf); - return save; - } else { - return cvtbuf; - } -} - -/******************************************************************* - Convert FROM contain 7 bits JIS(junet) codes to SHIFT JIS codes - return converted buffer -********************************************************************/ -static char *junet_to_sj(char *from, BOOL overwrite) -{ - char *out; - int shifted; - char *save; - - shifted = _KJ_ROMAN; - save = (char *) from; - for (out = cvtbuf; *from;) { - if (is_esc (*from)) { - if (is_so1 (from[1]) && is_so2 (from[2])) { - shifted = _KJ_KANJI; - from += 3; - } else if (is_si1 (from[1]) && is_si2 (from[2])) { - shifted = _KJ_ROMAN; - from += 3; - } else if (is_juk1(from[1]) && is_juk2 (from[2])) { - shifted = _KJ_KANA; - from += 3; - } else { /* sequence error */ - goto normal; - } - } else { - normal: - switch (shifted) { - default: - case _KJ_ROMAN: - *out++ = *from++; - break; - case _KJ_KANJI: - { - int code = jis2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff); - *out++ = (code >> 8) & 0xff; - *out++ = code; - from += 2; - } - break; - case _KJ_KANA: - *out++ = ((int) from[0]) + 0x80; - break; - } - } - } - *out = 0; - if (overwrite) { - pstrcpy (save, (char *) cvtbuf); - return save; - } else { - return cvtbuf; - } -} - -/******************************************************************* - Convert FROM contain SHIFT JIS codes to 7 bits JIS(junet) codes - return converted buffer -********************************************************************/ -static char *sj_to_junet(char *from, BOOL overwrite) -{ - char *out; - int shifted; - char *save; - - shifted = _KJ_ROMAN; - save = (char *) from; - for (out = cvtbuf; *from; ) { - if (is_shift_jis (*from)) { - int code; - switch (shifted) { - case _KJ_KANA: - case _KJ_ROMAN: /* to KANJI */ - *out++ = jis_esc; - *out++ = jis_so1; - *out++ = jis_so2; - shifted = _KJ_KANJI; - break; - } - code = sjis2jis ((int) from[0] & 0xff, (int) from[1] & 0xff); - *out++ = (code >> 8) & 0xff; - *out++ = code; - from += 2; - } else if (is_kana (from[0])) { - switch (shifted) { - case _KJ_KANJI: /* to ROMAN */ - case _KJ_ROMAN: /* to KANA */ - *out++ = jis_esc; - *out++ = junet_kana1; - *out++ = junet_kana2; - shifted = _KJ_KANA; - break; - } - *out++ = ((int) *from++) - 0x80; - } else { - switch (shifted) { - case _KJ_KANA: - case _KJ_KANJI: /* to ROMAN */ - *out++ = jis_esc; - *out++ = jis_si1; - *out++ = jis_si2; - shifted = _KJ_ROMAN; - break; - } - *out++ = *from++; - } - } - switch (shifted) { - case _KJ_KANA: - case _KJ_KANJI: /* to ROMAN */ - *out++ = jis_esc; - *out++ = jis_si1; - *out++ = jis_si2; - break; - } - *out = 0; - if (overwrite) { - pstrcpy (save, (char *) cvtbuf); - return save; - } else { - return cvtbuf; - } -} - -/******************************************************************* - HEX <-> SJIS -********************************************************************/ -/* ":xx" -> a byte */ -static char *hex_to_sj(char *from, BOOL overwrite) -{ - char *sp, *dp; - - sp = (char *) from; - dp = cvtbuf; - while (*sp) { - if (*sp == hex_tag && isxdigit((int)sp[1]) && isxdigit((int)sp[2])) { - *dp++ = (hex2bin (sp[1])<<4) | (hex2bin (sp[2])); - sp += 3; - } else - *dp++ = *sp++; - } - *dp = '\0'; - if (overwrite) { - pstrcpy ((char *) from, (char *) cvtbuf); - return (char *) from; - } else { - return cvtbuf; - } -} - -/******************************************************************* - kanji/kana -> ":xx" -********************************************************************/ -static char *sj_to_hex(char *from, BOOL overwrite) -{ - unsigned char *sp, *dp; - - sp = (unsigned char*) from; - dp = (unsigned char*) cvtbuf; - while (*sp) { - if (is_kana(*sp)) { - *dp++ = hex_tag; - *dp++ = bin2hex (((*sp)>>4)&0x0f); - *dp++ = bin2hex ((*sp)&0x0f); - sp++; - } else if (is_shift_jis (*sp) && is_shift_jis2 (sp[1])) { - *dp++ = hex_tag; - *dp++ = bin2hex (((*sp)>>4)&0x0f); - *dp++ = bin2hex ((*sp)&0x0f); - sp++; - *dp++ = hex_tag; - *dp++ = bin2hex (((*sp)>>4)&0x0f); - *dp++ = bin2hex ((*sp)&0x0f); - sp++; - } else - *dp++ = *sp++; - } - *dp = '\0'; - if (overwrite) { - pstrcpy ((char *) from, (char *) cvtbuf); - return (char *) from; - } else { - return cvtbuf; - } -} - -/******************************************************************* - CAP <-> SJIS -********************************************************************/ -/* ":xx" CAP -> a byte */ -static char *cap_to_sj(char *from, BOOL overwrite) -{ - char *sp, *dp; - - sp = (char *) from; - dp = cvtbuf; - while (*sp) { - /* - * The only change between this and hex_to_sj is here. sj_to_cap only - * translates characters greater or equal to 0x80 - make sure that here - * we only do the reverse (that's why the strchr is used rather than - * isxdigit. Based on fix from ado@elsie.nci.nih.gov (Arthur David Olson). - */ - if (*sp == hex_tag && (strchr ("89abcdefABCDEF", sp[1]) != NULL) && isxdigit((int)sp[2])) { - *dp++ = (hex2bin (sp[1])<<4) | (hex2bin (sp[2])); - sp += 3; - } else - *dp++ = *sp++; - } - *dp = '\0'; - if (overwrite) { - pstrcpy ((char *) from, (char *) cvtbuf); - return (char *) from; - } else { - return cvtbuf; - } -} - -/******************************************************************* - kanji/kana -> ":xx" - CAP format. -********************************************************************/ -static char *sj_to_cap(char *from, BOOL overwrite) -{ - unsigned char *sp, *dp; - - sp = (unsigned char*) from; - dp = (unsigned char*) cvtbuf; - while (*sp) { - if (*sp >= 0x80) { - *dp++ = hex_tag; - *dp++ = bin2hex (((*sp)>>4)&0x0f); - *dp++ = bin2hex ((*sp)&0x0f); - sp++; - } else { - *dp++ = *sp++; - } - } - *dp = '\0'; - if (overwrite) { - pstrcpy ((char *) from, (char *) cvtbuf); - return (char *) from; - } else { - return cvtbuf; - } -} - -/******************************************************************* - sj to sj -********************************************************************/ -static char *sj_to_sj(char *from, BOOL overwrite) -{ - if (!overwrite) { - pstrcpy (cvtbuf, (char *) from); - return cvtbuf; - } else { - return (char *) from; - } -} - -/************************************************************************ - conversion: - _dos_to_unix _unix_to_dos -************************************************************************/ - -static void setup_string_function(int codes) -{ - switch (codes) { - default: - _dos_to_unix = dos2unix_format; - _unix_to_dos = unix2dos_format; - break; - - case SJIS_CODE: - _dos_to_unix = sj_to_sj; - _unix_to_dos = sj_to_sj; - break; - - case EUC_CODE: - _dos_to_unix = sj_to_euc; - _unix_to_dos = euc_to_sj; - break; - - case JIS7_CODE: - _dos_to_unix = sj_to_jis7; - _unix_to_dos = jis7_to_sj; - break; - - case JIS8_CODE: - _dos_to_unix = sj_to_jis8; - _unix_to_dos = jis8_to_sj; - break; - - case JUNET_CODE: - _dos_to_unix = sj_to_junet; - _unix_to_dos = junet_to_sj; - break; - - case HEX_CODE: - _dos_to_unix = sj_to_hex; - _unix_to_dos = hex_to_sj; - break; - - case CAP_CODE: - _dos_to_unix = sj_to_cap; - _unix_to_dos = cap_to_sj; - break; - } -} - -/************************************************************************ - Interpret coding system. -************************************************************************/ - -void interpret_coding_system(const char *str) -{ - int codes = UNKNOWN_CODE; - - if (strequal (str, "sjis")) { - codes = SJIS_CODE; - } else if (strequal (str, "euc")) { - codes = EUC_CODE; - } else if (strequal (str, "cap")) { - codes = CAP_CODE; - hex_tag = HEXTAG; - } else if (strequal (str, "hex")) { - codes = HEX_CODE; - hex_tag = HEXTAG; - } else if (!strncasecmp (str, "hex", 3)) { - codes = HEX_CODE; - hex_tag = (str[3] ? str[3] : HEXTAG); - } else if (strequal (str, "j8bb")) { - codes = JIS8_CODE; - jis_kso = 'B'; - jis_ksi = 'B'; - } else if (strequal (str, "j8bj") || strequal (str, "jis8")) { - codes = JIS8_CODE; - jis_kso = 'B'; - jis_ksi = 'J'; - } else if (strequal (str, "j8bh")) { - codes = JIS8_CODE; - jis_kso = 'B'; - jis_ksi = 'H'; - } else if (strequal (str, "j8@b")) { - codes = JIS8_CODE; - jis_kso = '@'; - jis_ksi = 'B'; - } else if (strequal (str, "j8@j")) { - codes = JIS8_CODE; - jis_kso = '@'; - jis_ksi = 'J'; - } else if (strequal (str, "j8@h")) { - codes = JIS8_CODE; - jis_kso = '@'; - jis_ksi = 'H'; - } else if (strequal (str, "j7bb")) { - codes = JIS7_CODE; - jis_kso = 'B'; - jis_ksi = 'B'; - } else if (strequal (str, "j7bj") || strequal (str, "jis7")) { - codes = JIS7_CODE; - jis_kso = 'B'; - jis_ksi = 'J'; - } else if (strequal (str, "j7bh")) { - codes = JIS7_CODE; - jis_kso = 'B'; - jis_ksi = 'H'; - } else if (strequal (str, "j7@b")) { - codes = JIS7_CODE; - jis_kso = '@'; - jis_ksi = 'B'; - } else if (strequal (str, "j7@j")) { - codes = JIS7_CODE; - jis_kso = '@'; - jis_ksi = 'J'; - } else if (strequal (str, "j7@h")) { - codes = JIS7_CODE; - jis_kso = '@'; - jis_ksi = 'H'; - } else if (strequal (str, "jubb")) { - codes = JUNET_CODE; - jis_kso = 'B'; - jis_ksi = 'B'; - } else if (strequal (str, "jubj") || strequal (str, "junet")) { - codes = JUNET_CODE; - jis_kso = 'B'; - jis_ksi = 'J'; - } else if (strequal (str, "jubh")) { - codes = JUNET_CODE; - jis_kso = 'B'; - jis_ksi = 'H'; - } else if (strequal (str, "ju@b")) { - codes = JUNET_CODE; - jis_kso = '@'; - jis_ksi = 'B'; - } else if (strequal (str, "ju@j")) { - codes = JUNET_CODE; - jis_kso = '@'; - jis_ksi = 'J'; - } else if (strequal (str, "ju@h")) { - codes = JUNET_CODE; - jis_kso = '@'; - jis_ksi = 'H'; - } - setup_string_function (codes); -} - -/******************************************************************* - Non multibyte char function. -*******************************************************************/ - -static size_t skip_non_multibyte_char(char c) -{ - (void) c; - return 0; -} - -/******************************************************************* - Function that always says a character isn't multibyte. -*******************************************************************/ - -static BOOL not_multibyte_char_1(char c) -{ - (void) c; - return False; -} - -/******************************************************************* - Function to determine if we are in a multibyte code page. -*******************************************************************/ - -static BOOL is_multibyte_codepage_val = False; - -BOOL is_multibyte_codepage(void) -{ - return is_multibyte_codepage_val; -} - -/******************************************************************* - Setup the function pointers for the functions that are replaced - when multi-byte codepages are used. - - The dos_to_unix and unix_to_dos function pointers are only - replaced by setup_string_function called by interpret_coding_system - above. -*******************************************************************/ - -void initialize_multibyte_vectors( int client_codepage) -{ - switch( client_codepage ) - { - case KANJI_CODEPAGE: - multibyte_strchr = sj_strchr; - multibyte_strrchr = sj_strrchr; - multibyte_strstr = sj_strstr; - multibyte_strtok = sj_strtok; - _skip_multibyte_char = skip_kanji_multibyte_char; - is_multibyte_char_1 = is_kanji_multibyte_char_1; - is_multibyte_codepage_val = True; - break; - case HANGUL_CODEPAGE: - multibyte_strchr = generic_multibyte_strchr; - multibyte_strrchr = generic_multibyte_strrchr; - multibyte_strstr = generic_multibyte_strstr; - multibyte_strtok = generic_multibyte_strtok; - _skip_multibyte_char = skip_generic_multibyte_char; - is_multibyte_char_1 = hangul_is_multibyte_char_1; - is_multibyte_codepage_val = True; - break; - case BIG5_CODEPAGE: - multibyte_strchr = generic_multibyte_strchr; - multibyte_strrchr = generic_multibyte_strrchr; - multibyte_strstr = generic_multibyte_strstr; - multibyte_strtok = generic_multibyte_strtok; - _skip_multibyte_char = skip_generic_multibyte_char; - is_multibyte_char_1 = big5_is_multibyte_char_1; - is_multibyte_codepage_val = True; - break; - case SIMPLIFIED_CHINESE_CODEPAGE: - multibyte_strchr = generic_multibyte_strchr; - multibyte_strrchr = generic_multibyte_strrchr; - multibyte_strstr = generic_multibyte_strstr; - multibyte_strtok = generic_multibyte_strtok; - _skip_multibyte_char = skip_generic_multibyte_char; - is_multibyte_char_1 = simpch_is_multibyte_char_1; - is_multibyte_codepage_val = True; - break; - /* - * Single char size code page. - */ - default: - multibyte_strchr = (const char *(*)(const char *, int )) strchr; - multibyte_strrchr = (const char *(*)(const char *, int )) strrchr; - multibyte_strstr = (const char *(*)(const char *, const char *)) strstr; - multibyte_strtok = (char *(*)(char *, const char *)) strtok; - _skip_multibyte_char = skip_non_multibyte_char; - is_multibyte_char_1 = not_multibyte_char_1; - is_multibyte_codepage_val = False; - break; - } -} +/* + Unix SMB/Netbios implementation. + Version 1.9. + Kanji Extensions + + Copyright (C) Andrew Tridgell 1992-1998 + + Copyright (C) 2011 + The Free Software Foundation, Inc. + + Adding for Japanese language by 1994.9.5 + and extend coding system to EUC/SJIS/JIS/HEX at 1994.10.11 + and add all jis codes sequence type at 1995.8.16 + Notes: Hexadecimal code by + + This file is part of the Midnight Commander. + + The Midnight Commander is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + The Midnight Commander is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + */ + +#define _KANJI_C_ +#include "includes.h" + +/* + * Function pointers that get overridden when multi-byte code pages + * are loaded. + */ + +const char *(*multibyte_strchr) (const char *, int) = (const char *(*)(const char *, int)) strchr; +const char *(*multibyte_strrchr) (const char *, int) = (const char *(*)(const char *, int)) strrchr; +const char *(*multibyte_strstr) (const char *, const char *) = + (const char *(*)(const char *, const char *)) strstr; +char *(*multibyte_strtok) (char *, const char *) = (char *(*)(char *, const char *)) strtok; + +/* + * Kanji is treated differently here due to historical accident of + * it being the first non-English codepage added to Samba. + * The define 'KANJI' is being overloaded to mean 'use kanji codepage + * by default' and also 'this is the filename-to-disk conversion + * method to use'. This really should be removed and all control + * over this left in the smb.conf parameters 'client codepage' + * and 'coding system'. + */ + +#ifndef KANJI + +/* + * Set the default conversion to be the functions in + * charcnv.c. + */ + +static size_t skip_non_multibyte_char (char); +static BOOL not_multibyte_char_1 (char); + +char *(*_dos_to_unix) (char *, BOOL) = dos2unix_format; +char *(*_unix_to_dos) (char *, BOOL) = unix2dos_format; +size_t (*_skip_multibyte_char) (char) = skip_non_multibyte_char; +BOOL (*is_multibyte_char_1) (char) = not_multibyte_char_1; + +#else /* KANJI */ + +/* + * Set the default conversion to be the function + * sj_to_sj in this file. + */ + +static char *sj_to_sj (char *from, BOOL overwrite); +static size_t skip_kanji_multibyte_char (char); +static BOOL is_kanji_multibyte_char_1 (char); + +char *(*_dos_to_unix) (char *, BOOL) = sj_to_sj; +char *(*_unix_to_dos) (char *, BOOL) = sj_to_sj; +size_t (*_skip_multibyte_char) (char) = skip_kanji_multibyte_char; +int (*is_multibyte_char_1) (char) = is_kanji_multibyte_char_1; + +#endif /* KANJI */ + +/* jis si/so sequence */ +static char jis_kso = JIS_KSO; +static char jis_ksi = JIS_KSI; +static char hex_tag = HEXTAG; + +/******************************************************************* + SHIFT JIS functions +********************************************************************/ + +/******************************************************************* + search token from S1 separated any char of S2 + S1 contains SHIFT JIS chars. +********************************************************************/ + +static char * +sj_strtok (char *s1, const char *s2) +{ + static char *s = NULL; + char *q; + if (!s1) + { + if (!s) + { + return NULL; + } + s1 = s; + } + for (q = s1; *s1;) + { + if (is_shift_jis (*s1)) + { + s1 += 2; + } + else if (is_kana (*s1)) + { + s1++; + } + else + { + char *p = strchr (s2, *s1); + if (p) + { + if (s1 != q) + { + s = s1 + 1; + *s1 = '\0'; + return q; + } + q = s1 + 1; + } + s1++; + } + } + s = NULL; + if (*q) + { + return q; + } + return NULL; +} + +/******************************************************************* + search string S2 from S1 + S1 contains SHIFT JIS chars. +********************************************************************/ + +static const char * +sj_strstr (const char *s1, const char *s2) +{ + size_t len = strlen (s2); + if (!*s2) + return (const char *) s1; + for (; *s1;) + { + if (*s1 == *s2) + { + if (strncmp (s1, s2, len) == 0) + return (const char *) s1; + } + if (is_shift_jis (*s1)) + { + s1 += 2; + } + else + { + s1++; + } + } + return NULL; +} + +/******************************************************************* + Search char C from beginning of S. + S contains SHIFT JIS chars. +********************************************************************/ + +static const char * +sj_strchr (const char *s, int c) +{ + for (; *s;) + { + if (*s == c) + return (const char *) s; + if (is_shift_jis (*s)) + { + s += 2; + } + else + { + s++; + } + } + return NULL; +} + +/******************************************************************* + Search char C end of S. + S contains SHIFT JIS chars. +********************************************************************/ + +static const char * +sj_strrchr (const char *s, int c) +{ + const char *q; + + for (q = 0; *s;) + { + if (*s == c) + { + q = (const char *) s; + } + if (is_shift_jis (*s)) + { + s += 2; + } + else + { + s++; + } + } + return q; +} + +/******************************************************************* + Kanji multibyte char skip function. +*******************************************************************/ + +static size_t +skip_kanji_multibyte_char (char c) +{ + if (is_shift_jis (c)) + { + return 2; + } + else if (is_kana (c)) + { + return 1; + } + return 0; +} + +/******************************************************************* + Kanji multibyte char identification. +*******************************************************************/ + +static BOOL +is_kanji_multibyte_char_1 (char c) +{ + return is_shift_jis (c); +} + +/******************************************************************* + The following functions are the only ones needed to do multibyte + support for Hangul, Big5 and Simplified Chinese. Most of the + real work for these codepages is done in the generic multibyte + functions. The only reason these functions are needed at all + is that the is_xxx(c) calls are really preprocessor macros. +********************************************************************/ + +/******************************************************************* + Hangul (Korean - code page 949) function. +********************************************************************/ + +static BOOL +hangul_is_multibyte_char_1 (char c) +{ + return is_hangul (c); +} + +/******************************************************************* + Big5 Traditional Chinese (code page 950) function. +********************************************************************/ + +static BOOL +big5_is_multibyte_char_1 (char c) +{ + return is_big5_c1 (c); +} + +/******************************************************************* + Simplified Chinese (code page 936) function. +********************************************************************/ + +static BOOL +simpch_is_multibyte_char_1 (char c) +{ + return is_simpch_c1 (c); +} + +/******************************************************************* + Generic multibyte functions - used by Hangul, Big5 and Simplified + Chinese codepages. +********************************************************************/ + +/******************************************************************* + search token from S1 separated any char of S2 + S1 contains generic multibyte chars. +********************************************************************/ + +static char * +generic_multibyte_strtok (char *s1, const char *s2) +{ + static char *s = NULL; + char *q; + if (!s1) + { + if (!s) + { + return NULL; + } + s1 = s; + } + for (q = s1; *s1;) + { + if ((*is_multibyte_char_1) (*s1)) + { + s1 += 2; + } + else + { + char *p = strchr (s2, *s1); + if (p) + { + if (s1 != q) + { + s = s1 + 1; + *s1 = '\0'; + return q; + } + q = s1 + 1; + } + s1++; + } + } + s = NULL; + if (*q) + { + return q; + } + return NULL; +} + +/******************************************************************* + search string S2 from S1 + S1 contains generic multibyte chars. +********************************************************************/ + +static const char * +generic_multibyte_strstr (const char *s1, const char *s2) +{ + size_t len = strlen (s2); + if (!*s2) + return (const char *) s1; + for (; *s1;) + { + if (*s1 == *s2) + { + if (strncmp (s1, s2, len) == 0) + return (const char *) s1; + } + if ((*is_multibyte_char_1) (*s1)) + { + s1 += 2; + } + else + { + s1++; + } + } + return NULL; +} + +/******************************************************************* + Search char C from beginning of S. + S contains generic multibyte chars. +********************************************************************/ + +static const char * +generic_multibyte_strchr (const char *s, int c) +{ + for (; *s;) + { + if (*s == c) + return (const char *) s; + if ((*is_multibyte_char_1) (*s)) + { + s += 2; + } + else + { + s++; + } + } + return NULL; +} + +/******************************************************************* + Search char C end of S. + S contains generic multibyte chars. +********************************************************************/ + +static const char * +generic_multibyte_strrchr (const char *s, int c) +{ + const char *q; + + for (q = 0; *s;) + { + if (*s == c) + { + q = (const char *) s; + } + if ((*is_multibyte_char_1) (*s)) + { + s += 2; + } + else + { + s++; + } + } + return q; +} + +/******************************************************************* + Generic multibyte char skip function. +*******************************************************************/ + +static size_t +skip_generic_multibyte_char (char c) +{ + if ((*is_multibyte_char_1) (c)) + { + return 2; + } + return 0; +} + +/******************************************************************* + Code conversion +********************************************************************/ + +/* convesion buffer */ +static char cvtbuf[1024]; + +/******************************************************************* + EUC <-> SJIS +********************************************************************/ + +static int +euc2sjis (int hi, int lo) +{ + if (hi & 1) + return ((hi / 2 + (hi < 0xdf ? 0x31 : 0x71)) << 8) | (lo - (lo >= 0xe0 ? 0x60 : 0x61)); + else + return ((hi / 2 + (hi < 0xdf ? 0x30 : 0x70)) << 8) | (lo - 2); +} + +static int +sjis2euc (int hi, int lo) +{ + if (lo >= 0x9f) + return ((hi * 2 - (hi >= 0xe0 ? 0xe0 : 0x60)) << 8) | (lo + 2); + else + return ((hi * 2 - (hi >= 0xe0 ? 0xe1 : 0x61)) << 8) | (lo + (lo >= 0x7f ? 0x60 : 0x61)); +} + +/******************************************************************* + Convert FROM contain SHIFT JIS codes to EUC codes + return converted buffer +********************************************************************/ + +static char * +sj_to_euc (char *from, BOOL overwrite) +{ + char *out; + char *save; + + save = (char *) from; + for (out = cvtbuf; *from;) + { + if (is_shift_jis (*from)) + { + int code = sjis2euc ((int) from[0] & 0xff, (int) from[1] & 0xff); + *out++ = (code >> 8) & 0xff; + *out++ = code; + from += 2; + } + else if (is_kana (*from)) + { + *out++ = (char) euc_kana; + *out++ = *from++; + } + else + { + *out++ = *from++; + } + } + *out = 0; + if (overwrite) + { + pstrcpy ((char *) save, (char *) cvtbuf); + return (char *) save; + } + else + { + return cvtbuf; + } +} + +/******************************************************************* + Convert FROM contain EUC codes to SHIFT JIS codes + return converted buffer +********************************************************************/ + +static char * +euc_to_sj (char *from, BOOL overwrite) +{ + char *out; + char *save; + + save = (char *) from; + for (out = cvtbuf; *from;) + { + if (is_euc (*from)) + { + int code = euc2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff); + *out++ = (code >> 8) & 0xff; + *out++ = code; + from += 2; + } + else if (is_euc_kana (*from)) + { + *out++ = from[1]; + from += 2; + } + else + { + *out++ = *from++; + } + } + *out = 0; + if (overwrite) + { + pstrcpy (save, (char *) cvtbuf); + return save; + } + else + { + return cvtbuf; + } +} + +/******************************************************************* + JIS7,JIS8,JUNET <-> SJIS +********************************************************************/ + +static int +sjis2jis (int hi, int lo) +{ + if (lo >= 0x9f) + return ((hi * 2 - (hi >= 0xe0 ? 0x160 : 0xe0)) << 8) | (lo - 0x7e); + else + return ((hi * 2 - (hi >= 0xe0 ? 0x161 : 0xe1)) << 8) | (lo - (lo >= 0x7f ? 0x20 : 0x1f)); +} + +static int +jis2sjis (int hi, int lo) +{ + if (hi & 1) + return ((hi / 2 + (hi < 0x5f ? 0x71 : 0xb1)) << 8) | (lo + (lo >= 0x60 ? 0x20 : 0x1f)); + else + return ((hi / 2 + (hi < 0x5f ? 0x70 : 0xb0)) << 8) | (lo + 0x7e); +} + +/******************************************************************* + Convert FROM contain JIS codes to SHIFT JIS codes + return converted buffer +********************************************************************/ + +static char * +jis8_to_sj (char *from, BOOL overwrite) +{ + char *out; + int shifted; + char *save; + + shifted = _KJ_ROMAN; + save = (char *) from; + for (out = cvtbuf; *from;) + { + if (is_esc (*from)) + { + if (is_so1 (from[1]) && is_so2 (from[2])) + { + shifted = _KJ_KANJI; + from += 3; + } + else if (is_si1 (from[1]) && is_si2 (from[2])) + { + shifted = _KJ_ROMAN; + from += 3; + } + else + { /* sequence error */ + goto normal; + } + } + else + { + normal: + switch (shifted) + { + default: + case _KJ_ROMAN: + *out++ = *from++; + break; + case _KJ_KANJI: + { + int code = jis2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff); + *out++ = (code >> 8) & 0xff; + *out++ = code; + from += 2; + } + break; + } + } + } + *out = 0; + if (overwrite) + { + pstrcpy (save, (char *) cvtbuf); + return save; + } + else + { + return cvtbuf; + } +} + +/******************************************************************* + Convert FROM contain SHIFT JIS codes to JIS codes + return converted buffer +********************************************************************/ + +static char * +sj_to_jis8 (char *from, BOOL overwrite) +{ + char *out; + int shifted; + char *save; + + shifted = _KJ_ROMAN; + save = (char *) from; + for (out = cvtbuf; *from;) + { + if (is_shift_jis (*from)) + { + int code; + switch (shifted) + { + case _KJ_ROMAN: /* to KANJI */ + *out++ = jis_esc; + *out++ = jis_so1; + *out++ = jis_kso; + shifted = _KJ_KANJI; + break; + } + code = sjis2jis ((int) from[0] & 0xff, (int) from[1] & 0xff); + *out++ = (code >> 8) & 0xff; + *out++ = code; + from += 2; + } + else + { + switch (shifted) + { + case _KJ_KANJI: /* to ROMAN/KANA */ + *out++ = jis_esc; + *out++ = jis_si1; + *out++ = jis_ksi; + shifted = _KJ_ROMAN; + break; + } + *out++ = *from++; + } + } + switch (shifted) + { + case _KJ_KANJI: /* to ROMAN/KANA */ + *out++ = jis_esc; + *out++ = jis_si1; + *out++ = jis_ksi; + shifted = _KJ_ROMAN; + break; + } + *out = 0; + if (overwrite) + { + pstrcpy (save, (char *) cvtbuf); + return save; + } + else + { + return cvtbuf; + } +} + +/******************************************************************* + Convert FROM contain 7 bits JIS codes to SHIFT JIS codes + return converted buffer +********************************************************************/ +static char * +jis7_to_sj (char *from, BOOL overwrite) +{ + char *out; + int shifted; + char *save; + + shifted = _KJ_ROMAN; + save = (char *) from; + for (out = cvtbuf; *from;) + { + if (is_esc (*from)) + { + if (is_so1 (from[1]) && is_so2 (from[2])) + { + shifted = _KJ_KANJI; + from += 3; + } + else if (is_si1 (from[1]) && is_si2 (from[2])) + { + shifted = _KJ_ROMAN; + from += 3; + } + else + { /* sequence error */ + goto normal; + } + } + else if (is_so (*from)) + { + shifted = _KJ_KANA; /* to KANA */ + from++; + } + else if (is_si (*from)) + { + shifted = _KJ_ROMAN; /* to ROMAN */ + from++; + } + else + { + normal: + switch (shifted) + { + default: + case _KJ_ROMAN: + *out++ = *from++; + break; + case _KJ_KANJI: + { + int code = jis2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff); + *out++ = (code >> 8) & 0xff; + *out++ = code; + from += 2; + } + break; + case _KJ_KANA: + *out++ = ((int) from[0]) + 0x80; + break; + } + } + } + *out = 0; + if (overwrite) + { + pstrcpy (save, (char *) cvtbuf); + return save; + } + else + { + return cvtbuf; + } +} + +/******************************************************************* + Convert FROM contain SHIFT JIS codes to 7 bits JIS codes + return converted buffer +********************************************************************/ +static char * +sj_to_jis7 (char *from, BOOL overwrite) +{ + char *out; + int shifted; + char *save; + + shifted = _KJ_ROMAN; + save = (char *) from; + for (out = cvtbuf; *from;) + { + if (is_shift_jis (*from)) + { + int code; + switch (shifted) + { + case _KJ_KANA: + *out++ = jis_si; /* to ROMAN and through down */ + case _KJ_ROMAN: /* to KANJI */ + *out++ = jis_esc; + *out++ = jis_so1; + *out++ = jis_kso; + shifted = _KJ_KANJI; + break; + } + code = sjis2jis ((int) from[0] & 0xff, (int) from[1] & 0xff); + *out++ = (code >> 8) & 0xff; + *out++ = code; + from += 2; + } + else if (is_kana (from[0])) + { + switch (shifted) + { + case _KJ_KANJI: /* to ROMAN */ + *out++ = jis_esc; + *out++ = jis_si1; + *out++ = jis_ksi; + case _KJ_ROMAN: /* to KANA */ + *out++ = jis_so; + shifted = _KJ_KANA; + break; + } + *out++ = ((int) *from++) - 0x80; + } + else + { + switch (shifted) + { + case _KJ_KANA: + *out++ = jis_si; /* to ROMAN */ + shifted = _KJ_ROMAN; + break; + case _KJ_KANJI: /* to ROMAN */ + *out++ = jis_esc; + *out++ = jis_si1; + *out++ = jis_ksi; + shifted = _KJ_ROMAN; + break; + } + *out++ = *from++; + } + } + switch (shifted) + { + case _KJ_KANA: + *out++ = jis_si; /* to ROMAN */ + break; + case _KJ_KANJI: /* to ROMAN */ + *out++ = jis_esc; + *out++ = jis_si1; + *out++ = jis_ksi; + break; + } + *out = 0; + if (overwrite) + { + pstrcpy (save, (char *) cvtbuf); + return save; + } + else + { + return cvtbuf; + } +} + +/******************************************************************* + Convert FROM contain 7 bits JIS(junet) codes to SHIFT JIS codes + return converted buffer +********************************************************************/ +static char * +junet_to_sj (char *from, BOOL overwrite) +{ + char *out; + int shifted; + char *save; + + shifted = _KJ_ROMAN; + save = (char *) from; + for (out = cvtbuf; *from;) + { + if (is_esc (*from)) + { + if (is_so1 (from[1]) && is_so2 (from[2])) + { + shifted = _KJ_KANJI; + from += 3; + } + else if (is_si1 (from[1]) && is_si2 (from[2])) + { + shifted = _KJ_ROMAN; + from += 3; + } + else if (is_juk1 (from[1]) && is_juk2 (from[2])) + { + shifted = _KJ_KANA; + from += 3; + } + else + { /* sequence error */ + goto normal; + } + } + else + { + normal: + switch (shifted) + { + default: + case _KJ_ROMAN: + *out++ = *from++; + break; + case _KJ_KANJI: + { + int code = jis2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff); + *out++ = (code >> 8) & 0xff; + *out++ = code; + from += 2; + } + break; + case _KJ_KANA: + *out++ = ((int) from[0]) + 0x80; + break; + } + } + } + *out = 0; + if (overwrite) + { + pstrcpy (save, (char *) cvtbuf); + return save; + } + else + { + return cvtbuf; + } +} + +/******************************************************************* + Convert FROM contain SHIFT JIS codes to 7 bits JIS(junet) codes + return converted buffer +********************************************************************/ +static char * +sj_to_junet (char *from, BOOL overwrite) +{ + char *out; + int shifted; + char *save; + + shifted = _KJ_ROMAN; + save = (char *) from; + for (out = cvtbuf; *from;) + { + if (is_shift_jis (*from)) + { + int code; + switch (shifted) + { + case _KJ_KANA: + case _KJ_ROMAN: /* to KANJI */ + *out++ = jis_esc; + *out++ = jis_so1; + *out++ = jis_so2; + shifted = _KJ_KANJI; + break; + } + code = sjis2jis ((int) from[0] & 0xff, (int) from[1] & 0xff); + *out++ = (code >> 8) & 0xff; + *out++ = code; + from += 2; + } + else if (is_kana (from[0])) + { + switch (shifted) + { + case _KJ_KANJI: /* to ROMAN */ + case _KJ_ROMAN: /* to KANA */ + *out++ = jis_esc; + *out++ = junet_kana1; + *out++ = junet_kana2; + shifted = _KJ_KANA; + break; + } + *out++ = ((int) *from++) - 0x80; + } + else + { + switch (shifted) + { + case _KJ_KANA: + case _KJ_KANJI: /* to ROMAN */ + *out++ = jis_esc; + *out++ = jis_si1; + *out++ = jis_si2; + shifted = _KJ_ROMAN; + break; + } + *out++ = *from++; + } + } + switch (shifted) + { + case _KJ_KANA: + case _KJ_KANJI: /* to ROMAN */ + *out++ = jis_esc; + *out++ = jis_si1; + *out++ = jis_si2; + break; + } + *out = 0; + if (overwrite) + { + pstrcpy (save, (char *) cvtbuf); + return save; + } + else + { + return cvtbuf; + } +} + +/******************************************************************* + HEX <-> SJIS +********************************************************************/ +/* ":xx" -> a byte */ +static char * +hex_to_sj (char *from, BOOL overwrite) +{ + char *sp, *dp; + + sp = (char *) from; + dp = cvtbuf; + while (*sp) + { + if (*sp == hex_tag && isxdigit ((int) sp[1]) && isxdigit ((int) sp[2])) + { + *dp++ = (hex2bin (sp[1]) << 4) | (hex2bin (sp[2])); + sp += 3; + } + else + *dp++ = *sp++; + } + *dp = '\0'; + if (overwrite) + { + pstrcpy ((char *) from, (char *) cvtbuf); + return (char *) from; + } + else + { + return cvtbuf; + } +} + +/******************************************************************* + kanji/kana -> ":xx" +********************************************************************/ +static char * +sj_to_hex (char *from, BOOL overwrite) +{ + unsigned char *sp, *dp; + + sp = (unsigned char *) from; + dp = (unsigned char *) cvtbuf; + while (*sp) + { + if (is_kana (*sp)) + { + *dp++ = hex_tag; + *dp++ = bin2hex (((*sp) >> 4) & 0x0f); + *dp++ = bin2hex ((*sp) & 0x0f); + sp++; + } + else if (is_shift_jis (*sp) && is_shift_jis2 (sp[1])) + { + *dp++ = hex_tag; + *dp++ = bin2hex (((*sp) >> 4) & 0x0f); + *dp++ = bin2hex ((*sp) & 0x0f); + sp++; + *dp++ = hex_tag; + *dp++ = bin2hex (((*sp) >> 4) & 0x0f); + *dp++ = bin2hex ((*sp) & 0x0f); + sp++; + } + else + *dp++ = *sp++; + } + *dp = '\0'; + if (overwrite) + { + pstrcpy ((char *) from, (char *) cvtbuf); + return (char *) from; + } + else + { + return cvtbuf; + } +} + +/******************************************************************* + CAP <-> SJIS +********************************************************************/ +/* ":xx" CAP -> a byte */ +static char * +cap_to_sj (char *from, BOOL overwrite) +{ + char *sp, *dp; + + sp = (char *) from; + dp = cvtbuf; + while (*sp) + { + /* + * The only change between this and hex_to_sj is here. sj_to_cap only + * translates characters greater or equal to 0x80 - make sure that here + * we only do the reverse (that's why the strchr is used rather than + * isxdigit. Based on fix from ado@elsie.nci.nih.gov (Arthur David Olson). + */ + if (*sp == hex_tag && (strchr ("89abcdefABCDEF", sp[1]) != NULL) && isxdigit ((int) sp[2])) + { + *dp++ = (hex2bin (sp[1]) << 4) | (hex2bin (sp[2])); + sp += 3; + } + else + *dp++ = *sp++; + } + *dp = '\0'; + if (overwrite) + { + pstrcpy ((char *) from, (char *) cvtbuf); + return (char *) from; + } + else + { + return cvtbuf; + } +} + +/******************************************************************* + kanji/kana -> ":xx" - CAP format. +********************************************************************/ +static char * +sj_to_cap (char *from, BOOL overwrite) +{ + unsigned char *sp, *dp; + + sp = (unsigned char *) from; + dp = (unsigned char *) cvtbuf; + while (*sp) + { + if (*sp >= 0x80) + { + *dp++ = hex_tag; + *dp++ = bin2hex (((*sp) >> 4) & 0x0f); + *dp++ = bin2hex ((*sp) & 0x0f); + sp++; + } + else + { + *dp++ = *sp++; + } + } + *dp = '\0'; + if (overwrite) + { + pstrcpy ((char *) from, (char *) cvtbuf); + return (char *) from; + } + else + { + return cvtbuf; + } +} + +/******************************************************************* + sj to sj +********************************************************************/ +static char * +sj_to_sj (char *from, BOOL overwrite) +{ + if (!overwrite) + { + pstrcpy (cvtbuf, (char *) from); + return cvtbuf; + } + else + { + return (char *) from; + } +} + +/************************************************************************ + conversion: + _dos_to_unix _unix_to_dos +************************************************************************/ + +static void +setup_string_function (int codes) +{ + switch (codes) + { + default: + _dos_to_unix = dos2unix_format; + _unix_to_dos = unix2dos_format; + break; + + case SJIS_CODE: + _dos_to_unix = sj_to_sj; + _unix_to_dos = sj_to_sj; + break; + + case EUC_CODE: + _dos_to_unix = sj_to_euc; + _unix_to_dos = euc_to_sj; + break; + + case JIS7_CODE: + _dos_to_unix = sj_to_jis7; + _unix_to_dos = jis7_to_sj; + break; + + case JIS8_CODE: + _dos_to_unix = sj_to_jis8; + _unix_to_dos = jis8_to_sj; + break; + + case JUNET_CODE: + _dos_to_unix = sj_to_junet; + _unix_to_dos = junet_to_sj; + break; + + case HEX_CODE: + _dos_to_unix = sj_to_hex; + _unix_to_dos = hex_to_sj; + break; + + case CAP_CODE: + _dos_to_unix = sj_to_cap; + _unix_to_dos = cap_to_sj; + break; + } +} + +/************************************************************************ + Interpret coding system. +************************************************************************/ + +void +interpret_coding_system (const char *str) +{ + int codes = UNKNOWN_CODE; + + if (strequal (str, "sjis")) + { + codes = SJIS_CODE; + } + else if (strequal (str, "euc")) + { + codes = EUC_CODE; + } + else if (strequal (str, "cap")) + { + codes = CAP_CODE; + hex_tag = HEXTAG; + } + else if (strequal (str, "hex")) + { + codes = HEX_CODE; + hex_tag = HEXTAG; + } + else if (!strncasecmp (str, "hex", 3)) + { + codes = HEX_CODE; + hex_tag = (str[3] ? str[3] : HEXTAG); + } + else if (strequal (str, "j8bb")) + { + codes = JIS8_CODE; + jis_kso = 'B'; + jis_ksi = 'B'; + } + else if (strequal (str, "j8bj") || strequal (str, "jis8")) + { + codes = JIS8_CODE; + jis_kso = 'B'; + jis_ksi = 'J'; + } + else if (strequal (str, "j8bh")) + { + codes = JIS8_CODE; + jis_kso = 'B'; + jis_ksi = 'H'; + } + else if (strequal (str, "j8@b")) + { + codes = JIS8_CODE; + jis_kso = '@'; + jis_ksi = 'B'; + } + else if (strequal (str, "j8@j")) + { + codes = JIS8_CODE; + jis_kso = '@'; + jis_ksi = 'J'; + } + else if (strequal (str, "j8@h")) + { + codes = JIS8_CODE; + jis_kso = '@'; + jis_ksi = 'H'; + } + else if (strequal (str, "j7bb")) + { + codes = JIS7_CODE; + jis_kso = 'B'; + jis_ksi = 'B'; + } + else if (strequal (str, "j7bj") || strequal (str, "jis7")) + { + codes = JIS7_CODE; + jis_kso = 'B'; + jis_ksi = 'J'; + } + else if (strequal (str, "j7bh")) + { + codes = JIS7_CODE; + jis_kso = 'B'; + jis_ksi = 'H'; + } + else if (strequal (str, "j7@b")) + { + codes = JIS7_CODE; + jis_kso = '@'; + jis_ksi = 'B'; + } + else if (strequal (str, "j7@j")) + { + codes = JIS7_CODE; + jis_kso = '@'; + jis_ksi = 'J'; + } + else if (strequal (str, "j7@h")) + { + codes = JIS7_CODE; + jis_kso = '@'; + jis_ksi = 'H'; + } + else if (strequal (str, "jubb")) + { + codes = JUNET_CODE; + jis_kso = 'B'; + jis_ksi = 'B'; + } + else if (strequal (str, "jubj") || strequal (str, "junet")) + { + codes = JUNET_CODE; + jis_kso = 'B'; + jis_ksi = 'J'; + } + else if (strequal (str, "jubh")) + { + codes = JUNET_CODE; + jis_kso = 'B'; + jis_ksi = 'H'; + } + else if (strequal (str, "ju@b")) + { + codes = JUNET_CODE; + jis_kso = '@'; + jis_ksi = 'B'; + } + else if (strequal (str, "ju@j")) + { + codes = JUNET_CODE; + jis_kso = '@'; + jis_ksi = 'J'; + } + else if (strequal (str, "ju@h")) + { + codes = JUNET_CODE; + jis_kso = '@'; + jis_ksi = 'H'; + } + setup_string_function (codes); +} + +/******************************************************************* + Non multibyte char function. +*******************************************************************/ + +static size_t +skip_non_multibyte_char (char c) +{ + (void) c; + return 0; +} + +/******************************************************************* + Function that always says a character isn't multibyte. +*******************************************************************/ + +static BOOL +not_multibyte_char_1 (char c) +{ + (void) c; + return False; +} + +/******************************************************************* + Function to determine if we are in a multibyte code page. +*******************************************************************/ + +static BOOL is_multibyte_codepage_val = False; + +BOOL +is_multibyte_codepage (void) +{ + return is_multibyte_codepage_val; +} + +/******************************************************************* + Setup the function pointers for the functions that are replaced + when multi-byte codepages are used. + + The dos_to_unix and unix_to_dos function pointers are only + replaced by setup_string_function called by interpret_coding_system + above. +*******************************************************************/ + +void +initialize_multibyte_vectors (int client_codepage) +{ + switch (client_codepage) + { + case KANJI_CODEPAGE: + multibyte_strchr = sj_strchr; + multibyte_strrchr = sj_strrchr; + multibyte_strstr = sj_strstr; + multibyte_strtok = sj_strtok; + _skip_multibyte_char = skip_kanji_multibyte_char; + is_multibyte_char_1 = is_kanji_multibyte_char_1; + is_multibyte_codepage_val = True; + break; + case HANGUL_CODEPAGE: + multibyte_strchr = generic_multibyte_strchr; + multibyte_strrchr = generic_multibyte_strrchr; + multibyte_strstr = generic_multibyte_strstr; + multibyte_strtok = generic_multibyte_strtok; + _skip_multibyte_char = skip_generic_multibyte_char; + is_multibyte_char_1 = hangul_is_multibyte_char_1; + is_multibyte_codepage_val = True; + break; + case BIG5_CODEPAGE: + multibyte_strchr = generic_multibyte_strchr; + multibyte_strrchr = generic_multibyte_strrchr; + multibyte_strstr = generic_multibyte_strstr; + multibyte_strtok = generic_multibyte_strtok; + _skip_multibyte_char = skip_generic_multibyte_char; + is_multibyte_char_1 = big5_is_multibyte_char_1; + is_multibyte_codepage_val = True; + break; + case SIMPLIFIED_CHINESE_CODEPAGE: + multibyte_strchr = generic_multibyte_strchr; + multibyte_strrchr = generic_multibyte_strrchr; + multibyte_strstr = generic_multibyte_strstr; + multibyte_strtok = generic_multibyte_strtok; + _skip_multibyte_char = skip_generic_multibyte_char; + is_multibyte_char_1 = simpch_is_multibyte_char_1; + is_multibyte_codepage_val = True; + break; + /* + * Single char size code page. + */ + default: + multibyte_strchr = (const char *(*)(const char *, int)) strchr; + multibyte_strrchr = (const char *(*)(const char *, int)) strrchr; + multibyte_strstr = (const char *(*)(const char *, const char *)) strstr; + multibyte_strtok = (char *(*)(char *, const char *)) strtok; + _skip_multibyte_char = skip_non_multibyte_char; + is_multibyte_char_1 = not_multibyte_char_1; + is_multibyte_codepage_val = False; + break; + } +} diff --git a/src/vfs/smbfs/helpers/lib/md4.c b/src/vfs/smbfs/helpers/lib/md4.c dissimilarity index 66% index fa11b05bb..54186eba6 100644 --- a/src/vfs/smbfs/helpers/lib/md4.c +++ b/src/vfs/smbfs/helpers/lib/md4.c @@ -1,175 +1,217 @@ -/* - Unix SMB/Netbios implementation. - Version 1.9. - a implementation of MD4 designed for use in the SMB authentication protocol - - Copyright (C) Andrew Tridgell 1997-1998. - - Copyright (C) 2011 - The Free Software Foundation, Inc. - - This file is part of the Midnight Commander. - - The Midnight Commander is free software: you can redistribute it - and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of the License, - or (at your option) any later version. - - The Midnight Commander is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "includes.h" - -/* NOTE: This code makes no attempt to be fast! - - It assumes that a int is at least 32 bits long -*/ - -static uint32 A, B, C, D; - -static uint32 F(uint32 X, uint32 Y, uint32 Z) -{ - return (X&Y) | ((~X)&Z); -} - -static uint32 G(uint32 X, uint32 Y, uint32 Z) -{ - return (X&Y) | (X&Z) | (Y&Z); -} - -static uint32 H(uint32 X, uint32 Y, uint32 Z) -{ - return X^Y^Z; -} - -static uint32 lshift(uint32 x, int s) -{ - x &= 0xFFFFFFFF; - return ((x<>(32-s)); -} - -#define ROUND1(a,b,c,d,k,s) a = lshift(a + F(b,c,d) + X[k], s) -#define ROUND2(a,b,c,d,k,s) a = lshift(a + G(b,c,d) + X[k] + (uint32)0x5A827999,s) -#define ROUND3(a,b,c,d,k,s) a = lshift(a + H(b,c,d) + X[k] + (uint32)0x6ED9EBA1,s) - -/* this applies md4 to 64 byte chunks */ -static void mdfour64(uint32 *M) -{ - int j; - uint32 AA, BB, CC, DD; - uint32 X[16]; - - for (j=0;j<16;j++) - X[j] = M[j]; - - AA = A; BB = B; CC = C; DD = D; - - ROUND1(A,B,C,D, 0, 3); ROUND1(D,A,B,C, 1, 7); - ROUND1(C,D,A,B, 2, 11); ROUND1(B,C,D,A, 3, 19); - ROUND1(A,B,C,D, 4, 3); ROUND1(D,A,B,C, 5, 7); - ROUND1(C,D,A,B, 6, 11); ROUND1(B,C,D,A, 7, 19); - ROUND1(A,B,C,D, 8, 3); ROUND1(D,A,B,C, 9, 7); - ROUND1(C,D,A,B, 10, 11); ROUND1(B,C,D,A, 11, 19); - ROUND1(A,B,C,D, 12, 3); ROUND1(D,A,B,C, 13, 7); - ROUND1(C,D,A,B, 14, 11); ROUND1(B,C,D,A, 15, 19); - - ROUND2(A,B,C,D, 0, 3); ROUND2(D,A,B,C, 4, 5); - ROUND2(C,D,A,B, 8, 9); ROUND2(B,C,D,A, 12, 13); - ROUND2(A,B,C,D, 1, 3); ROUND2(D,A,B,C, 5, 5); - ROUND2(C,D,A,B, 9, 9); ROUND2(B,C,D,A, 13, 13); - ROUND2(A,B,C,D, 2, 3); ROUND2(D,A,B,C, 6, 5); - ROUND2(C,D,A,B, 10, 9); ROUND2(B,C,D,A, 14, 13); - ROUND2(A,B,C,D, 3, 3); ROUND2(D,A,B,C, 7, 5); - ROUND2(C,D,A,B, 11, 9); ROUND2(B,C,D,A, 15, 13); - - ROUND3(A,B,C,D, 0, 3); ROUND3(D,A,B,C, 8, 9); - ROUND3(C,D,A,B, 4, 11); ROUND3(B,C,D,A, 12, 15); - ROUND3(A,B,C,D, 2, 3); ROUND3(D,A,B,C, 10, 9); - ROUND3(C,D,A,B, 6, 11); ROUND3(B,C,D,A, 14, 15); - ROUND3(A,B,C,D, 1, 3); ROUND3(D,A,B,C, 9, 9); - ROUND3(C,D,A,B, 5, 11); ROUND3(B,C,D,A, 13, 15); - ROUND3(A,B,C,D, 3, 3); ROUND3(D,A,B,C, 11, 9); - ROUND3(C,D,A,B, 7, 11); ROUND3(B,C,D,A, 15, 15); - - A += AA; B += BB; C += CC; D += DD; - - A &= 0xFFFFFFFF; B &= 0xFFFFFFFF; - C &= 0xFFFFFFFF; D &= 0xFFFFFFFF; - - for (j=0;j<16;j++) - X[j] = 0; -} - -static void copy64(uint32 *M, unsigned char *in) -{ - int i; - - for (i=0;i<16;i++) - M[i] = (in[i*4+3]<<24) | (in[i*4+2]<<16) | - (in[i*4+1]<<8) | (in[i*4+0]<<0); -} - -static void copy4(unsigned char *out,uint32 x) -{ - out[0] = x&0xFF; - out[1] = (x>>8)&0xFF; - out[2] = (x>>16)&0xFF; - out[3] = (x>>24)&0xFF; -} - -/* produce a md4 message digest from data of length n bytes */ -void mdfour(unsigned char *out, unsigned char *in, int n) -{ - unsigned char buf[128]; - uint32 M[16]; - uint32 b = n * 8; - int i; - - A = 0x67452301; - B = 0xefcdab89; - C = 0x98badcfe; - D = 0x10325476; - - while (n > 64) { - copy64(M, in); - mdfour64(M); - in += 64; - n -= 64; - } - - for (i=0;i<128;i++) - buf[i] = 0; - memcpy(buf, in, n); - buf[n] = 0x80; - - if (n <= 55) { - copy4(buf+56, b); - copy64(M, buf); - mdfour64(M); - } else { - copy4(buf+120, b); - copy64(M, buf); - mdfour64(M); - copy64(M, buf+64); - mdfour64(M); - } - - for (i=0;i<128;i++) - buf[i] = 0; - copy64(M, buf); - - copy4(out, A); - copy4(out+4, B); - copy4(out+8, C); - copy4(out+12, D); - - A = B = C = D = 0; -} - - +/* + Unix SMB/Netbios implementation. + Version 1.9. + a implementation of MD4 designed for use in the SMB authentication protocol + + Copyright (C) Andrew Tridgell 1997-1998. + + Copyright (C) 2011 + The Free Software Foundation, Inc. + + This file is part of the Midnight Commander. + + The Midnight Commander is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + The Midnight Commander is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + */ + +#include "includes.h" + +/* NOTE: This code makes no attempt to be fast! + + It assumes that a int is at least 32 bits long + */ + +static uint32 A, B, C, D; + +static uint32 +F (uint32 X, uint32 Y, uint32 Z) +{ + return (X & Y) | ((~X) & Z); +} + +static uint32 +G (uint32 X, uint32 Y, uint32 Z) +{ + return (X & Y) | (X & Z) | (Y & Z); +} + +static uint32 +H (uint32 X, uint32 Y, uint32 Z) +{ + return X ^ Y ^ Z; +} + +static uint32 +lshift (uint32 x, int s) +{ + x &= 0xFFFFFFFF; + return ((x << s) & 0xFFFFFFFF) | (x >> (32 - s)); +} + +#define ROUND1(a,b,c,d,k,s) a = lshift(a + F(b,c,d) + X[k], s) +#define ROUND2(a,b,c,d,k,s) a = lshift(a + G(b,c,d) + X[k] + (uint32)0x5A827999,s) +#define ROUND3(a,b,c,d,k,s) a = lshift(a + H(b,c,d) + X[k] + (uint32)0x6ED9EBA1,s) + +/* this applies md4 to 64 byte chunks */ +static void +mdfour64 (uint32 * M) +{ + int j; + uint32 AA, BB, CC, DD; + uint32 X[16]; + + for (j = 0; j < 16; j++) + X[j] = M[j]; + + AA = A; + BB = B; + CC = C; + DD = D; + + ROUND1 (A, B, C, D, 0, 3); + ROUND1 (D, A, B, C, 1, 7); + ROUND1 (C, D, A, B, 2, 11); + ROUND1 (B, C, D, A, 3, 19); + ROUND1 (A, B, C, D, 4, 3); + ROUND1 (D, A, B, C, 5, 7); + ROUND1 (C, D, A, B, 6, 11); + ROUND1 (B, C, D, A, 7, 19); + ROUND1 (A, B, C, D, 8, 3); + ROUND1 (D, A, B, C, 9, 7); + ROUND1 (C, D, A, B, 10, 11); + ROUND1 (B, C, D, A, 11, 19); + ROUND1 (A, B, C, D, 12, 3); + ROUND1 (D, A, B, C, 13, 7); + ROUND1 (C, D, A, B, 14, 11); + ROUND1 (B, C, D, A, 15, 19); + + ROUND2 (A, B, C, D, 0, 3); + ROUND2 (D, A, B, C, 4, 5); + ROUND2 (C, D, A, B, 8, 9); + ROUND2 (B, C, D, A, 12, 13); + ROUND2 (A, B, C, D, 1, 3); + ROUND2 (D, A, B, C, 5, 5); + ROUND2 (C, D, A, B, 9, 9); + ROUND2 (B, C, D, A, 13, 13); + ROUND2 (A, B, C, D, 2, 3); + ROUND2 (D, A, B, C, 6, 5); + ROUND2 (C, D, A, B, 10, 9); + ROUND2 (B, C, D, A, 14, 13); + ROUND2 (A, B, C, D, 3, 3); + ROUND2 (D, A, B, C, 7, 5); + ROUND2 (C, D, A, B, 11, 9); + ROUND2 (B, C, D, A, 15, 13); + + ROUND3 (A, B, C, D, 0, 3); + ROUND3 (D, A, B, C, 8, 9); + ROUND3 (C, D, A, B, 4, 11); + ROUND3 (B, C, D, A, 12, 15); + ROUND3 (A, B, C, D, 2, 3); + ROUND3 (D, A, B, C, 10, 9); + ROUND3 (C, D, A, B, 6, 11); + ROUND3 (B, C, D, A, 14, 15); + ROUND3 (A, B, C, D, 1, 3); + ROUND3 (D, A, B, C, 9, 9); + ROUND3 (C, D, A, B, 5, 11); + ROUND3 (B, C, D, A, 13, 15); + ROUND3 (A, B, C, D, 3, 3); + ROUND3 (D, A, B, C, 11, 9); + ROUND3 (C, D, A, B, 7, 11); + ROUND3 (B, C, D, A, 15, 15); + + A += AA; + B += BB; + C += CC; + D += DD; + + A &= 0xFFFFFFFF; + B &= 0xFFFFFFFF; + C &= 0xFFFFFFFF; + D &= 0xFFFFFFFF; + + for (j = 0; j < 16; j++) + X[j] = 0; +} + +static void +copy64 (uint32 * M, unsigned char *in) +{ + int i; + + for (i = 0; i < 16; i++) + M[i] = (in[i * 4 + 3] << 24) | (in[i * 4 + 2] << 16) | + (in[i * 4 + 1] << 8) | (in[i * 4 + 0] << 0); +} + +static void +copy4 (unsigned char *out, uint32 x) +{ + out[0] = x & 0xFF; + out[1] = (x >> 8) & 0xFF; + out[2] = (x >> 16) & 0xFF; + out[3] = (x >> 24) & 0xFF; +} + +/* produce a md4 message digest from data of length n bytes */ +void +mdfour (unsigned char *out, unsigned char *in, int n) +{ + unsigned char buf[128]; + uint32 M[16]; + uint32 b = n * 8; + int i; + + A = 0x67452301; + B = 0xefcdab89; + C = 0x98badcfe; + D = 0x10325476; + + while (n > 64) + { + copy64 (M, in); + mdfour64 (M); + in += 64; + n -= 64; + } + + for (i = 0; i < 128; i++) + buf[i] = 0; + memcpy (buf, in, n); + buf[n] = 0x80; + + if (n <= 55) + { + copy4 (buf + 56, b); + copy64 (M, buf); + mdfour64 (M); + } + else + { + copy4 (buf + 120, b); + copy64 (M, buf); + mdfour64 (M); + copy64 (M, buf + 64); + mdfour64 (M); + } + + for (i = 0; i < 128; i++) + buf[i] = 0; + copy64 (M, buf); + + copy4 (out, A); + copy4 (out + 4, B); + copy4 (out + 8, C); + copy4 (out + 12, D); + + A = B = C = D = 0; +} diff --git a/src/vfs/smbfs/helpers/lib/netmask.c b/src/vfs/smbfs/helpers/lib/netmask.c index 05b9425b3..d23fd89c0 100644 --- a/src/vfs/smbfs/helpers/lib/netmask.c +++ b/src/vfs/smbfs/helpers/lib/netmask.c @@ -22,7 +22,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . -*/ + */ /* working out the netmask for an interface is an incredibly non-portable @@ -34,7 +34,7 @@ this code cannot use any of the normal Samba debug stuff or defines. This is standalone code. -*/ + */ #ifndef AUTOCONF #include "config.h" @@ -63,84 +63,89 @@ * Prototype for gcc in fussy mode. */ -int get_netmask(struct in_addr *ipaddr, struct in_addr *nmask); +int get_netmask (struct in_addr *ipaddr, struct in_addr *nmask); /**************************************************************************** get the netmask address for a local interface ****************************************************************************/ -int get_netmask(struct in_addr *ipaddr, struct in_addr *nmask) -{ - struct ifconf ifc; - char buff[2048]; - int fd, i, n; - struct ifreq *ifr=NULL; - - if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { +int +get_netmask (struct in_addr *ipaddr, struct in_addr *nmask) +{ + struct ifconf ifc; + char buff[2048]; + int fd, i, n; + struct ifreq *ifr = NULL; + + if ((fd = socket (AF_INET, SOCK_DGRAM, 0)) == -1) + { #ifdef DEBUG - fprintf(stderr,"socket failed\n"); + fprintf (stderr, "socket failed\n"); #endif - return -1; - } - - ifc.ifc_len = sizeof(buff); - ifc.ifc_buf = buff; - if (ioctl(fd, SIOCGIFCONF, &ifc) != 0) { + return -1; + } + + ifc.ifc_len = sizeof (buff); + ifc.ifc_buf = buff; + if (ioctl (fd, SIOCGIFCONF, &ifc) != 0) + { #ifdef DEBUG - fprintf(stderr,"SIOCGIFCONF failed\n"); + fprintf (stderr, "SIOCGIFCONF failed\n"); #endif - close(fd); - return -1; - } - - ifr = ifc.ifc_req; - - n = ifc.ifc_len / sizeof(struct ifreq); - + close (fd); + return -1; + } + + ifr = ifc.ifc_req; + + n = ifc.ifc_len / sizeof (struct ifreq); + #ifdef DEBUG - fprintf(stderr,"%d interfaces - looking for %s\n", - n, inet_ntoa(*ipaddr)); + fprintf (stderr, "%d interfaces - looking for %s\n", n, inet_ntoa (*ipaddr)); #endif - /* Loop through interfaces, looking for given IP address */ - for (i=n-1;i>=0;i--) { - if (ioctl(fd, SIOCGIFADDR, &ifr[i]) != 0) { + /* Loop through interfaces, looking for given IP address */ + for (i = n - 1; i >= 0; i--) + { + if (ioctl (fd, SIOCGIFADDR, &ifr[i]) != 0) + { #ifdef DEBUG - fprintf(stderr,"SIOCGIFADDR failed\n"); + fprintf (stderr, "SIOCGIFADDR failed\n"); #endif - continue; - } + continue; + } #ifdef DEBUG - fprintf(stderr,"interface %s\n", - inet_ntoa((*(struct sockaddr_in *)&ifr[i].ifr_addr).sin_addr)); + fprintf (stderr, "interface %s\n", + inet_ntoa ((*(struct sockaddr_in *) &ifr[i].ifr_addr).sin_addr)); #endif - if (ipaddr->s_addr != - (*(struct sockaddr_in *)&ifr[i].ifr_addr).sin_addr.s_addr) { - continue; - } + if (ipaddr->s_addr != (*(struct sockaddr_in *) &ifr[i].ifr_addr).sin_addr.s_addr) + { + continue; + } - if (ioctl(fd, SIOCGIFNETMASK, &ifr[i]) != 0) { + if (ioctl (fd, SIOCGIFNETMASK, &ifr[i]) != 0) + { #ifdef DEBUG - fprintf(stderr,"SIOCGIFNETMASK failed\n"); + fprintf (stderr, "SIOCGIFNETMASK failed\n"); #endif - close(fd); - return -1; - } - close(fd); - (*nmask) = ((struct sockaddr_in *)&ifr[i].ifr_addr)->sin_addr; + close (fd); + return -1; + } + close (fd); + (*nmask) = ((struct sockaddr_in *) &ifr[i].ifr_addr)->sin_addr; #ifdef DEBUG - fprintf(stderr,"netmask %s\n", inet_ntoa(*nmask)); + fprintf (stderr, "netmask %s\n", inet_ntoa (*nmask)); #endif - return 0; - } + return 0; + } #ifdef DEBUG - fprintf(stderr,"interface not found\n"); + fprintf (stderr, "interface not found\n"); #endif - close(fd); - return -1; -} + close (fd); + return -1; +} #elif defined(HAVE_NETMASK_IFREQ) @@ -165,84 +170,90 @@ int get_netmask(struct in_addr *ipaddr, struct in_addr *nmask) /**************************************************************************** this should cover most of the rest of systems ****************************************************************************/ - int get_netmask(struct in_addr *ipaddr, struct in_addr *nmask) +int +get_netmask (struct in_addr *ipaddr, struct in_addr *nmask) { - struct ifreq ifreq; - struct strioctl strioctl; - struct ifconf *ifc; - char buff[2048]; - int fd, i, n; - struct ifreq *ifr=NULL; - - if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { + struct ifreq ifreq; + struct strioctl strioctl; + struct ifconf *ifc; + char buff[2048]; + int fd, i, n; + struct ifreq *ifr = NULL; + + if ((fd = socket (AF_INET, SOCK_DGRAM, 0)) == -1) + { #ifdef DEBUG - fprintf(stderr,"socket failed\n"); + fprintf (stderr, "socket failed\n"); #endif - return -1; - } - - ifc = (struct ifconf *)buff; - ifc->ifc_len = BUFSIZ - sizeof(struct ifconf); - strioctl.ic_cmd = SIOCGIFCONF; - strioctl.ic_dp = (char *)ifc; - strioctl.ic_len = sizeof(buff); - if (ioctl(fd, I_STR, &strioctl) < 0) { + return -1; + } + + ifc = (struct ifconf *) buff; + ifc->ifc_len = BUFSIZ - sizeof (struct ifconf); + strioctl.ic_cmd = SIOCGIFCONF; + strioctl.ic_dp = (char *) ifc; + strioctl.ic_len = sizeof (buff); + if (ioctl (fd, I_STR, &strioctl) < 0) + { #ifdef DEBUG - fprintf(stderr,"SIOCGIFCONF failed\n"); + fprintf (stderr, "SIOCGIFCONF failed\n"); #endif - close(fd); - return -1; - } - - ifr = (struct ifreq *)ifc->ifc_req; + close (fd); + return -1; + } - /* Loop through interfaces, looking for given IP address */ - n = ifc->ifc_len / sizeof(struct ifreq); + ifr = (struct ifreq *) ifc->ifc_req; - for (i = 0; iifc_len / sizeof (struct ifreq); + + for (i = 0; i < n; i++, ifr++) + { #ifdef DEBUG - fprintf(stderr,"interface %s\n", - inet_ntoa((*(struct sockaddr_in *)&ifr->ifr_addr).sin_addr.s_addr)); + fprintf (stderr, "interface %s\n", + inet_ntoa ((*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr.s_addr)); #endif - if (ipaddr->s_addr == - (*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr.s_addr) { - break; - } - } + if (ipaddr->s_addr == (*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr.s_addr) + { + break; + } + } #ifdef DEBUG - if (i == n) { - fprintf(stderr,"interface not found\n"); - close(fd); - return -1; - } + if (i == n) + { + fprintf (stderr, "interface not found\n"); + close (fd); + return -1; + } #endif - ifreq = *ifr; - - strioctl.ic_cmd = SIOCGIFNETMASK; - strioctl.ic_dp = (char *)&ifreq; - strioctl.ic_len = sizeof(struct ifreq); - if (ioctl(fd, I_STR, &strioctl) != 0) { + ifreq = *ifr; + + strioctl.ic_cmd = SIOCGIFNETMASK; + strioctl.ic_dp = (char *) &ifreq; + strioctl.ic_len = sizeof (struct ifreq); + if (ioctl (fd, I_STR, &strioctl) != 0) + { #ifdef DEBUG - fprintf(stderr,"Failed SIOCGIFNETMASK\n"); + fprintf (stderr, "Failed SIOCGIFNETMASK\n"); #endif - close(fd); - return -1; - } + close (fd); + return -1; + } - close(fd); - *nmask = ((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr; + close (fd); + *nmask = ((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr; #ifdef DEBUG - fprintf(stderr,"netmask %s\n", inet_ntoa(*nmask)); + fprintf (stderr, "netmask %s\n", inet_ntoa (*nmask)); #endif - return 0; + return 0; } #elif defined(HAVE_NETMASK_AIX) #include -#include /* close() declaration for gcc in fussy mode */ +#include /* close() declaration for gcc in fussy mode */ #include #include #include @@ -259,87 +270,93 @@ this should cover most of the rest of systems * Prototype for gcc in fussy mode. */ -int get_netmask(struct in_addr *ipaddr, struct in_addr *nmask); +int get_netmask (struct in_addr *ipaddr, struct in_addr *nmask); /**************************************************************************** this one is for AIX ****************************************************************************/ - int get_netmask(struct in_addr *ipaddr, struct in_addr *nmask) +int +get_netmask (struct in_addr *ipaddr, struct in_addr *nmask) { - char buff[2048]; - int fd, i; - struct ifconf ifc; - struct ifreq *ifr=NULL; + char buff[2048]; + int fd, i; + struct ifconf ifc; + struct ifreq *ifr = NULL; - if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { + if ((fd = socket (AF_INET, SOCK_DGRAM, 0)) == -1) + { #ifdef DEBUG - fprintf(stderr,"socket failed\n"); + fprintf (stderr, "socket failed\n"); #endif - return -1; - } + return -1; + } - ifc.ifc_len = sizeof(buff); - ifc.ifc_buf = buff; + ifc.ifc_len = sizeof (buff); + ifc.ifc_buf = buff; - if (ioctl(fd, SIOCGIFCONF, &ifc) != 0) { + if (ioctl (fd, SIOCGIFCONF, &ifc) != 0) + { #ifdef DEBUG - fprintf(stderr,"SIOCGIFCONF failed\n"); + fprintf (stderr, "SIOCGIFCONF failed\n"); #endif - close(fd); - return -1; - } - - ifr = ifc.ifc_req; - /* Loop through interfaces, looking for given IP address */ - i = ifc.ifc_len; - while (i > 0) { + close (fd); + return -1; + } + + ifr = ifc.ifc_req; + /* Loop through interfaces, looking for given IP address */ + i = ifc.ifc_len; + while (i > 0) + { #ifdef DEBUG - fprintf(stderr,"interface %s\n", - inet_ntoa((*(struct sockaddr_in *)&ifr->ifr_addr).sin_addr)); + fprintf (stderr, "interface %s\n", + inet_ntoa ((*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr)); #endif - if (ipaddr->s_addr == - (*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr.s_addr) { - break; - } - i -= ifr->ifr_addr.sa_len + IFNAMSIZ; - ifr = (struct ifreq*) ((char*) ifr + ifr->ifr_addr.sa_len + - IFNAMSIZ); - } - + if (ipaddr->s_addr == (*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr.s_addr) + { + break; + } + i -= ifr->ifr_addr.sa_len + IFNAMSIZ; + ifr = (struct ifreq *) ((char *) ifr + ifr->ifr_addr.sa_len + IFNAMSIZ); + } + #ifdef DEBUG - if (i <= 0) { - fprintf(stderr,"interface not found\n"); - close(fd); - return -1; - } + if (i <= 0) + { + fprintf (stderr, "interface not found\n"); + close (fd); + return -1; + } #endif - if (ioctl(fd, SIOCGIFNETMASK, ifr) != 0) { + if (ioctl (fd, SIOCGIFNETMASK, ifr) != 0) + { #ifdef DEBUG - fprintf(stderr,"SIOCGIFNETMASK failed\n"); + fprintf (stderr, "SIOCGIFNETMASK failed\n"); #endif - close(fd); - return -1; - } + close (fd); + return -1; + } - close(fd); + close (fd); - (*nmask) = ((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr; + (*nmask) = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr; #ifdef DEBUG - fprintf(stderr,"netmask %s\n", inet_ntoa(*nmask)); + fprintf (stderr, "netmask %s\n", inet_ntoa (*nmask)); #endif - return 0; + return 0; } #else /* a dummy version */ -struct in_addr; /* it may not have been declared before */ -int get_netmask(struct in_addr *ipaddr, struct in_addr *nmask); - int get_netmask(struct in_addr *ipaddr, struct in_addr *nmask) +struct in_addr; /* it may not have been declared before */ +int get_netmask (struct in_addr *ipaddr, struct in_addr *nmask); +int +get_netmask (struct in_addr *ipaddr, struct in_addr *nmask) { - return -1; + return -1; } #endif @@ -347,29 +364,32 @@ int get_netmask(struct in_addr *ipaddr, struct in_addr *nmask); #ifdef AUTOCONF /* this is the autoconf driver to test get_netmask() */ - main() +main () { - char buf[1024]; - struct hostent *hp; - struct in_addr ip, nmask; + char buf[1024]; + struct hostent *hp; + struct in_addr ip, nmask; - if (gethostname(buf, sizeof(buf)-1) != 0) { - fprintf(stderr,"gethostname failed\n"); - exit(1); - } + if (gethostname (buf, sizeof (buf) - 1) != 0) + { + fprintf (stderr, "gethostname failed\n"); + exit (1); + } - hp = gethostbyname(buf); + hp = gethostbyname (buf); - if (!hp) { - fprintf(stderr,"gethostbyname failed\n"); - exit(1); - } + if (!hp) + { + fprintf (stderr, "gethostbyname failed\n"); + exit (1); + } - memcpy((char *)&ip, (char *)hp->h_addr, hp->h_length); + memcpy ((char *) &ip, (char *) hp->h_addr, hp->h_length); - if (get_netmask(&ip, &nmask) == 0) exit(0); + if (get_netmask (&ip, &nmask) == 0) + exit (0); - fprintf(stderr,"get_netmask failed\n"); - exit(1); + fprintf (stderr, "get_netmask failed\n"); + exit (1); } #endif diff --git a/src/vfs/smbfs/helpers/lib/slprintf.c b/src/vfs/smbfs/helpers/lib/slprintf.c index 6ca11967e..28a2804b3 100644 --- a/src/vfs/smbfs/helpers/lib/slprintf.c +++ b/src/vfs/smbfs/helpers/lib/slprintf.c @@ -22,7 +22,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . -*/ + */ #include "includes.h" @@ -32,40 +32,44 @@ extern int DEBUGLEVEL; /* this is like vsnprintf but the 'n' limit does not include the terminating null. So if you have a 1024 byte buffer then pass 1023 for n */ -int vslprintf(char *str, int n, const char *format, va_list ap) +int +vslprintf (char *str, int n, const char *format, va_list ap) { - int ret = vsnprintf(str, n, format, ap); - if (ret > n || ret < 0) { - str[n] = 0; - return -1; - } - str[ret] = 0; - return ret; + int ret = vsnprintf (str, n, format, ap); + if (ret > n || ret < 0) + { + str[n] = 0; + return -1; + } + str[ret] = 0; + return ret; } #ifdef HAVE_STDARG_H - int slprintf(char *str, int n, const char *format, ...) +int +slprintf (char *str, int n, const char *format, ...) { #else - int slprintf(va_alist) -va_dcl +int +slprintf (va_alist) + va_dcl { - char *str, *format; - int n; + char *str, *format; + int n; #endif - va_list ap; - int ret; + va_list ap; + int ret; #ifdef HAVE_STDARG_H - va_start(ap, format); + va_start (ap, format); #else - va_start(ap); - str = va_arg(ap,char *); - n = va_arg(ap,int); - format = va_arg(ap,char *); + va_start (ap); + str = va_arg (ap, char *); + n = va_arg (ap, int); + format = va_arg (ap, char *); #endif - ret = vslprintf(str,n,format,ap); - va_end(ap); - return ret; + ret = vslprintf (str, n, format, ap); + va_end (ap); + return ret; } diff --git a/src/vfs/smbfs/helpers/lib/system.c b/src/vfs/smbfs/helpers/lib/system.c index d8d630a50..70d88ecf0 100644 --- a/src/vfs/smbfs/helpers/lib/system.c +++ b/src/vfs/smbfs/helpers/lib/system.c @@ -22,7 +22,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . -*/ + */ #include "includes.h" @@ -39,9 +39,9 @@ extern int DEBUGLEVEL; - to allow easier integration of things like the japanese extensions - to support the philosophy of Samba to expose the features of - the OS within the SMB model. In general whatever file/printer/variable - expansions/etc make sense to the OS should be acceptable to Samba. -*/ + the OS within the SMB model. In general whatever file/printer/variable + expansions/etc make sense to the OS should be acceptable to Samba. + */ /******************************************************************* @@ -50,96 +50,109 @@ return if some data has arrived on one of the file descriptors return -1 means error ********************************************************************/ #ifndef HAVE_SELECT -static int pollfd(int fd) +static int +pollfd (int fd) { - int r=0; + int r = 0; #ifdef HAS_RDCHK - r = rdchk(fd); + r = rdchk (fd); #elif defined(TCRDCHK) - (void)ioctl(fd, TCRDCHK, &r); + (void) ioctl (fd, TCRDCHK, &r); #else - (void)ioctl(fd, FIONREAD, &r); + (void) ioctl (fd, FIONREAD, &r); #endif - return(r); + return (r); } -int sys_select(int maxfd, fd_set *fds,struct timeval *tval) +int +sys_select (int maxfd, fd_set * fds, struct timeval *tval) { - fd_set fds2; - int counter=0; - int found=0; - - FD_ZERO(&fds2); - - while (1) - { - int i; - for (i=0;i0) { - found++; - FD_SET(i,&fds2); - } + fd_set fds2; + int counter = 0; + int found = 0; + + FD_ZERO (&fds2); + + while (1) + { + int i; + for (i = 0; i < maxfd; i++) + { + if (FD_ISSET (i, fds) && pollfd (i) > 0) + { + found++; + FD_SET (i, &fds2); + } + } + + if (found) + { + memcpy ((void *) fds, (void *) &fds2, sizeof (fds2)); + return (found); + } + + if (tval && tval->tv_sec < counter) + return (0); + sleep (1); + counter++; } - - if (found) { - memcpy((void *)fds,(void *)&fds2,sizeof(fds2)); - return(found); - } - - if (tval && tval->tv_sec < counter) return(0); - sleep(1); - counter++; - } } #else /* !NO_SELECT */ -int sys_select(int maxfd, fd_set *fds,struct timeval *tval) +int +sys_select (int maxfd, fd_set * fds, struct timeval *tval) { #ifdef USE_POLL - struct pollfd pfd[256]; - int i; - int maxpoll; - int timeout; - int pollrtn; - - maxpoll = 0; - for( i = 0; i < maxfd; i++) { - if(FD_ISSET(i,fds)) { - struct pollfd *pfdp = &pfd[maxpoll++]; - pfdp->fd = i; - pfdp->events = POLLIN; - pfdp->revents = 0; + struct pollfd pfd[256]; + int i; + int maxpoll; + int timeout; + int pollrtn; + + maxpoll = 0; + for (i = 0; i < maxfd; i++) + { + if (FD_ISSET (i, fds)) + { + struct pollfd *pfdp = &pfd[maxpoll++]; + pfdp->fd = i; + pfdp->events = POLLIN; + pfdp->revents = 0; + } } - } - timeout = (tval != NULL) ? (tval->tv_sec * 1000) + (tval->tv_usec/1000) : - -1; - errno = 0; - do { - pollrtn = poll( &pfd[0], maxpoll, timeout); - } while (pollrtn<0 && errno == EINTR); + timeout = (tval != NULL) ? (tval->tv_sec * 1000) + (tval->tv_usec / 1000) : -1; + errno = 0; + do + { + pollrtn = poll (&pfd[0], maxpoll, timeout); + } + while (pollrtn < 0 && errno == EINTR); - FD_ZERO(fds); + FD_ZERO (fds); - for( i = 0; i < maxpoll; i++) - if( pfd[i].revents & POLLIN ) - FD_SET(pfd[i].fd,fds); + for (i = 0; i < maxpoll; i++) + if (pfd[i].revents & POLLIN) + FD_SET (pfd[i].fd, fds); - return pollrtn; + return pollrtn; #else /* USE_POLL */ - struct timeval t2; - int selrtn; + struct timeval t2; + int selrtn; - do { - if (tval) memcpy((void *)&t2,(void *)tval,sizeof(t2)); - errno = 0; - selrtn = select(maxfd,SELECT_CAST fds,NULL,NULL,tval?&t2:NULL); - } while (selrtn<0 && errno == EINTR); + do + { + if (tval) + memcpy ((void *) &t2, (void *) tval, sizeof (t2)); + errno = 0; + selrtn = select (maxfd, SELECT_CAST fds, NULL, NULL, tval ? &t2 : NULL); + } + while (selrtn < 0 && errno == EINTR); - return(selrtn); + return (selrtn); } #endif /* USE_POLL */ #endif /* NO_SELECT */ @@ -148,75 +161,84 @@ int sys_select(int maxfd, fd_set *fds,struct timeval *tval) A stat() wrapper that will deal with 64 bit filesizes. ********************************************************************/ -int sys_stat(const char *fname,SMB_STRUCT_STAT *sbuf) +int +sys_stat (const char *fname, SMB_STRUCT_STAT * sbuf) { - return stat(fname, sbuf); + return stat (fname, sbuf); } /******************************************************************* An lstat() wrapper that will deal with 64 bit filesizes. ********************************************************************/ #if 0 -int sys_lstat(const char *fname,SMB_STRUCT_STAT *sbuf) +int +sys_lstat (const char *fname, SMB_STRUCT_STAT * sbuf) { - return lstat(fname, sbuf); + return lstat (fname, sbuf); } /******************************************************************* An fseek() wrapper that will deal with 64 bit filesizes. ********************************************************************/ -int sys_fseek(FILE *fp, SMB_OFF_T offset, int whence) +int +sys_fseek (FILE * fp, SMB_OFF_T offset, int whence) { - return fseek(fp, offset, whence); + return fseek (fp, offset, whence); } /******************************************************************* An ftell() wrapper that will deal with 64 bit filesizes. ********************************************************************/ -SMB_OFF_T sys_ftell(FILE *fp) +SMB_OFF_T +sys_ftell (FILE * fp) { - return (SMB_OFF_T)ftell(fp); + return (SMB_OFF_T) ftell (fp); } #endif /* 0 */ /******************************************************************* An open() wrapper that will deal with 64 bit filesizes. ********************************************************************/ -int sys_open(const char *path, int oflag, mode_t mode) +int +sys_open (const char *path, int oflag, mode_t mode) { - return open(path, oflag, mode); + return open (path, oflag, mode); } /******************************************************************* An fopen() wrapper that will deal with 64 bit filesizes. ********************************************************************/ -FILE *sys_fopen(const char *path, const char *type) +FILE * +sys_fopen (const char *path, const char *type) { - return fopen(path, type); + return fopen (path, type); } + #if 0 /******************************************************************* A readdir wrapper that will deal with 64 bit filesizes. ********************************************************************/ -SMB_STRUCT_DIRENT *sys_readdir(DIR *dirp) +SMB_STRUCT_DIRENT * +sys_readdir (DIR * dirp) { - return readdir(dirp); + return readdir (dirp); } /******************************************************************* system wrapper for getwd ********************************************************************/ -char *sys_getwd(char *s) +char * +sys_getwd (char *s) { char *wd; #ifdef HAVE_GETCWD - wd = (char *)getcwd(s, sizeof (pstring)); + wd = (char *) getcwd (s, sizeof (pstring)); #else - wd = (char *)getwd(s); + wd = (char *) getwd (s); #endif return wd; } @@ -225,16 +247,18 @@ char *sys_getwd(char *s) chown isn't used much but OS/2 doesn't have it ********************************************************************/ -int sys_chown(const char *fname,uid_t uid,gid_t gid) +int +sys_chown (const char *fname, uid_t uid, gid_t gid) { #ifndef HAVE_CHOWN - static int done; - if (!done) { - DEBUG(1,("WARNING: no chown!\n")); - done=1; - } + static int done; + if (!done) + { + DEBUG (1, ("WARNING: no chown!\n")); + done = 1; + } #else - return(chown(fname,uid,gid)); + return (chown (fname, uid, gid)); #endif } #endif /* 0 */ @@ -243,39 +267,40 @@ A wrapper for gethostbyname() that tries avoids looking up hostnames in the root domain, which can cause dial-on-demand links to come up for no apparent reason. ****************************************************************************/ -struct hostent *sys_gethostbyname(const char *name) +struct hostent * +sys_gethostbyname (const char *name) { #ifdef REDUCE_ROOT_DNS_LOOKUPS - char query[256], hostname[256]; - char *domain; + char query[256], hostname[256]; + char *domain; - /* Does this name have any dots in it? If so, make no change */ + /* Does this name have any dots in it? If so, make no change */ - if (strchr(name, '.')) - return(gethostbyname(name)); + if (strchr (name, '.')) + return (gethostbyname (name)); - /* Get my hostname, which should have domain name - attached. If not, just do the gethostname on the - original string. - */ + /* Get my hostname, which should have domain name + attached. If not, just do the gethostname on the + original string. + */ - gethostname(hostname, sizeof(hostname) - 1); - hostname[sizeof(hostname) - 1] = 0; - if ((domain = strchr(hostname, '.')) == NULL) - return(gethostbyname(name)); + gethostname (hostname, sizeof (hostname) - 1); + hostname[sizeof (hostname) - 1] = 0; + if ((domain = strchr (hostname, '.')) == NULL) + return (gethostbyname (name)); - /* Attach domain name to query and do modified query. - If names too large, just do gethostname on the - original string. - */ + /* Attach domain name to query and do modified query. + If names too large, just do gethostname on the + original string. + */ - if((strlen(name) + strlen(domain)) >= sizeof(query)) - return(gethostbyname(name)); + if ((strlen (name) + strlen (domain)) >= sizeof (query)) + return (gethostbyname (name)); - slprintf(query, sizeof(query)-1, "%s%s", name, domain); - return(gethostbyname(query)); + slprintf (query, sizeof (query) - 1, "%s%s", name, domain); + return (gethostbyname (query)); #else /* REDUCE_ROOT_DNS_LOOKUPS */ - return(gethostbyname(name)); + return (gethostbyname (name)); #endif /* REDUCE_ROOT_DNS_LOOKUPS */ } @@ -283,15 +308,16 @@ struct hostent *sys_gethostbyname(const char *name) Wrapper for random(). ****************************************************************************/ #if 0 -long sys_random(void) +long +sys_random (void) { #if defined(HAVE_RANDOM) - return (long)random(); + return (long) random (); #elif defined(HAVE_RAND) - return (long)rand(); + return (long) rand (); #else - DEBUG(0,("Error - no random function available !\n")); - exit(1); + DEBUG (0, ("Error - no random function available !\n")); + exit (1); #endif } @@ -299,15 +325,16 @@ long sys_random(void) Wrapper for srandom(). ****************************************************************************/ -void sys_srandom(unsigned int seed) +void +sys_srandom (unsigned int seed) { #if defined(HAVE_SRANDOM) - srandom(seed); + srandom (seed); #elif defined(HAVE_SRAND) - srand(seed); + srand (seed); #else - DEBUG(0,("Error - no srandom function available !\n")); - exit(1); + DEBUG (0, ("Error - no srandom function available !\n")); + exit (1); #endif } #endif /* 0 */ diff --git a/src/vfs/smbfs/helpers/lib/time.c b/src/vfs/smbfs/helpers/lib/time.c index 3875d673d..2c236a566 100644 --- a/src/vfs/smbfs/helpers/lib/time.c +++ b/src/vfs/smbfs/helpers/lib/time.c @@ -22,17 +22,17 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . -*/ + */ #include "includes.h" /* - This stuff was largely rewritten by Paul Eggert - in May 1996 - */ + This stuff was largely rewritten by Paul Eggert + in May 1996 + */ -int serverzone=0; +int serverzone = 0; int extra_time_offset = 0; extern int DEBUGLEVEL; @@ -54,12 +54,13 @@ extern int DEBUGLEVEL; /******************************************************************* a gettimeofday wrapper ********************************************************************/ -void GetTimeOfDay(struct timeval *tval) +void +GetTimeOfDay (struct timeval *tval) { #ifdef HAVE_GETTIMEOFDAY_TZ - gettimeofday(tval,NULL); + gettimeofday (tval, NULL); #else - gettimeofday(tval); + gettimeofday (tval); #endif } @@ -68,35 +69,36 @@ void GetTimeOfDay(struct timeval *tval) /******************************************************************* yield the difference between *A and *B, in seconds, ignoring leap seconds ********************************************************************/ -static int tm_diff(struct tm *a, struct tm *b) +static int +tm_diff (struct tm *a, struct tm *b) { - int ay = a->tm_year + (TM_YEAR_BASE - 1); - int by = b->tm_year + (TM_YEAR_BASE - 1); - int intervening_leap_days = - (ay/4 - by/4) - (ay/100 - by/100) + (ay/400 - by/400); - int years = ay - by; - int days = 365*years + intervening_leap_days + (a->tm_yday - b->tm_yday); - int hours = 24*days + (a->tm_hour - b->tm_hour); - int minutes = 60*hours + (a->tm_min - b->tm_min); - int seconds = 60*minutes + (a->tm_sec - b->tm_sec); - - return seconds; + int ay = a->tm_year + (TM_YEAR_BASE - 1); + int by = b->tm_year + (TM_YEAR_BASE - 1); + int intervening_leap_days = (ay / 4 - by / 4) - (ay / 100 - by / 100) + (ay / 400 - by / 400); + int years = ay - by; + int days = 365 * years + intervening_leap_days + (a->tm_yday - b->tm_yday); + int hours = 24 * days + (a->tm_hour - b->tm_hour); + int minutes = 60 * hours + (a->tm_min - b->tm_min); + int seconds = 60 * minutes + (a->tm_sec - b->tm_sec); + + return seconds; } /******************************************************************* return the UTC offset in seconds west of UTC, or 0 if it cannot be determined ******************************************************************/ -static int TimeZone(time_t t) +static int +TimeZone (time_t t) { - struct tm *tm = gmtime(&t); - struct tm tm_utc; - if (!tm) - return 0; - tm_utc = *tm; - tm = localtime(&t); - if (!tm) - return 0; - return tm_diff(&tm_utc,tm); + struct tm *tm = gmtime (&t); + struct tm tm_utc; + if (!tm) + return 0; + tm_utc = *tm; + tm = localtime (&t); + if (!tm) + return 0; + return tm_diff (&tm_utc, tm); } @@ -104,15 +106,17 @@ static int TimeZone(time_t t) /******************************************************************* init the time differences ********************************************************************/ -void TimeInit(void) +void +TimeInit (void) { - serverzone = TimeZone(time(NULL)); + serverzone = TimeZone (time (NULL)); - if ((serverzone % 60) != 0) { - DEBUG(1,("WARNING: Your timezone is not a multiple of 1 minute.\n")); - } + if ((serverzone % 60) != 0) + { + DEBUG (1, ("WARNING: Your timezone is not a multiple of 1 minute.\n")); + } - DEBUG(4,("Serverzone is %d\n",serverzone)); + DEBUG (4, ("Serverzone is %d\n", serverzone)); } @@ -124,86 +128,99 @@ call of this function. This saves a LOT of time on many unixes. Updated by Paul Eggert ********************************************************************/ -static int TimeZoneFaster(time_t t) +static int +TimeZoneFaster (time_t t) { - static struct dst_table {time_t start,end; int zone;} *dst_table = NULL; - static int table_size = 0; - int i; - int zone = 0; - - if (t == 0) t = time(NULL); - - /* Tunis has a 8 day DST region, we need to be careful ... */ + static struct dst_table + { + time_t start, end; + int zone; + } *dst_table = NULL; + static int table_size = 0; + int i; + int zone = 0; + + if (t == 0) + t = time (NULL); + + /* Tunis has a 8 day DST region, we need to be careful ... */ #define MAX_DST_WIDTH (365*24*60*60) #define MAX_DST_SKIP (7*24*60*60) - for (i=0;i= dst_table[i].start && t <= dst_table[i].end) break; - - if (i MAX_DST_SKIP*2) - t = dst_table[i].start - MAX_DST_SKIP; - else - t = low + (dst_table[i].start-low)/2; - if (TimeZone(t) == zone) - dst_table[i].start = t; - else - low = t; - } - - while (high-60*60 > dst_table[i].end) { - if (high - dst_table[i].end > MAX_DST_SKIP*2) - t = dst_table[i].end + MAX_DST_SKIP; - else - t = high - (high-dst_table[i].end)/2; - if (TimeZone(t) == zone) - dst_table[i].end = t; - else - high = t; - } + for (i = 0; i < table_size; i++) + if (t >= dst_table[i].start && t <= dst_table[i].end) + break; + + if (i < table_size) + { + zone = dst_table[i].zone; + } + else + { + time_t low, high; + + zone = TimeZone (t); + dst_table = (struct dst_table *) Realloc (dst_table, sizeof (dst_table[0]) * (i + 1)); + if (!dst_table) + { + table_size = 0; + } + else + { + table_size++; + + dst_table[i].zone = zone; + dst_table[i].start = dst_table[i].end = t; + + /* no entry will cover more than 6 months */ + low = t - MAX_DST_WIDTH / 2; + if (t < low) + low = TIME_T_MIN; + + high = t + MAX_DST_WIDTH / 2; + if (high < t) + high = TIME_T_MAX; + + /* widen the new entry using two bisection searches */ + while (low + 60 * 60 < dst_table[i].start) + { + if (dst_table[i].start - low > MAX_DST_SKIP * 2) + t = dst_table[i].start - MAX_DST_SKIP; + else + t = low + (dst_table[i].start - low) / 2; + if (TimeZone (t) == zone) + dst_table[i].start = t; + else + low = t; + } + + while (high - 60 * 60 > dst_table[i].end) + { + if (high - dst_table[i].end > MAX_DST_SKIP * 2) + t = dst_table[i].end + MAX_DST_SKIP; + else + t = high - (high - dst_table[i].end) / 2; + if (TimeZone (t) == zone) + dst_table[i].end = t; + else + high = t; + } #if 0 - DEBUG(1,("Added DST entry from %s ", - asctime(localtime(&dst_table[i].start)))); - DEBUG(1,("to %s (%d)\n",asctime(localtime(&dst_table[i].end)), - dst_table[i].zone)); + DEBUG (1, ("Added DST entry from %s ", asctime (localtime (&dst_table[i].start)))); + DEBUG (1, ("to %s (%d)\n", asctime (localtime (&dst_table[i].end)), dst_table[i].zone)); #endif + } } - } - return zone; + return zone; } /**************************************************************************** return the UTC offset in seconds west of UTC, adjusted for extra time offset **************************************************************************/ -int TimeDiff(time_t t) +int +TimeDiff (time_t t) { - return TimeZoneFaster(t) + 60*extra_time_offset; + return TimeZoneFaster (t) + 60 * extra_time_offset; } @@ -214,31 +231,33 @@ int TimeDiff(time_t t) daylight savings transitions because some local times are ambiguous. LocTimeDiff(t) equals TimeDiff(t) except near daylight savings transitions. +**************************************************************************/ -static int LocTimeDiff(time_t lte) +static int +LocTimeDiff (time_t lte) { - time_t lt = lte - 60*extra_time_offset; - int d = TimeZoneFaster(lt); - time_t t = lt + d; + time_t lt = lte - 60 * extra_time_offset; + int d = TimeZoneFaster (lt); + time_t t = lt + d; - /* if overflow occurred, ignore all the adjustments so far */ - if (((lte < lt) ^ (extra_time_offset < 0)) | ((t < lt) ^ (d < 0))) - t = lte; + /* if overflow occurred, ignore all the adjustments so far */ + if (((lte < lt) ^ (extra_time_offset < 0)) | ((t < lt) ^ (d < 0))) + t = lte; - /* now t should be close enough to the true UTC to yield the right answer */ - return TimeDiff(t); + /* now t should be close enough to the true UTC to yield the right answer */ + return TimeDiff (t); } /**************************************************************************** try to optimise the localtime call, it can be quite expensive on some machines ****************************************************************************/ -struct tm *LocalTime(time_t *t) +struct tm * +LocalTime (time_t * t) { - time_t t2 = *t; + time_t t2 = *t; - t2 -= TimeDiff(t2); + t2 -= TimeDiff (t2); - return(gmtime(&t2)); + return (gmtime (&t2)); } #define TIME_FIXUP_CONSTANT (369.0*365.25*24*60*60-(3.0*24*60*60+6.0*60*60)) @@ -252,34 +271,36 @@ its the GMT you get by taking a localtime and adding the serverzone. This is NOT the same as GMT in some cases. This routine converts this to real GMT. ****************************************************************************/ -time_t nt_time_to_unix(NTTIME *nt) +time_t +nt_time_to_unix (NTTIME * nt) { - double d; - time_t ret; - /* The next two lines are a fix needed for the - broken SCO compiler. JRA. */ - time_t l_time_min = TIME_T_MIN; - time_t l_time_max = TIME_T_MAX; + double d; + time_t ret; + /* The next two lines are a fix needed for the + broken SCO compiler. JRA. */ + time_t l_time_min = TIME_T_MIN; + time_t l_time_max = TIME_T_MAX; + + if (nt->high == 0) + return (0); - if (nt->high == 0) return(0); + d = ((double) nt->high) * 4.0 * (double) (1 << 30); + d += (nt->low & 0xFFF00000); + d *= 1.0e-7; - d = ((double)nt->high)*4.0*(double)(1<<30); - d += (nt->low&0xFFF00000); - d *= 1.0e-7; - - /* now adjust by 369 years to make the secs since 1970 */ - d -= TIME_FIXUP_CONSTANT; + /* now adjust by 369 years to make the secs since 1970 */ + d -= TIME_FIXUP_CONSTANT; - if (!(l_time_min <= d && d <= l_time_max)) - return(0); + if (!(l_time_min <= d && d <= l_time_max)) + return (0); - ret = (time_t)(d+0.5); + ret = (time_t) (d + 0.5); - /* this takes us from kludge-GMT to real GMT */ - ret -= serverzone; - ret += LocTimeDiff(ret); + /* this takes us from kludge-GMT to real GMT */ + ret -= serverzone; + ret += LocTimeDiff (ret); - return(ret); + return (ret); } @@ -287,38 +308,40 @@ time_t nt_time_to_unix(NTTIME *nt) /**************************************************************************** interprets an nt time into a unix time_t ****************************************************************************/ -time_t interpret_long_date(char *p) +time_t +interpret_long_date (char *p) { - NTTIME nt; - nt.low = IVAL(p,0); - nt.high = IVAL(p,4); - return nt_time_to_unix(&nt); + NTTIME nt; + nt.low = IVAL (p, 0); + nt.high = IVAL (p, 4); + return nt_time_to_unix (&nt); } /**************************************************************************** put a 8 byte filetime from a time_t This takes real GMT as input and converts to kludge-GMT ****************************************************************************/ -void unix_to_nt_time(NTTIME *nt, time_t t) +void +unix_to_nt_time (NTTIME * nt, time_t t) { - double d; + double d; - if (t==0) - { - nt->low = 0; - nt->high = 0; - return; - } + if (t == 0) + { + nt->low = 0; + nt->high = 0; + return; + } - /* this converts GMT to kludge-GMT */ - t -= LocTimeDiff(t) - serverzone; + /* this converts GMT to kludge-GMT */ + t -= LocTimeDiff (t) - serverzone; - d = (double)(t); - d += TIME_FIXUP_CONSTANT; - d *= 1.0e7; + d = (double) (t); + d += TIME_FIXUP_CONSTANT; + d *= 1.0e7; - nt->high = (uint32)(d * (1.0/(4.0*(double)(1<<30)))); - nt->low = (uint32)(d - ((double)nt->high)*4.0*(double)(1<<30)); + nt->high = (uint32) (d * (1.0 / (4.0 * (double) (1 << 30)))); + nt->low = (uint32) (d - ((double) nt->high) * 4.0 * (double) (1 << 30)); } @@ -326,84 +349,91 @@ void unix_to_nt_time(NTTIME *nt, time_t t) take an NTTIME structure, containing high / low time. convert to unix time. lkclXXXX this may need 2 SIVALs not a memcpy. we'll see... ****************************************************************************/ -void put_long_date(char *p,time_t t) +void +put_long_date (char *p, time_t t) { - NTTIME nt; - unix_to_nt_time(&nt, t); - SIVAL(p, 0, nt.low); - SIVAL(p, 4, nt.high); + NTTIME nt; + unix_to_nt_time (&nt, t); + SIVAL (p, 0, nt.low); + SIVAL (p, 4, nt.high); } /**************************************************************************** check if it's a null mtime ****************************************************************************/ -BOOL null_mtime(time_t mtime) +BOOL +null_mtime (time_t mtime) { - if (mtime == (time_t)0 || mtime == (time_t)0xFFFFFFFF || mtime == (time_t)-1) - return(True); - return(False); + if (mtime == (time_t) 0 || mtime == (time_t) 0xFFFFFFFF || mtime == (time_t) - 1) + return (True); + return (False); } /******************************************************************* create a 16 bit dos packed date ********************************************************************/ -static uint16 make_dos_date1(struct tm *t) +static uint16 +make_dos_date1 (struct tm *t) { - uint16 ret=0; - ret = (((unsigned)(t->tm_mon+1)) >> 3) | ((t->tm_year-80) << 1); - ret = ((ret&0xFF)<<8) | (t->tm_mday | (((t->tm_mon+1) & 0x7) << 5)); - return(ret); + uint16 ret = 0; + ret = (((unsigned) (t->tm_mon + 1)) >> 3) | ((t->tm_year - 80) << 1); + ret = ((ret & 0xFF) << 8) | (t->tm_mday | (((t->tm_mon + 1) & 0x7) << 5)); + return (ret); } /******************************************************************* create a 16 bit dos packed time ********************************************************************/ -static uint16 make_dos_time1(struct tm *t) +static uint16 +make_dos_time1 (struct tm *t) { - uint16 ret=0; - ret = ((((unsigned)t->tm_min >> 3)&0x7) | (((unsigned)t->tm_hour) << 3)); - ret = ((ret&0xFF)<<8) | ((t->tm_sec/2) | ((t->tm_min & 0x7) << 5)); - return(ret); + uint16 ret = 0; + ret = ((((unsigned) t->tm_min >> 3) & 0x7) | (((unsigned) t->tm_hour) << 3)); + ret = ((ret & 0xFF) << 8) | ((t->tm_sec / 2) | ((t->tm_min & 0x7) << 5)); + return (ret); } /******************************************************************* create a 32 bit dos packed date/time from some parameters This takes a GMT time and returns a packed localtime structure ********************************************************************/ -static uint32 make_dos_date(time_t unixdate) +static uint32 +make_dos_date (time_t unixdate) { - struct tm *t; - uint32 ret=0; + struct tm *t; + uint32 ret = 0; - t = LocalTime(&unixdate); - if (!t) - return 0xFFFFFFFF; + t = LocalTime (&unixdate); + if (!t) + return 0xFFFFFFFF; - ret = make_dos_date1(t); - ret = ((ret&0xFFFF)<<16) | make_dos_time1(t); + ret = make_dos_date1 (t); + ret = ((ret & 0xFFFF) << 16) | make_dos_time1 (t); - return(ret); + return (ret); } /******************************************************************* put a dos date into a buffer (time/date format) This takes GMT time and puts local time in the buffer ********************************************************************/ -void put_dos_date(char *buf,int offset,time_t unixdate) +void +put_dos_date (char *buf, int offset, time_t unixdate) { - uint32 x = make_dos_date(unixdate); - SIVAL(buf,offset,x); + uint32 x = make_dos_date (unixdate); + SIVAL (buf, offset, x); } /******************************************************************* put a dos date into a buffer (date/time format) This takes GMT time and puts local time in the buffer ********************************************************************/ -void put_dos_date2(char *buf,int offset,time_t unixdate) +void +put_dos_date2 (char *buf, int offset, time_t unixdate) { - uint32 x = make_dos_date(unixdate); - x = ((x&0xFFFF)<<16) | ((x&0xFFFF0000)>>16); - SIVAL(buf,offset,x); + uint32 x = make_dos_date (unixdate); + x = ((x & 0xFFFF) << 16) | ((x & 0xFFFF0000) >> 16); + SIVAL (buf, offset, x); } /******************************************************************* @@ -411,95 +441,105 @@ put a dos 32 bit "unix like" date into a buffer. This routine takes GMT and converts it to LOCAL time before putting it (most SMBs assume localtime for this sort of date) ********************************************************************/ -void put_dos_date3(char *buf,int offset,time_t unixdate) +void +put_dos_date3 (char *buf, int offset, time_t unixdate) { - if (!null_mtime(unixdate)) - unixdate -= TimeDiff(unixdate); - SIVAL(buf,offset,unixdate); + if (!null_mtime (unixdate)) + unixdate -= TimeDiff (unixdate); + SIVAL (buf, offset, unixdate); } /******************************************************************* interpret a 32 bit dos packed date/time to some parameters ********************************************************************/ -static void interpret_dos_date(uint32 date,int *year,int *month,int *day,int *hour,int *minute,int *second) +static void +interpret_dos_date (uint32 date, int *year, int *month, int *day, int *hour, int *minute, + int *second) { - uint32 p0,p1,p2,p3; - - p0=date&0xFF; p1=((date&0xFF00)>>8)&0xFF; - p2=((date&0xFF0000)>>16)&0xFF; p3=((date&0xFF000000)>>24)&0xFF; - - *second = 2*(p0 & 0x1F); - *minute = ((p0>>5)&0xFF) + ((p1&0x7)<<3); - *hour = (p1>>3)&0xFF; - *day = (p2&0x1F); - *month = ((p2>>5)&0xFF) + ((p3&0x1)<<3) - 1; - *year = ((p3>>1)&0xFF) + 80; + uint32 p0, p1, p2, p3; + + p0 = date & 0xFF; + p1 = ((date & 0xFF00) >> 8) & 0xFF; + p2 = ((date & 0xFF0000) >> 16) & 0xFF; + p3 = ((date & 0xFF000000) >> 24) & 0xFF; + + *second = 2 * (p0 & 0x1F); + *minute = ((p0 >> 5) & 0xFF) + ((p1 & 0x7) << 3); + *hour = (p1 >> 3) & 0xFF; + *day = (p2 & 0x1F); + *month = ((p2 >> 5) & 0xFF) + ((p3 & 0x1) << 3) - 1; + *year = ((p3 >> 1) & 0xFF) + 80; } /******************************************************************* create a unix date (int GMT) from a dos date (which is actually in localtime) ********************************************************************/ -time_t make_unix_date(void *date_ptr) +time_t +make_unix_date (void *date_ptr) { - uint32 dos_date=0; - struct tm t; - time_t ret; - - dos_date = IVAL(date_ptr,0); - - if (dos_date == 0) return(0); - - interpret_dos_date(dos_date,&t.tm_year,&t.tm_mon, - &t.tm_mday,&t.tm_hour,&t.tm_min,&t.tm_sec); - t.tm_isdst = -1; - - /* mktime() also does the local to GMT time conversion for us */ - ret = mktime(&t); - - return(ret); + uint32 dos_date = 0; + struct tm t; + time_t ret; + + dos_date = IVAL (date_ptr, 0); + + if (dos_date == 0) + return (0); + + interpret_dos_date (dos_date, &t.tm_year, &t.tm_mon, + &t.tm_mday, &t.tm_hour, &t.tm_min, &t.tm_sec); + t.tm_isdst = -1; + + /* mktime() also does the local to GMT time conversion for us */ + ret = mktime (&t); + + return (ret); } /******************************************************************* like make_unix_date() but the words are reversed ********************************************************************/ -time_t make_unix_date2(void *date_ptr) +time_t +make_unix_date2 (void *date_ptr) { - uint32 x,x2; + uint32 x, x2; - x = IVAL(date_ptr,0); - x2 = ((x&0xFFFF)<<16) | ((x&0xFFFF0000)>>16); - SIVAL(&x,0,x2); + x = IVAL (date_ptr, 0); + x2 = ((x & 0xFFFF) << 16) | ((x & 0xFFFF0000) >> 16); + SIVAL (&x, 0, x2); - return(make_unix_date((void *)&x)); + return (make_unix_date ((void *) &x)); } /******************************************************************* create a unix GMT date from a dos date in 32 bit "unix like" format these generally arrive as localtimes, with corresponding DST ******************************************************************/ -time_t make_unix_date3(void *date_ptr) +time_t +make_unix_date3 (void *date_ptr) { - time_t t = (time_t)IVAL(date_ptr,0); - if (!null_mtime(t)) - t += LocTimeDiff(t); - return(t); + time_t t = (time_t) IVAL (date_ptr, 0); + if (!null_mtime (t)) + t += LocTimeDiff (t); + return (t); } #if 0 /*************************************************************************** return a HTTP/1.0 time string ***************************************************************************/ -char *http_timestring(time_t t) +char * +http_timestring (time_t t) { - static fstring buf; - struct tm *tm = LocalTime(&t); - - if (!tm) - slprintf(buf,sizeof(buf)-1,"%ld seconds since the Epoch",(long)t); - else - strftime(buf, sizeof(buf)-1, "%a, %d %b %Y %H:%M:%S %Z", tm); - return buf; + static fstring buf; + struct tm *tm = LocalTime (&t); + + if (!tm) + slprintf (buf, sizeof (buf) - 1, "%ld seconds since the Epoch", (long) t); + else + strftime (buf, sizeof (buf) - 1, "%a, %d %b %Y %H:%M:%S %Z", tm); + return buf; } #endif /*0 */ @@ -507,18 +547,22 @@ char *http_timestring(time_t t) /**************************************************************************** return the date and time as a string ****************************************************************************/ -char *timestring(void ) +char * +timestring (void) { - static fstring TimeBuf; - time_t t = time(NULL); - struct tm *tm = LocalTime(&t); - - if (!tm) { - slprintf(TimeBuf,sizeof(TimeBuf)-1,"%ld seconds since the Epoch",(long)t); - } else { - strftime(TimeBuf,100,"%Y/%m/%d %H:%M:%S",tm); - } - return(TimeBuf); + static fstring TimeBuf; + time_t t = time (NULL); + struct tm *tm = LocalTime (&t); + + if (!tm) + { + slprintf (TimeBuf, sizeof (TimeBuf) - 1, "%ld seconds since the Epoch", (long) t); + } + else + { + strftime (TimeBuf, 100, "%Y/%m/%d %H:%M:%S", tm); + } + return (TimeBuf); } /**************************************************************************** @@ -526,23 +570,23 @@ char *timestring(void ) structure. ****************************************************************************/ -time_t get_create_time(SMB_STRUCT_STAT *st,BOOL fake_dirs) +time_t +get_create_time (SMB_STRUCT_STAT * st, BOOL fake_dirs) { - time_t ret, ret1; - - if(S_ISDIR(st->st_mode) && fake_dirs) - return (time_t)315493200L; /* 1/1/1980 */ - - ret = MIN(st->st_ctime, st->st_mtime); - ret1 = MIN(ret, st->st_atime); - - if(ret1 != (time_t)0) - return ret1; - - /* - * One of ctime, mtime or atime was zero (probably atime). - * Just return MIN(ctime, mtime). - */ - return ret; -} + time_t ret, ret1; + + if (S_ISDIR (st->st_mode) && fake_dirs) + return (time_t) 315493200L; /* 1/1/1980 */ + + ret = MIN (st->st_ctime, st->st_mtime); + ret1 = MIN (ret, st->st_atime); + if (ret1 != (time_t) 0) + return ret1; + + /* + * One of ctime, mtime or atime was zero (probably atime). + * Just return MIN(ctime, mtime). + */ + return ret; +} diff --git a/src/vfs/smbfs/helpers/lib/username.c b/src/vfs/smbfs/helpers/lib/username.c dissimilarity index 60% index 770eb540e..dcdcc9004 100644 --- a/src/vfs/smbfs/helpers/lib/username.c +++ b/src/vfs/smbfs/helpers/lib/username.c @@ -1,424 +1,450 @@ -/* - Unix SMB/Netbios implementation. - Version 1.9. - Username handling - - Copyright (C) Andrew Tridgell 1992-1998 - - Copyright (C) 2011 - The Free Software Foundation, Inc. - - This file is part of the Midnight Commander. - - The Midnight Commander is free software: you can redistribute it - and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of the License, - or (at your option) any later version. - - The Midnight Commander is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "includes.h" -extern int DEBUGLEVEL; - -/* internal functions */ -static struct passwd *uname_string_combinations(char *s, struct passwd * (*fn) (const char *), int N); -static struct passwd *uname_string_combinations2(char *s, int offset, struct passwd * (*fn) (const char *), int N); - -/**************************************************************************** -get a users home directory. -****************************************************************************/ -const char *get_home_dir(char *user) -{ - struct passwd *pass; - - pass = Get_Pwnam(user); - - if (!pass) return(NULL); - return(pass->pw_dir); -} - - -#if 0 /* Fix possible buffer overflow in sscanf(unixname,"%s",user) if uncomment */ -/******************************************************************* -map a username from a dos name to a unix name by looking in the username -map. Note that this modifies the name in place. -This is the main function that should be called *once* on -any incoming or new username - in order to canonicalize the name. -This is being done to de-couple the case conversions from the user mapping -function. Previously, the map_username was being called -every time Get_Pwnam was called. -Returns True if username was changed, false otherwise. -********************************************************************/ -BOOL map_username(const char *user) -{ - static BOOL initialised=False; - static fstring last_from,last_to; - FILE *f; - char *mapfile = lp_username_map(); - char *s; - pstring buf; - BOOL mapped_user = False; - - if (!*user) - return False; - - if (!*mapfile) - return False; - - if (!initialised) { - *last_from = *last_to = 0; - initialised = True; - } - - if (strequal(user,last_to)) - return False; - - if (strequal(user,last_from)) { - DEBUG(3,("Mapped user %s to %s\n",user,last_to)); - fstrcpy(user,last_to); - return True; - } - - f = sys_fopen(mapfile,"r"); - if (!f) { - DEBUG(0,("can't open username map %s\n",mapfile)); - return False; - } - - DEBUG(4,("Scanning username map %s\n",mapfile)); - - while((s=fgets_slash(buf,sizeof(buf),f))!=NULL) { - char *unixname = s; - char *dosname = strchr(unixname,'='); - BOOL return_if_mapped = False; - - if (!dosname) - continue; - - *dosname++ = 0; - - while (isspace(*unixname)) - unixname++; - if ('!' == *unixname) { - return_if_mapped = True; - unixname++; - while (*unixname && isspace(*unixname)) - unixname++; - } - - if (!*unixname || strchr("#;",*unixname)) - continue; - - { - int l = strlen(unixname); - while (l && isspace(unixname[l-1])) { - unixname[l-1] = 0; - l--; - } - } - - if (strchr(dosname,'*') || user_in_list(user,dosname)) { - DEBUG(3,("Mapped user %s to %s\n",user,unixname)); - mapped_user = True; - fstrcpy(last_from,user); - sscanf(unixname,"%s",user); - fstrcpy(last_to,user); - if(return_if_mapped) { - fclose(f); - return True; - } - } - } - - fclose(f); - - /* - * Setup the last_from and last_to as an optimization so - * that we don't scan the file again for the same user. - */ - fstrcpy(last_from,user); - fstrcpy(last_to,user); - - return mapped_user; -} -#endif /* 0 */ - -/**************************************************************************** -Get_Pwnam wrapper -****************************************************************************/ -static struct passwd *_Get_Pwnam(const char *s) -{ - struct passwd *ret; - - ret = getpwnam(s); - if (ret) - { -#ifdef HAVE_GETPWANAM - struct passwd_adjunct *pwret; - pwret = getpwanam(s); - if (pwret) - { - free(ret->pw_passwd); - ret->pw_passwd = pwret->pwa_passwd; - } -#endif - - } - - return(ret); -} - - -/**************************************************************************** -a wrapper for getpwnam() that tries with all lower and all upper case -if the initial name fails. Also tried with first letter capitalised -****************************************************************************/ -struct passwd *Get_Pwnam(const char *a_user) -{ - fstring user; - int last_char; - int usernamelevel = lp_usernamelevel(); - - struct passwd *ret; - - if (!a_user || !(*a_user)) - return(NULL); - - StrnCpy(user,a_user,sizeof(user)-1); - - ret = _Get_Pwnam(user); - if (ret) return(ret); - - strlower(user); - ret = _Get_Pwnam(user); - if (ret) return(ret); - - strupper(user); - ret = _Get_Pwnam(user); - if (ret) return(ret); - - /* try with first letter capitalised */ - if (strlen(user) > 1) - strlower(user+1); - ret = _Get_Pwnam(user); - if (ret) return(ret); - - /* try with last letter capitalised */ - strlower(user); - last_char = strlen(user)-1; - user[last_char] = toupper(user[last_char]); - ret = _Get_Pwnam(user); - if (ret) return(ret); - - /* try all combinations up to usernamelevel */ - strlower(user); - ret = uname_string_combinations(user, _Get_Pwnam, usernamelevel); - if (ret) return(ret); - - return(NULL); -} - -#if 0 -/**************************************************************************** -check if a user is in a netgroup user list -****************************************************************************/ -static BOOL user_in_netgroup_list(char *user,char *ngname) -{ -#ifdef HAVE_NETGROUP - static char *mydomain = NULL; - if (mydomain == NULL) - yp_get_default_domain(&mydomain); - - if(mydomain == NULL) - { - DEBUG(5,("Unable to get default yp domain\n")); - } - else - { - DEBUG(5,("looking for user %s of domain %s in netgroup %s\n", - user, mydomain, ngname)); - DEBUG(5,("innetgr is %s\n", - innetgr(ngname, NULL, user, mydomain) - ? "TRUE" : "FALSE")); - - if (innetgr(ngname, NULL, user, mydomain)) - return (True); - } -#endif /* HAVE_NETGROUP */ - return False; -} - -/**************************************************************************** -check if a user is in a UNIX user list -****************************************************************************/ -static BOOL user_in_group_list(char *user,char *gname) -{ -#ifdef HAVE_GETGRNAM - struct group *gptr; - char **member; - struct passwd *pass = Get_Pwnam(user,False); - - if (pass) - { - gptr = getgrgid(pass->pw_gid); - if (gptr && strequal(gptr->gr_name,gname)) - return(True); - } - - gptr = (struct group *)getgrnam(gname); - - if (gptr) - { - member = gptr->gr_mem; - while (member && *member) - { - if (strequal(*member,user)) - return(True); - member++; - } - } -#endif /* HAVE_GETGRNAM */ - return False; -} - -/**************************************************************************** -check if a user is in a user list - can check combinations of UNIX -and netgroup lists. -****************************************************************************/ -BOOL user_in_list(char *user,char *list) -{ - pstring tok; - char *p=list; - - while (next_token(&p,tok,LIST_SEP, sizeof(tok))) - { - /* - * Check raw username. - */ - if (strequal(user,tok)) - return(True); - - /* - * Now check to see if any combination - * of UNIX and netgroups has been specified. - */ - - if(*tok == '@') - { - /* - * Old behaviour. Check netgroup list - * followed by UNIX list. - */ - if(user_in_netgroup_list(user,&tok[1])) - return True; - if(user_in_group_list(user,&tok[1])) - return True; - } - else if (*tok == '+') - { - if(tok[1] == '&') - { - /* - * Search UNIX list followed by netgroup. - */ - if(user_in_group_list(user,&tok[2])) - return True; - if(user_in_netgroup_list(user,&tok[2])) - return True; - } - else - { - /* - * Just search UNIX list. - */ - if(user_in_group_list(user,&tok[1])) - return True; - } - } - else if (*tok == '&') - { - if(tok[1] == '&') - { - /* - * Search netgroup list followed by UNIX list. - */ - if(user_in_netgroup_list(user,&tok[2])) - return True; - if(user_in_group_list(user,&tok[2])) - return True; - } - else - { - /* - * Just search netgroup list. - */ - if(user_in_netgroup_list(user,&tok[1])) - return True; - } - } - } - return(False); -} -#endif /* 0 */ - -/* The functions below have been taken from password.c and slightly modified */ -/**************************************************************************** -apply a function to upper/lower case combinations -of a string and return true if one of them returns true. -try all combinations with N uppercase letters. -offset is the first char to try and change (start with 0) -it assumes the string starts lowercased -****************************************************************************/ -static struct passwd *uname_string_combinations2(char *s,int offset,struct passwd *(*fn)(const char *),int N) -{ - int len = strlen(s); - int i; - struct passwd *ret; - -#ifdef PASSWORD_LENGTH - len = MIN(len,PASSWORD_LENGTH); -#endif - - if (N <= 0 || offset >= len) - return(fn(s)); - - - for (i=offset;i<(len-(N-1));i++) - - { - char c = s[i]; - if (!islower(c)) continue; - s[i] = toupper(c); - ret = uname_string_combinations2(s,i+1,fn,N-1); - if(ret) return(ret); - s[i] = c; - } - return(NULL); -} - -/**************************************************************************** -apply a function to upper/lower case combinations -of a string and return true if one of them returns true. -try all combinations with up to N uppercase letters. -offset is the first char to try and change (start with 0) -it assumes the string starts lowercased -****************************************************************************/ -static struct passwd * uname_string_combinations(char *s,struct passwd * (*fn)(const char *),int N) -{ - int n; - struct passwd *ret; - - for (n=1;n<=N;n++) - { - ret = uname_string_combinations2(s,0,fn,n); - if(ret) return(ret); - } - return(NULL); -} +/* + Unix SMB/Netbios implementation. + Version 1.9. + Username handling + + Copyright (C) Andrew Tridgell 1992-1998 + + Copyright (C) 2011 + The Free Software Foundation, Inc. + + This file is part of the Midnight Commander. + + The Midnight Commander is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + The Midnight Commander is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + */ + +#include "includes.h" +extern int DEBUGLEVEL; + +/* internal functions */ +static struct passwd *uname_string_combinations (char *s, struct passwd *(*fn) (const char *), + int N); +static struct passwd *uname_string_combinations2 (char *s, int offset, + struct passwd *(*fn) (const char *), int N); + +/**************************************************************************** +get a users home directory. +****************************************************************************/ +const char * +get_home_dir (char *user) +{ + struct passwd *pass; + + pass = Get_Pwnam (user); + + if (!pass) + return (NULL); + return (pass->pw_dir); +} + + +#if 0 /* Fix possible buffer overflow in sscanf(unixname,"%s",user) if uncomment */ +/******************************************************************* +map a username from a dos name to a unix name by looking in the username +map. Note that this modifies the name in place. +This is the main function that should be called *once* on +any incoming or new username - in order to canonicalize the name. +This is being done to de-couple the case conversions from the user mapping +function. Previously, the map_username was being called +every time Get_Pwnam was called. +Returns True if username was changed, false otherwise. +********************************************************************/ +BOOL +map_username (const char *user) +{ + static BOOL initialised = False; + static fstring last_from, last_to; + FILE *f; + char *mapfile = lp_username_map (); + char *s; + pstring buf; + BOOL mapped_user = False; + + if (!*user) + return False; + + if (!*mapfile) + return False; + + if (!initialised) + { + *last_from = *last_to = 0; + initialised = True; + } + + if (strequal (user, last_to)) + return False; + + if (strequal (user, last_from)) + { + DEBUG (3, ("Mapped user %s to %s\n", user, last_to)); + fstrcpy (user, last_to); + return True; + } + + f = sys_fopen (mapfile, "r"); + if (!f) + { + DEBUG (0, ("can't open username map %s\n", mapfile)); + return False; + } + + DEBUG (4, ("Scanning username map %s\n", mapfile)); + + while ((s = fgets_slash (buf, sizeof (buf), f)) != NULL) + { + char *unixname = s; + char *dosname = strchr (unixname, '='); + BOOL return_if_mapped = False; + + if (!dosname) + continue; + + *dosname++ = 0; + + while (isspace (*unixname)) + unixname++; + if ('!' == *unixname) + { + return_if_mapped = True; + unixname++; + while (*unixname && isspace (*unixname)) + unixname++; + } + + if (!*unixname || strchr ("#;", *unixname)) + continue; + + { + int l = strlen (unixname); + while (l && isspace (unixname[l - 1])) + { + unixname[l - 1] = 0; + l--; + } + } + + if (strchr (dosname, '*') || user_in_list (user, dosname)) + { + DEBUG (3, ("Mapped user %s to %s\n", user, unixname)); + mapped_user = True; + fstrcpy (last_from, user); + sscanf (unixname, "%s", user); + fstrcpy (last_to, user); + if (return_if_mapped) + { + fclose (f); + return True; + } + } + } + + fclose (f); + + /* + * Setup the last_from and last_to as an optimization so + * that we don't scan the file again for the same user. + */ + fstrcpy (last_from, user); + fstrcpy (last_to, user); + + return mapped_user; +} +#endif /* 0 */ + +/**************************************************************************** +Get_Pwnam wrapper +****************************************************************************/ +static struct passwd * +_Get_Pwnam (const char *s) +{ + struct passwd *ret; + + ret = getpwnam (s); + if (ret) + { +#ifdef HAVE_GETPWANAM + struct passwd_adjunct *pwret; + pwret = getpwanam (s); + if (pwret) + { + free (ret->pw_passwd); + ret->pw_passwd = pwret->pwa_passwd; + } +#endif + + } + + return (ret); +} + + +/**************************************************************************** +a wrapper for getpwnam() that tries with all lower and all upper case +if the initial name fails. Also tried with first letter capitalised +****************************************************************************/ +struct passwd * +Get_Pwnam (const char *a_user) +{ + fstring user; + int last_char; + int usernamelevel = lp_usernamelevel (); + + struct passwd *ret; + + if (!a_user || !(*a_user)) + return (NULL); + + StrnCpy (user, a_user, sizeof (user) - 1); + + ret = _Get_Pwnam (user); + if (ret) + return (ret); + + strlower (user); + ret = _Get_Pwnam (user); + if (ret) + return (ret); + + strupper (user); + ret = _Get_Pwnam (user); + if (ret) + return (ret); + + /* try with first letter capitalised */ + if (strlen (user) > 1) + strlower (user + 1); + ret = _Get_Pwnam (user); + if (ret) + return (ret); + + /* try with last letter capitalised */ + strlower (user); + last_char = strlen (user) - 1; + user[last_char] = toupper (user[last_char]); + ret = _Get_Pwnam (user); + if (ret) + return (ret); + + /* try all combinations up to usernamelevel */ + strlower (user); + ret = uname_string_combinations (user, _Get_Pwnam, usernamelevel); + if (ret) + return (ret); + + return (NULL); +} + +#if 0 +/**************************************************************************** +check if a user is in a netgroup user list +****************************************************************************/ +static BOOL +user_in_netgroup_list (char *user, char *ngname) +{ +#ifdef HAVE_NETGROUP + static char *mydomain = NULL; + if (mydomain == NULL) + yp_get_default_domain (&mydomain); + + if (mydomain == NULL) + { + DEBUG (5, ("Unable to get default yp domain\n")); + } + else + { + DEBUG (5, ("looking for user %s of domain %s in netgroup %s\n", user, mydomain, ngname)); + DEBUG (5, ("innetgr is %s\n", innetgr (ngname, NULL, user, mydomain) ? "TRUE" : "FALSE")); + + if (innetgr (ngname, NULL, user, mydomain)) + return (True); + } +#endif /* HAVE_NETGROUP */ + return False; +} + +/**************************************************************************** +check if a user is in a UNIX user list +****************************************************************************/ +static BOOL +user_in_group_list (char *user, char *gname) +{ +#ifdef HAVE_GETGRNAM + struct group *gptr; + char **member; + struct passwd *pass = Get_Pwnam (user, False); + + if (pass) + { + gptr = getgrgid (pass->pw_gid); + if (gptr && strequal (gptr->gr_name, gname)) + return (True); + } + + gptr = (struct group *) getgrnam (gname); + + if (gptr) + { + member = gptr->gr_mem; + while (member && *member) + { + if (strequal (*member, user)) + return (True); + member++; + } + } +#endif /* HAVE_GETGRNAM */ + return False; +} + +/**************************************************************************** +check if a user is in a user list - can check combinations of UNIX +and netgroup lists. +****************************************************************************/ +BOOL +user_in_list (char *user, char *list) +{ + pstring tok; + char *p = list; + + while (next_token (&p, tok, LIST_SEP, sizeof (tok))) + { + /* + * Check raw username. + */ + if (strequal (user, tok)) + return (True); + + /* + * Now check to see if any combination + * of UNIX and netgroups has been specified. + */ + + if (*tok == '@') + { + /* + * Old behaviour. Check netgroup list + * followed by UNIX list. + */ + if (user_in_netgroup_list (user, &tok[1])) + return True; + if (user_in_group_list (user, &tok[1])) + return True; + } + else if (*tok == '+') + { + if (tok[1] == '&') + { + /* + * Search UNIX list followed by netgroup. + */ + if (user_in_group_list (user, &tok[2])) + return True; + if (user_in_netgroup_list (user, &tok[2])) + return True; + } + else + { + /* + * Just search UNIX list. + */ + if (user_in_group_list (user, &tok[1])) + return True; + } + } + else if (*tok == '&') + { + if (tok[1] == '&') + { + /* + * Search netgroup list followed by UNIX list. + */ + if (user_in_netgroup_list (user, &tok[2])) + return True; + if (user_in_group_list (user, &tok[2])) + return True; + } + else + { + /* + * Just search netgroup list. + */ + if (user_in_netgroup_list (user, &tok[1])) + return True; + } + } + } + return (False); +} +#endif /* 0 */ + +/* The functions below have been taken from password.c and slightly modified */ +/**************************************************************************** +apply a function to upper/lower case combinations +of a string and return true if one of them returns true. +try all combinations with N uppercase letters. +offset is the first char to try and change (start with 0) +it assumes the string starts lowercased +****************************************************************************/ +static struct passwd * +uname_string_combinations2 (char *s, int offset, struct passwd *(*fn) (const char *), int N) +{ + int len = strlen (s); + int i; + struct passwd *ret; + +#ifdef PASSWORD_LENGTH + len = MIN (len, PASSWORD_LENGTH); +#endif + + if (N <= 0 || offset >= len) + return (fn (s)); + + + for (i = offset; i < (len - (N - 1)); i++) + + { + char c = s[i]; + if (!islower (c)) + continue; + s[i] = toupper (c); + ret = uname_string_combinations2 (s, i + 1, fn, N - 1); + if (ret) + return (ret); + s[i] = c; + } + return (NULL); +} + +/**************************************************************************** +apply a function to upper/lower case combinations +of a string and return true if one of them returns true. +try all combinations with up to N uppercase letters. +offset is the first char to try and change (start with 0) +it assumes the string starts lowercased +****************************************************************************/ +static struct passwd * +uname_string_combinations (char *s, struct passwd *(*fn) (const char *), int N) +{ + int n; + struct passwd *ret; + + for (n = 1; n <= N; n++) + { + ret = uname_string_combinations2 (s, 0, fn, n); + if (ret) + return (ret); + } + return (NULL); +} diff --git a/src/vfs/smbfs/helpers/lib/util_file.c b/src/vfs/smbfs/helpers/lib/util_file.c index ab8693996..9155ac78c 100644 --- a/src/vfs/smbfs/helpers/lib/util_file.c +++ b/src/vfs/smbfs/helpers/lib/util_file.c @@ -33,9 +33,10 @@ static int gotalarm; Signal function to tell us we timed out. ****************************************************************/ -static void gotalarm_sig(void) +static void +gotalarm_sig (void) { - gotalarm = 1; + gotalarm = 1; } /*************************************************************** @@ -43,74 +44,78 @@ static void gotalarm_sig(void) seconds. ****************************************************************/ -BOOL do_file_lock(int fd, int waitsecs, int type) +BOOL +do_file_lock (int fd, int waitsecs, int type) { - SMB_STRUCT_FLOCK lock; - int ret; - - gotalarm = 0; - CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig); - - lock.l_type = type; - lock.l_whence = SEEK_SET; - lock.l_start = 0; - lock.l_len = 1; - lock.l_pid = 0; - - alarm(waitsecs); - ret = fcntl(fd, SMB_F_SETLKW, &lock); - alarm(0); - CatchSignal(SIGALRM, SIGNAL_CAST SIG_DFL); - - if (gotalarm) { - DEBUG(0, ("do_file_lock: failed to %s file.\n", - type == F_UNLCK ? "unlock" : "lock")); - return False; - } - - return (ret == 0); + SMB_STRUCT_FLOCK lock; + int ret; + + gotalarm = 0; + CatchSignal (SIGALRM, SIGNAL_CAST gotalarm_sig); + + lock.l_type = type; + lock.l_whence = SEEK_SET; + lock.l_start = 0; + lock.l_len = 1; + lock.l_pid = 0; + + alarm (waitsecs); + ret = fcntl (fd, SMB_F_SETLKW, &lock); + alarm (0); + CatchSignal (SIGALRM, SIGNAL_CAST SIG_DFL); + + if (gotalarm) + { + DEBUG (0, ("do_file_lock: failed to %s file.\n", type == F_UNLCK ? "unlock" : "lock")); + return False; + } + + return (ret == 0); } /*************************************************************** Lock an fd. Abandon after waitsecs seconds. ****************************************************************/ -BOOL file_lock(int fd, int type, int secs, int *plock_depth) +BOOL +file_lock (int fd, int type, int secs, int *plock_depth) { - if (fd < 0) - return False; + if (fd < 0) + return False; - (*plock_depth)++; + (*plock_depth)++; - if ((*plock_depth) == 0) - { - if (!do_file_lock(fd, secs, type)) { - DEBUG(10,("file_lock: locking file failed, error = %s.\n", - unix_error_string (errno))); - return False; + if ((*plock_depth) == 0) + { + if (!do_file_lock (fd, secs, type)) + { + DEBUG (10, ("file_lock: locking file failed, error = %s.\n", + unix_error_string (errno))); + return False; + } } - } - return True; + return True; } /*************************************************************** Unlock an fd. Abandon after waitsecs seconds. ****************************************************************/ -BOOL file_unlock(int fd, int *plock_depth) +BOOL +file_unlock (int fd, int *plock_depth) { - BOOL ret=True; + BOOL ret = True; - if(*plock_depth == 1) - ret = do_file_lock(fd, 5, F_UNLCK); + if (*plock_depth == 1) + ret = do_file_lock (fd, 5, F_UNLCK); - (*plock_depth)--; + (*plock_depth)--; - if(!ret) - DEBUG(10,("file_unlock: unlocking file failed, error = %s.\n", - unix_error_string (errno))); - return ret; + if (!ret) + DEBUG (10, ("file_unlock: unlocking file failed, error = %s.\n", + unix_error_string (errno))); + return ret; } /*************************************************************** @@ -118,52 +123,54 @@ BOOL file_unlock(int fd, int *plock_depth) update to be set = True if modification is required. ****************************************************************/ -void *startfilepwent(char *pfile, char *s_readbuf, int bufsize, - int *file_lock_depth, BOOL update) +void * +startfilepwent (char *pfile, char *s_readbuf, int bufsize, int *file_lock_depth, BOOL update) { - FILE *fp = NULL; + FILE *fp = NULL; - if (!*pfile) - { - DEBUG(0, ("startfilepwent: No file set\n")); - return (NULL); - } - DEBUG(10, ("startfilepwent: opening file %s\n", pfile)); + if (!*pfile) + { + DEBUG (0, ("startfilepwent: No file set\n")); + return (NULL); + } + DEBUG (10, ("startfilepwent: opening file %s\n", pfile)); - fp = sys_fopen(pfile, update ? "r+b" : "rb"); + fp = sys_fopen (pfile, update ? "r+b" : "rb"); - if (fp == NULL) { - DEBUG(0, ("startfilepwent: unable to open file %s\n", pfile)); - return NULL; - } + if (fp == NULL) + { + DEBUG (0, ("startfilepwent: unable to open file %s\n", pfile)); + return NULL; + } - /* Set a buffer to do more efficient reads */ - setvbuf(fp, s_readbuf, _IOFBF, bufsize); + /* Set a buffer to do more efficient reads */ + setvbuf (fp, s_readbuf, _IOFBF, bufsize); - if (!file_lock(fileno(fp), (update ? F_WRLCK : F_RDLCK), 5, file_lock_depth)) - { - DEBUG(0, ("startfilepwent: unable to lock file %s\n", pfile)); - fclose(fp); - return NULL; - } + if (!file_lock (fileno (fp), (update ? F_WRLCK : F_RDLCK), 5, file_lock_depth)) + { + DEBUG (0, ("startfilepwent: unable to lock file %s\n", pfile)); + fclose (fp); + return NULL; + } - /* Make sure it is only rw by the owner */ - chmod(pfile, 0600); + /* Make sure it is only rw by the owner */ + chmod (pfile, 0600); - /* We have a lock on the file. */ - return (void *)fp; + /* We have a lock on the file. */ + return (void *) fp; } /*************************************************************** End enumeration of the file. ****************************************************************/ -void endfilepwent(void *vp, int *file_lock_depth) +void +endfilepwent (void *vp, int *file_lock_depth) { - FILE *fp = (FILE *)vp; + FILE *fp = (FILE *) vp; - file_unlock(fileno(fp), file_lock_depth); - fclose(fp); - DEBUG(7, ("endfilepwent: closed file.\n")); + file_unlock (fileno (fp), file_lock_depth); + fclose (fp); + DEBUG (7, ("endfilepwent: closed file.\n")); } @@ -171,18 +178,20 @@ void endfilepwent(void *vp, int *file_lock_depth) Return the current position in the file list as an SMB_BIG_UINT. This must be treated as an opaque token. *************************************************************************/ -SMB_BIG_UINT getfilepwpos(void *vp) +SMB_BIG_UINT +getfilepwpos (void *vp) { - return (SMB_BIG_UINT)sys_ftell((FILE *)vp); + return (SMB_BIG_UINT) sys_ftell ((FILE *) vp); } /************************************************************************* Set the current position in the file list from an SMB_BIG_UINT. This must be treated as an opaque token. *************************************************************************/ -BOOL setfilepwpos(void *vp, SMB_BIG_UINT tok) +BOOL +setfilepwpos (void *vp, SMB_BIG_UINT tok) { - return !sys_fseek((FILE *)vp, (SMB_OFF_T)tok, SEEK_SET); + return !sys_fseek ((FILE *) vp, (SMB_OFF_T) tok, SEEK_SET); } /************************************************************************* @@ -190,146 +199,149 @@ BOOL setfilepwpos(void *vp, SMB_BIG_UINT tok) line is of format "xxxx:xxxxxx:xxxxx:". lines with "#" at the front are ignored. *************************************************************************/ -int getfileline(void *vp, char *linebuf, int linebuf_size) +int +getfileline (void *vp, char *linebuf, int linebuf_size) { - /* Static buffers we will return. */ - FILE *fp = (FILE *)vp; - unsigned char c; - unsigned char *p; - size_t linebuf_len; - - if (fp == NULL) - { - DEBUG(0,("getfileline: Bad file pointer.\n")); - return -1; - } - - /* - * Scan the file, a line at a time. - */ - while (!feof(fp)) - { - linebuf[0] = '\0'; - - fgets(linebuf, linebuf_size, fp); - if (ferror(fp)) - { - return -1; - } - - /* - * Check if the string is terminated with a newline - if not - * then we must keep reading and discard until we get one. - */ - - linebuf_len = strlen(linebuf); - if (linebuf[linebuf_len - 1] != '\n') - { - c = '\0'; - while (!ferror(fp) && !feof(fp)) - { - c = fgetc(fp); - if (c == '\n') - { - break; - } - } - } - else - { - linebuf[linebuf_len - 1] = '\0'; - } + /* Static buffers we will return. */ + FILE *fp = (FILE *) vp; + unsigned char c; + unsigned char *p; + size_t linebuf_len; + + if (fp == NULL) + { + DEBUG (0, ("getfileline: Bad file pointer.\n")); + return -1; + } + + /* + * Scan the file, a line at a time. + */ + while (!feof (fp)) + { + linebuf[0] = '\0'; + + fgets (linebuf, linebuf_size, fp); + if (ferror (fp)) + { + return -1; + } + + /* + * Check if the string is terminated with a newline - if not + * then we must keep reading and discard until we get one. + */ + + linebuf_len = strlen (linebuf); + if (linebuf[linebuf_len - 1] != '\n') + { + c = '\0'; + while (!ferror (fp) && !feof (fp)) + { + c = fgetc (fp); + if (c == '\n') + { + break; + } + } + } + else + { + linebuf[linebuf_len - 1] = '\0'; + } #ifdef DEBUG_PASSWORD - DEBUG(100, ("getfileline: got line |%s|\n", linebuf)); + DEBUG (100, ("getfileline: got line |%s|\n", linebuf)); #endif - if ((linebuf[0] == 0) && feof(fp)) - { - DEBUG(4, ("getfileline: end of file reached\n")); - return 0; - } - - if (linebuf[0] == '#' || linebuf[0] == '\0') - { - DEBUG(6, ("getfileline: skipping comment or blank line\n")); - continue; - } - - p = (unsigned char *) strchr(linebuf, ':'); - if (p == NULL) - { - DEBUG(0, ("getfileline: malformed line entry (no :)\n")); - continue; - } - return linebuf_len; - } - return -1; + if ((linebuf[0] == 0) && feof (fp)) + { + DEBUG (4, ("getfileline: end of file reached\n")); + return 0; + } + + if (linebuf[0] == '#' || linebuf[0] == '\0') + { + DEBUG (6, ("getfileline: skipping comment or blank line\n")); + continue; + } + + p = (unsigned char *) strchr (linebuf, ':'); + if (p == NULL) + { + DEBUG (0, ("getfileline: malformed line entry (no :)\n")); + continue; + } + return linebuf_len; + } + return -1; } -#endif /* 0 */ +#endif /* 0 */ /**************************************************************************** read a line from a file with possible \ continuation chars. Blanks at the start or end of a line are stripped. The string will be allocated if s2 is NULL ****************************************************************************/ -char *fgets_slash(char *s2,int maxlen,FILE *f) +char * +fgets_slash (char *s2, int maxlen, FILE * f) { - char *s=s2; - int len = 0; - int c; - BOOL start_of_line = True; + char *s = s2; + int len = 0; + int c; + BOOL start_of_line = True; - if (feof(f)) - return(NULL); + if (feof (f)) + return (NULL); - if (!s2) + if (!s2) { - maxlen = MIN(maxlen,8); - s = (char *)Realloc(s,maxlen); + maxlen = MIN (maxlen, 8); + s = (char *) Realloc (s, maxlen); } - if (!s || maxlen < 2) return(NULL); + if (!s || maxlen < 2) + return (NULL); - *s = 0; + *s = 0; - while (len < maxlen-1) + while (len < maxlen - 1) { - c = getc(f); - switch (c) - { - case '\r': - break; - case '\n': - while (len > 0 && s[len-1] == ' ') - { - s[--len] = 0; - } - if (len > 0 && s[len-1] == '\\') - { - s[--len] = 0; - start_of_line = True; - break; - } - return(s); - case EOF: - if (len <= 0 && !s2) - free(s); - return(len>0?s:NULL); - case ' ': - if (start_of_line) - break; - default: - start_of_line = False; - s[len++] = c; - s[len] = 0; - } - if (!s2 && len > maxlen-3) - { - maxlen *= 2; - s = (char *)Realloc(s,maxlen); - if (!s) return(NULL); - } + c = getc (f); + switch (c) + { + case '\r': + break; + case '\n': + while (len > 0 && s[len - 1] == ' ') + { + s[--len] = 0; + } + if (len > 0 && s[len - 1] == '\\') + { + s[--len] = 0; + start_of_line = True; + break; + } + return (s); + case EOF: + if (len <= 0 && !s2) + free (s); + return (len > 0 ? s : NULL); + case ' ': + if (start_of_line) + break; + default: + start_of_line = False; + s[len++] = c; + s[len] = 0; + } + if (!s2 && len > maxlen - 3) + { + maxlen *= 2; + s = (char *) Realloc (s, maxlen); + if (!s) + return (NULL); + } } - return(s); + return (s); } - diff --git a/src/vfs/smbfs/helpers/lib/util_sock.c b/src/vfs/smbfs/helpers/lib/util_sock.c dissimilarity index 67% index c4b7e7a85..0c259864f 100644 --- a/src/vfs/smbfs/helpers/lib/util_sock.c +++ b/src/vfs/smbfs/helpers/lib/util_sock.c @@ -1,889 +1,982 @@ -/* - Unix SMB/Netbios implementation. - Version 1.9. - Samba utility functions - - Copyright (C) Andrew Tridgell 1992-1998 - - Copyright (C) 2011 - The Free Software Foundation, Inc. - - This file is part of the Midnight Commander. - - The Midnight Commander is free software: you can redistribute it - and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of the License, - or (at your option) any later version. - - The Midnight Commander is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "includes.h" - -const char *unix_error_string (int error_num); - -#ifdef WITH_SSL -#include -#undef Realloc /* SSLeay defines this and samba has a function of this name */ -extern SSL *ssl; -extern int sslFd; -#endif /* WITH_SSL */ - -extern int DEBUGLEVEL; - -BOOL passive = False; - -/* the client file descriptor */ -int Client = -1; - -/* the last IP received from */ -struct in_addr lastip; - -/* the last port received from */ -int lastport=0; - - -int smb_read_error = 0; - - -/**************************************************************************** -determine if a file descriptor is in fact a socket -****************************************************************************/ -BOOL is_a_socket(int fd) -{ - int v; - unsigned int l; - l = sizeof(int); - return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0); -} - - -enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON}; - -static const struct -{ - const char *name; - int level; - int option; - int value; - int opttype; -} socket_options[] = { - {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL}, - {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL}, - {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL}, -#ifdef TCP_NODELAY - {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL}, -#endif -#ifdef IPTOS_LOWDELAY - {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON}, -#endif -#ifdef IPTOS_THROUGHPUT - {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON}, -#endif -#ifdef SO_SNDBUF - {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT}, -#endif -#ifdef SO_RCVBUF - {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT}, -#endif -#ifdef SO_SNDLOWAT - {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT}, -#endif -#ifdef SO_RCVLOWAT - {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT}, -#endif -#ifdef SO_SNDTIMEO - {"SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, 0, OPT_INT}, -#endif -#ifdef SO_RCVTIMEO - {"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, 0, OPT_INT}, -#endif - {NULL,0,0,0,0}}; - - - -/**************************************************************************** -set user socket options -****************************************************************************/ -void set_socket_options(int fd, char *options) -{ - fstring tok; - - while (next_token(&options,tok," \t,", sizeof(tok))) - { - int ret=0,i; - int value = 1; - char *p; - BOOL got_value = False; - - if ((p = strchr(tok,'='))) - { - *p = 0; - value = atoi(p+1); - got_value = True; - } - - for (i=0;socket_options[i].name;i++) - if (strequal(socket_options[i].name,tok)) - break; - - if (!socket_options[i].name) - { - DEBUG(0,("Unknown socket option %s\n",tok)); - continue; - } - - switch (socket_options[i].opttype) - { - case OPT_BOOL: - case OPT_INT: - ret = setsockopt(fd,socket_options[i].level, - socket_options[i].option,(char *)&value,sizeof(int)); - break; - - case OPT_ON: - if (got_value) - DEBUG(0,("syntax error - %s does not take a value\n",tok)); - - { - int on = socket_options[i].value; - ret = setsockopt(fd,socket_options[i].level, - socket_options[i].option,(char *)&on,sizeof(int)); - } - break; - } - - if (ret != 0) - DEBUG(0,("Failed to set socket option %s\n",tok)); - } -} - - - -/**************************************************************************** - close the socket communication -****************************************************************************/ -void close_sockets(void ) -{ -#ifdef WITH_SSL - sslutil_disconnect(Client); -#endif /* WITH_SSL */ - - close(Client); - Client = -1; -} - - - -/**************************************************************************** -write to a socket -****************************************************************************/ -ssize_t write_socket(int fd,char *buf,size_t len) -{ - ssize_t ret=0; - - if (passive) - return(len); - DEBUG(6,("write_socket(%d,%d)\n",fd,(int)len)); - ret = write_data(fd,buf,len); - - DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,(int)len,(int)ret)); - if(ret <= 0) - DEBUG(1,("write_socket: Error writing %d bytes to socket %d: ERRNO = %s\n", - (int)len, fd, unix_error_string (errno) )); - - return(ret); -} - -/**************************************************************************** -read from a socket -****************************************************************************/ -ssize_t read_udp_socket(int fd,char *buf,size_t len) -{ - ssize_t ret; - struct sockaddr_in sock; - unsigned int socklen; - - socklen = sizeof(sock); - memset((char *)&sock,'\0',socklen); - memset((char *)&lastip,'\0',sizeof(lastip)); - ret = (ssize_t)recvfrom(fd,buf,len,0,(struct sockaddr *)&sock,&socklen); - if (ret <= 0) { - DEBUG(2,("read socket failed. ERRNO=%s\n", unix_error_string (errno))); - return(0); - } - - lastip = sock.sin_addr; - lastport = ntohs(sock.sin_port); - - DEBUG(10,("read_udp_socket: lastip %s lastport %d read: %d\n", - inet_ntoa(lastip), lastport, (int)ret)); - - return(ret); -} - - -/**************************************************************************** -read data from a device with a timout in msec. -mincount = if timeout, minimum to read before returning -maxcount = number to be read. -time_out = timeout in milliseconds -****************************************************************************/ - -ssize_t read_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned int time_out) -{ - fd_set fds; - int selrtn; - ssize_t readret; - size_t nread = 0; - struct timeval timeout; - - /* just checking .... */ - if (maxcnt <= 0) return(0); - - smb_read_error = 0; - - /* Blocking read */ - if (time_out <= 0) { - if (mincnt == 0) mincnt = maxcnt; - - while (nread < mincnt) { -#ifdef WITH_SSL - if(fd == sslFd){ - readret = SSL_read(ssl, buf + nread, maxcnt - nread); - }else{ - readret = read(fd, buf + nread, maxcnt - nread); - } -#else /* WITH_SSL */ - readret = read(fd, buf + nread, maxcnt - nread); -#endif /* WITH_SSL */ - - if (readret == 0) { - DEBUG(5,("read_with_timeout: blocking read. EOF from client.\n")); - smb_read_error = READ_EOF; - return -1; - } - - if (readret == -1) { - DEBUG(0,("read_with_timeout: read error = %s.\n", unix_error_string (errno) )); - smb_read_error = READ_ERROR; - return -1; - } - nread += readret; - } - return((ssize_t)nread); - } - - /* Most difficult - timeout read */ - /* If this is ever called on a disk file and - mincnt is greater then the filesize then - system performance will suffer severely as - select always returns true on disk files */ - - /* Set initial timeout */ - timeout.tv_sec = (time_t)(time_out / 1000); - timeout.tv_usec = (long)(1000 * (time_out % 1000)); - - for (nread=0; nread < mincnt; ) - { - FD_ZERO(&fds); - FD_SET(fd,&fds); - - selrtn = sys_select(fd+1,&fds,&timeout); - - /* Check if error */ - if(selrtn == -1) { - /* something is wrong. Maybe the socket is dead? */ - DEBUG(0,("read_with_timeout: timeout read. select error = %s.\n", unix_error_string (errno) )); - smb_read_error = READ_ERROR; - return -1; - } - - /* Did we timeout ? */ - if (selrtn == 0) { - DEBUG(10,("read_with_timeout: timeout read. select timed out.\n")); - smb_read_error = READ_TIMEOUT; - return -1; - } - -#ifdef WITH_SSL - if(fd == sslFd){ - readret = SSL_read(ssl, buf + nread, maxcnt - nread); - }else{ - readret = read(fd, buf + nread, maxcnt - nread); - } -#else /* WITH_SSL */ - readret = read(fd, buf+nread, maxcnt-nread); -#endif /* WITH_SSL */ - - if (readret == 0) { - /* we got EOF on the file descriptor */ - DEBUG(5,("read_with_timeout: timeout read. EOF from client.\n")); - smb_read_error = READ_EOF; - return -1; - } - - if (readret == -1) { - /* the descriptor is probably dead */ - DEBUG(0,("read_with_timeout: timeout read. read error = %s.\n", unix_error_string (errno) )); - smb_read_error = READ_ERROR; - return -1; - } - - nread += readret; - } - - /* Return the number we got */ - return((ssize_t)nread); -} - - -/**************************************************************************** -send a keepalive packet (rfc1002) -****************************************************************************/ -BOOL send_keepalive(int client) -{ - unsigned char buf[4]; - - buf[0] = 0x85; - buf[1] = buf[2] = buf[3] = 0; - - return(write_data(client,(char *)buf,4) == 4); -} - - - -/**************************************************************************** - read data from the client, reading exactly N bytes. -****************************************************************************/ -ssize_t read_data(int fd,char *buffer,size_t N) -{ - ssize_t ret; - size_t total=0; - - smb_read_error = 0; - - while (total < N) - { -#ifdef WITH_SSL - if(fd == sslFd){ - ret = SSL_read(ssl, buffer + total, N - total); - }else{ - ret = read(fd,buffer + total,N - total); - } -#else /* WITH_SSL */ - ret = read(fd,buffer + total,N - total); -#endif /* WITH_SSL */ - - if (ret == 0) - { - DEBUG(10,("read_data: read of %d returned 0. Error = %s\n", (int)(N - total), unix_error_string (errno) )); - smb_read_error = READ_EOF; - return 0; - } - if (ret == -1) - { - DEBUG(0,("read_data: read failure for %d. Error = %s\n", (int)(N - total), unix_error_string (errno) )); - smb_read_error = READ_ERROR; - return -1; - } - total += ret; - } - return (ssize_t)total; -} - - -/**************************************************************************** - write data to a fd -****************************************************************************/ -ssize_t write_data(int fd,char *buffer,size_t N) -{ - size_t total=0; - ssize_t ret; - - while (total < N) - { -#ifdef WITH_SSL - if(fd == sslFd){ - ret = SSL_write(ssl,buffer + total,N - total); - }else{ - ret = write(fd,buffer + total,N - total); - } -#else /* WITH_SSL */ - ret = write(fd,buffer + total,N - total); -#endif /* WITH_SSL */ - - if (ret == -1) { - DEBUG(1,("write_data: write failure. Error = %s\n", unix_error_string (errno) )); - return -1; - } - if (ret == 0) return total; - - total += ret; - } - return (ssize_t)total; -} - - - -/**************************************************************************** -read 4 bytes of a smb packet and return the smb length of the packet -store the result in the buffer -This version of the function will return a length of zero on receiving -a keepalive packet. -timeout is in milliseconds. -****************************************************************************/ -static ssize_t read_smb_length_return_keepalive(int fd,char *inbuf,unsigned int timeout) -{ - ssize_t len=0; - int msg_type; - BOOL ok = False; - - while (!ok) - { - if (timeout > 0) - ok = (read_with_timeout(fd,inbuf,4,4,timeout) == 4); - else - ok = (read_data(fd,inbuf,4) == 4); - - if (!ok) - return(-1); - - len = smb_len(inbuf); - msg_type = CVAL(inbuf,0); - - if (msg_type == 0x85) - DEBUG(5,("Got keepalive packet\n")); - } - - DEBUG(10,("got smb length of %d\n", (int)len)); - - return(len); -} -#if 0 -/**************************************************************************** -read 4 bytes of a smb packet and return the smb length of the packet -store the result in the buffer. This version of the function will -never return a session keepalive (length of zero). -timeout is in milliseconds. -****************************************************************************/ -ssize_t read_smb_length(int fd,char *inbuf,unsigned int timeout) -{ - ssize_t len; - - for(;;) - { - len = read_smb_length_return_keepalive(fd, inbuf, timeout); - - if(len < 0) - return len; - - /* Ignore session keepalives. */ - if(CVAL(inbuf,0) != 0x85) - break; - } - - DEBUG(10,("read_smb_length: got smb length of %d\n",len)); - - return len; -} -#endif /* 0 */ -/**************************************************************************** - read an smb from a fd. Note that the buffer *MUST* be of size - BUFFER_SIZE+SAFETY_MARGIN. - The timeout is in milliseconds. - This function will return on a - receipt of a session keepalive packet. -****************************************************************************/ -BOOL receive_smb(int fd,char *buffer, unsigned int timeout) -{ - ssize_t len,ret; - - smb_read_error = 0; - - memset(buffer,'\0',smb_size + 100); - - len = read_smb_length_return_keepalive(fd,buffer,timeout); - if (len < 0) - { - DEBUG(10,("receive_smb: length < 0!\n")); - return(False); - } - - if (len > BUFFER_SIZE) { - DEBUG(0,("Invalid packet length! (%d bytes).\n", (int)len)); - if (len > BUFFER_SIZE + (SAFETY_MARGIN/2)) - { - exit(1); - } - } - - if(len > 0) { - ret = read_data(fd,buffer+4,len); - if (ret != len) { - smb_read_error = READ_ERROR; - return False; - } - } - return(True); -} - -/**************************************************************************** - read an smb from a fd ignoring all keepalive packets. Note that the buffer - *MUST* be of size BUFFER_SIZE+SAFETY_MARGIN. - The timeout is in milliseconds - - This is exactly the same as receive_smb except that it never returns - a session keepalive packet (just as receive_smb used to do). - receive_smb was changed to return keepalives as the oplock processing means this call - should never go into a blocking read. -****************************************************************************/ - -BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout) -{ - BOOL ret; - - for(;;) - { - ret = receive_smb(fd, buffer, timeout); - - if (!ret) - { - DEBUG(10,("client_receive_smb failed\n")); - show_msg(buffer); - return ret; - } - - /* Ignore session keepalive packets. */ - if(CVAL(buffer,0) != 0x85) - break; - } - show_msg(buffer); - return ret; -} - -/**************************************************************************** - send an null session message to a fd -****************************************************************************/ -#if 0 -BOOL send_null_session_msg(int fd) -{ - ssize_t ret; - uint32 blank = 0; - size_t len = 4; - size_t nwritten=0; - char *buffer = (char *)␣ - - while (nwritten < len) - { - ret = write_socket(fd,buffer+nwritten,len - nwritten); - if (ret <= 0) - { - DEBUG(0,("send_null_session_msg: Error writing %d bytes to client. %d. Exiting\n",(int)len,(int)ret)); - close_sockets(); - exit(1); - } - nwritten += ret; - } - - DEBUG(10,("send_null_session_msg: sent 4 null bytes to client.\n")); - return True; -} - -/**************************************************************************** - send an smb to a fd -****************************************************************************/ -BOOL send_smb(int fd,char *buffer) -{ - size_t len; - size_t nwritten=0; - ssize_t ret; - len = smb_len(buffer) + 4; - - while (nwritten < len) - { - ret = write_socket(fd,buffer+nwritten,len - nwritten); - if (ret <= 0) - { - DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",(int)len,(int)ret)); - close_sockets(); - exit(1); - } - nwritten += ret; - } - - return True; -} - - - -/**************************************************************************** -send a single packet to a port on another machine -****************************************************************************/ -BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type) -{ - BOOL ret; - int out_fd; - struct sockaddr_in sock_out; - - if (passive) - return(True); - - /* create a socket to write to */ - out_fd = socket(AF_INET, type, 0); - if (out_fd == -1) - { - DEBUG(0,("socket failed")); - return False; - } - - /* set the address and port */ - memset((char *)&sock_out,'\0',sizeof(sock_out)); - putip((char *)&sock_out.sin_addr,(char *)&ip); - sock_out.sin_port = htons( port ); - sock_out.sin_family = AF_INET; - - if (DEBUGLEVEL > 0) - DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n", - len,inet_ntoa(ip),port,type==SOCK_DGRAM?"DGRAM":"STREAM")); - - /* send it */ - ret = (sendto(out_fd,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0); - - if (!ret) - DEBUG(0,("Packet send to %s(%d) failed ERRNO=%s\n", - inet_ntoa(ip),port,unix_error_string (errno))); - - close(out_fd); - return(ret); -} -#endif /* 0 */ - -/**************************************************************************** -open a socket of the specified type, port and address for incoming data -****************************************************************************/ -int open_socket_in(int type, int port, int dlevel,uint32 socket_addr, BOOL rebind) -{ - struct hostent *hp; - struct sockaddr_in sock; - pstring host_name; - int res; - - /* get my host name */ - if (gethostname(host_name, MAXHOSTNAMELEN) == -1) - { DEBUG(0,("gethostname failed\n")); return -1; } - - /* get host info */ - if ((hp = Get_Hostbyname(host_name)) == 0) - { - DEBUG(0,( "Get_Hostbyname: Unknown host %s\n",host_name)); - return -1; - } - - memset((char *)&sock,'\0',sizeof(sock)); - memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length); - -#ifdef HAVE_SOCK_SIN_LEN - sock.sin_len = sizeof(sock); -#endif - sock.sin_port = htons( port ); - sock.sin_family = hp->h_addrtype; - sock.sin_addr.s_addr = socket_addr; - res = socket(hp->h_addrtype, type, 0); - if (res == -1) - { DEBUG(0,("socket failed\n")); return -1; } - - { - int val=1; - if(rebind) - val=1; - else - val=0; - setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val)); - } - - /* now we've got a socket - we need to bind it */ - if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0) - { - if (port) { - if (port == SMB_PORT || port == NMB_PORT) - DEBUG(dlevel,("bind failed on port %d socket_addr=%s (%s)\n", - port,inet_ntoa(sock.sin_addr),unix_error_string (errno))); - close(res); - - if (dlevel > 0 && port < 1000) - port = 7999; - - if (port >= 1000 && port < 9000) - return(open_socket_in(type,port+1,dlevel,socket_addr,rebind)); - } - - return(-1); - } - DEBUG(3,("bind succeeded on port %d\n",port)); - - return res; -} - - -/**************************************************************************** - create an outgoing socket. timeout is in milliseconds. - **************************************************************************/ -int open_socket_out(int type, struct in_addr *addr, int port ,int timeout) -{ - struct sockaddr_in sock_out; - int res,ret; - int connect_loop = 250; /* 250 milliseconds */ - int loops = (timeout) / connect_loop; - - /* create a socket to write to */ - res = socket(PF_INET, type, 0); - if (res == -1) - { DEBUG(0,("socket error\n")); return -1; } - - if (type != SOCK_STREAM) return(res); - - memset((char *)&sock_out,'\0',sizeof(sock_out)); - putip((char *)&sock_out.sin_addr,(char *)addr); - - sock_out.sin_port = htons( port ); - sock_out.sin_family = PF_INET; - - /* set it non-blocking */ - set_blocking(res,False); - - DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port)); - - /* and connect it to the destination */ -connect_again: - ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out)); - - /* Some systems return EAGAIN when they mean EINPROGRESS */ - if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY || - errno == EAGAIN) && loops--) { - msleep(connect_loop); - goto connect_again; - } - - if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY || - errno == EAGAIN)) { - DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port)); - close(res); - return -1; - } - -#ifdef EISCONN - if (ret < 0 && errno == EISCONN) { - errno = 0; - ret = 0; - } -#endif - - if (ret < 0) { - DEBUG(1,("error connecting to %s:%d (%s)\n", - inet_ntoa(*addr),port,unix_error_string (errno))); - close(res); - return -1; - } - - /* set it blocking again */ - set_blocking(res,True); - - return res; -} - - -/******************************************************************* - Reset the 'done' variables so after a client process is created - from a fork call these calls will be re-done. This should be - expanded if more variables need reseting. - ******************************************************************/ - -static BOOL global_client_name_done = False; -static BOOL global_client_addr_done = False; - -/******************************************************************* - return the DNS name of the client - ******************************************************************/ -char *client_name(int fd) -{ - struct sockaddr sa; - struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa); - unsigned int length = sizeof(sa); - static pstring name_buf; - struct hostent *hp; - static int last_fd=-1; - - if (global_client_name_done && last_fd == fd) - return name_buf; - - last_fd = fd; - global_client_name_done = False; - - pstrcpy(name_buf,"UNKNOWN"); - - if (fd == -1) { - return name_buf; - } - - if (getpeername(fd, &sa, &length) < 0) { - DEBUG(0,("getpeername failed. Error was %s\n", unix_error_string (errno) )); - return name_buf; - } - - /* Look up the remote host name. */ - if ((hp = gethostbyaddr((char *) &sockin->sin_addr, - sizeof(sockin->sin_addr), - AF_INET)) == 0) { - DEBUG(1,("Gethostbyaddr failed for %s\n",client_addr(fd))); - StrnCpy(name_buf,client_addr(fd),sizeof(name_buf) - 1); - } else { - StrnCpy(name_buf,(char *)hp->h_name,sizeof(name_buf) - 1); - if (!matchname(name_buf, sockin->sin_addr)) { - DEBUG(0,("Matchname failed on %s %s\n",name_buf,client_addr(fd))); - pstrcpy(name_buf,"UNKNOWN"); - } - } - global_client_name_done = True; - return name_buf; -} - -/******************************************************************* - return the IP addr of the client as a string - ******************************************************************/ -char *client_addr(int fd) -{ - struct sockaddr sa; - struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa); - unsigned int length = sizeof(sa); - static fstring addr_buf; - static int last_fd = -1; - - if (global_client_addr_done && fd == last_fd) - return addr_buf; - - last_fd = fd; - global_client_addr_done = False; - - fstrcpy(addr_buf,"0.0.0.0"); - - if (fd == -1) { - return addr_buf; - } - - if (getpeername(fd, &sa, &length) < 0) { - DEBUG(0,("getpeername failed. Error was %s\n", unix_error_string (errno) )); - return addr_buf; - } - - fstrcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr)); - - global_client_addr_done = True; - return addr_buf; -} +/* + Unix SMB/Netbios implementation. + Version 1.9. + Samba utility functions + + Copyright (C) Andrew Tridgell 1992-1998 + + Copyright (C) 2011 + The Free Software Foundation, Inc. + + This file is part of the Midnight Commander. + + The Midnight Commander is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + The Midnight Commander is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + */ + +#include "includes.h" + +const char *unix_error_string (int error_num); + +#ifdef WITH_SSL +#include +#undef Realloc /* SSLeay defines this and samba has a function of this name */ +extern SSL *ssl; +extern int sslFd; +#endif /* WITH_SSL */ + +extern int DEBUGLEVEL; + +BOOL passive = False; + +/* the client file descriptor */ +int Client = -1; + +/* the last IP received from */ +struct in_addr lastip; + +/* the last port received from */ +int lastport = 0; + + +int smb_read_error = 0; + + +/**************************************************************************** +determine if a file descriptor is in fact a socket +****************************************************************************/ +BOOL +is_a_socket (int fd) +{ + int v; + unsigned int l; + l = sizeof (int); + return (getsockopt (fd, SOL_SOCKET, SO_TYPE, (char *) &v, &l) == 0); +} + + +enum SOCK_OPT_TYPES +{ OPT_BOOL, OPT_INT, OPT_ON }; + +static const struct +{ + const char *name; + int level; + int option; + int value; + int opttype; +} socket_options[] = +{ + { + "SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL}, + { + "SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL}, + { + "SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL}, +#ifdef TCP_NODELAY + { + "TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL}, +#endif +#ifdef IPTOS_LOWDELAY + { + "IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON}, +#endif +#ifdef IPTOS_THROUGHPUT + { + "IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON}, +#endif +#ifdef SO_SNDBUF + { + "SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT}, +#endif +#ifdef SO_RCVBUF + { + "SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT}, +#endif +#ifdef SO_SNDLOWAT + { + "SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT}, +#endif +#ifdef SO_RCVLOWAT + { + "SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT}, +#endif +#ifdef SO_SNDTIMEO + { + "SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, 0, OPT_INT}, +#endif +#ifdef SO_RCVTIMEO + { + "SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, 0, OPT_INT}, +#endif + { +NULL, 0, 0, 0, 0}}; + + + +/**************************************************************************** +set user socket options +****************************************************************************/ +void +set_socket_options (int fd, char *options) +{ + fstring tok; + + while (next_token (&options, tok, " \t,", sizeof (tok))) + { + int ret = 0, i; + int value = 1; + char *p; + BOOL got_value = False; + + if ((p = strchr (tok, '='))) + { + *p = 0; + value = atoi (p + 1); + got_value = True; + } + + for (i = 0; socket_options[i].name; i++) + if (strequal (socket_options[i].name, tok)) + break; + + if (!socket_options[i].name) + { + DEBUG (0, ("Unknown socket option %s\n", tok)); + continue; + } + + switch (socket_options[i].opttype) + { + case OPT_BOOL: + case OPT_INT: + ret = setsockopt (fd, socket_options[i].level, + socket_options[i].option, (char *) &value, sizeof (int)); + break; + + case OPT_ON: + if (got_value) + DEBUG (0, ("syntax error - %s does not take a value\n", tok)); + + { + int on = socket_options[i].value; + ret = setsockopt (fd, socket_options[i].level, + socket_options[i].option, (char *) &on, sizeof (int)); + } + break; + } + + if (ret != 0) + DEBUG (0, ("Failed to set socket option %s\n", tok)); + } +} + + + +/**************************************************************************** + close the socket communication +****************************************************************************/ +void +close_sockets (void) +{ +#ifdef WITH_SSL + sslutil_disconnect (Client); +#endif /* WITH_SSL */ + + close (Client); + Client = -1; +} + + + +/**************************************************************************** +write to a socket +****************************************************************************/ +ssize_t +write_socket (int fd, char *buf, size_t len) +{ + ssize_t ret = 0; + + if (passive) + return (len); + DEBUG (6, ("write_socket(%d,%d)\n", fd, (int) len)); + ret = write_data (fd, buf, len); + + DEBUG (6, ("write_socket(%d,%d) wrote %d\n", fd, (int) len, (int) ret)); + if (ret <= 0) + DEBUG (1, ("write_socket: Error writing %d bytes to socket %d: ERRNO = %s\n", + (int) len, fd, unix_error_string (errno))); + + return (ret); +} + +/**************************************************************************** +read from a socket +****************************************************************************/ +ssize_t +read_udp_socket (int fd, char *buf, size_t len) +{ + ssize_t ret; + struct sockaddr_in sock; + unsigned int socklen; + + socklen = sizeof (sock); + memset ((char *) &sock, '\0', socklen); + memset ((char *) &lastip, '\0', sizeof (lastip)); + ret = (ssize_t) recvfrom (fd, buf, len, 0, (struct sockaddr *) &sock, &socklen); + if (ret <= 0) + { + DEBUG (2, ("read socket failed. ERRNO=%s\n", unix_error_string (errno))); + return (0); + } + + lastip = sock.sin_addr; + lastport = ntohs (sock.sin_port); + + DEBUG (10, ("read_udp_socket: lastip %s lastport %d read: %d\n", + inet_ntoa (lastip), lastport, (int) ret)); + + return (ret); +} + + +/**************************************************************************** +read data from a device with a timout in msec. +mincount = if timeout, minimum to read before returning +maxcount = number to be read. +time_out = timeout in milliseconds +****************************************************************************/ + +ssize_t +read_with_timeout (int fd, char *buf, size_t mincnt, size_t maxcnt, unsigned int time_out) +{ + fd_set fds; + int selrtn; + ssize_t readret; + size_t nread = 0; + struct timeval timeout; + + /* just checking .... */ + if (maxcnt <= 0) + return (0); + + smb_read_error = 0; + + /* Blocking read */ + if (time_out <= 0) + { + if (mincnt == 0) + mincnt = maxcnt; + + while (nread < mincnt) + { +#ifdef WITH_SSL + if (fd == sslFd) + { + readret = SSL_read (ssl, buf + nread, maxcnt - nread); + } + else + { + readret = read (fd, buf + nread, maxcnt - nread); + } +#else /* WITH_SSL */ + readret = read (fd, buf + nread, maxcnt - nread); +#endif /* WITH_SSL */ + + if (readret == 0) + { + DEBUG (5, ("read_with_timeout: blocking read. EOF from client.\n")); + smb_read_error = READ_EOF; + return -1; + } + + if (readret == -1) + { + DEBUG (0, ("read_with_timeout: read error = %s.\n", unix_error_string (errno))); + smb_read_error = READ_ERROR; + return -1; + } + nread += readret; + } + return ((ssize_t) nread); + } + + /* Most difficult - timeout read */ + /* If this is ever called on a disk file and + mincnt is greater then the filesize then + system performance will suffer severely as + select always returns true on disk files */ + + /* Set initial timeout */ + timeout.tv_sec = (time_t) (time_out / 1000); + timeout.tv_usec = (long) (1000 * (time_out % 1000)); + + for (nread = 0; nread < mincnt;) + { + FD_ZERO (&fds); + FD_SET (fd, &fds); + + selrtn = sys_select (fd + 1, &fds, &timeout); + + /* Check if error */ + if (selrtn == -1) + { + /* something is wrong. Maybe the socket is dead? */ + DEBUG (0, + ("read_with_timeout: timeout read. select error = %s.\n", + unix_error_string (errno))); + smb_read_error = READ_ERROR; + return -1; + } + + /* Did we timeout ? */ + if (selrtn == 0) + { + DEBUG (10, ("read_with_timeout: timeout read. select timed out.\n")); + smb_read_error = READ_TIMEOUT; + return -1; + } + +#ifdef WITH_SSL + if (fd == sslFd) + { + readret = SSL_read (ssl, buf + nread, maxcnt - nread); + } + else + { + readret = read (fd, buf + nread, maxcnt - nread); + } +#else /* WITH_SSL */ + readret = read (fd, buf + nread, maxcnt - nread); +#endif /* WITH_SSL */ + + if (readret == 0) + { + /* we got EOF on the file descriptor */ + DEBUG (5, ("read_with_timeout: timeout read. EOF from client.\n")); + smb_read_error = READ_EOF; + return -1; + } + + if (readret == -1) + { + /* the descriptor is probably dead */ + DEBUG (0, + ("read_with_timeout: timeout read. read error = %s.\n", + unix_error_string (errno))); + smb_read_error = READ_ERROR; + return -1; + } + + nread += readret; + } + + /* Return the number we got */ + return ((ssize_t) nread); +} + + +/**************************************************************************** +send a keepalive packet (rfc1002) +****************************************************************************/ +BOOL +send_keepalive (int client) +{ + unsigned char buf[4]; + + buf[0] = 0x85; + buf[1] = buf[2] = buf[3] = 0; + + return (write_data (client, (char *) buf, 4) == 4); +} + + + +/**************************************************************************** + read data from the client, reading exactly N bytes. +****************************************************************************/ +ssize_t +read_data (int fd, char *buffer, size_t N) +{ + ssize_t ret; + size_t total = 0; + + smb_read_error = 0; + + while (total < N) + { +#ifdef WITH_SSL + if (fd == sslFd) + { + ret = SSL_read (ssl, buffer + total, N - total); + } + else + { + ret = read (fd, buffer + total, N - total); + } +#else /* WITH_SSL */ + ret = read (fd, buffer + total, N - total); +#endif /* WITH_SSL */ + + if (ret == 0) + { + DEBUG (10, + ("read_data: read of %d returned 0. Error = %s\n", (int) (N - total), + unix_error_string (errno))); + smb_read_error = READ_EOF; + return 0; + } + if (ret == -1) + { + DEBUG (0, + ("read_data: read failure for %d. Error = %s\n", (int) (N - total), + unix_error_string (errno))); + smb_read_error = READ_ERROR; + return -1; + } + total += ret; + } + return (ssize_t) total; +} + + +/**************************************************************************** + write data to a fd +****************************************************************************/ +ssize_t +write_data (int fd, char *buffer, size_t N) +{ + size_t total = 0; + ssize_t ret; + + while (total < N) + { +#ifdef WITH_SSL + if (fd == sslFd) + { + ret = SSL_write (ssl, buffer + total, N - total); + } + else + { + ret = write (fd, buffer + total, N - total); + } +#else /* WITH_SSL */ + ret = write (fd, buffer + total, N - total); +#endif /* WITH_SSL */ + + if (ret == -1) + { + DEBUG (1, ("write_data: write failure. Error = %s\n", unix_error_string (errno))); + return -1; + } + if (ret == 0) + return total; + + total += ret; + } + return (ssize_t) total; +} + + + +/**************************************************************************** +read 4 bytes of a smb packet and return the smb length of the packet +store the result in the buffer +This version of the function will return a length of zero on receiving +a keepalive packet. +timeout is in milliseconds. +****************************************************************************/ +static ssize_t +read_smb_length_return_keepalive (int fd, char *inbuf, unsigned int timeout) +{ + ssize_t len = 0; + int msg_type; + BOOL ok = False; + + while (!ok) + { + if (timeout > 0) + ok = (read_with_timeout (fd, inbuf, 4, 4, timeout) == 4); + else + ok = (read_data (fd, inbuf, 4) == 4); + + if (!ok) + return (-1); + + len = smb_len (inbuf); + msg_type = CVAL (inbuf, 0); + + if (msg_type == 0x85) + DEBUG (5, ("Got keepalive packet\n")); + } + + DEBUG (10, ("got smb length of %d\n", (int) len)); + + return (len); +} + +#if 0 +/**************************************************************************** +read 4 bytes of a smb packet and return the smb length of the packet +store the result in the buffer. This version of the function will +never return a session keepalive (length of zero). +timeout is in milliseconds. +****************************************************************************/ +ssize_t +read_smb_length (int fd, char *inbuf, unsigned int timeout) +{ + ssize_t len; + + for (;;) + { + len = read_smb_length_return_keepalive (fd, inbuf, timeout); + + if (len < 0) + return len; + + /* Ignore session keepalives. */ + if (CVAL (inbuf, 0) != 0x85) + break; + } + + DEBUG (10, ("read_smb_length: got smb length of %d\n", len)); + + return len; +} +#endif /* 0 */ +/**************************************************************************** + read an smb from a fd. Note that the buffer *MUST* be of size + BUFFER_SIZE+SAFETY_MARGIN. + The timeout is in milliseconds. + This function will return on a + receipt of a session keepalive packet. +****************************************************************************/ +BOOL +receive_smb (int fd, char *buffer, unsigned int timeout) +{ + ssize_t len, ret; + + smb_read_error = 0; + + memset (buffer, '\0', smb_size + 100); + + len = read_smb_length_return_keepalive (fd, buffer, timeout); + if (len < 0) + { + DEBUG (10, ("receive_smb: length < 0!\n")); + return (False); + } + + if (len > BUFFER_SIZE) + { + DEBUG (0, ("Invalid packet length! (%d bytes).\n", (int) len)); + if (len > BUFFER_SIZE + (SAFETY_MARGIN / 2)) + { + exit (1); + } + } + + if (len > 0) + { + ret = read_data (fd, buffer + 4, len); + if (ret != len) + { + smb_read_error = READ_ERROR; + return False; + } + } + return (True); +} + +/**************************************************************************** + read an smb from a fd ignoring all keepalive packets. Note that the buffer + *MUST* be of size BUFFER_SIZE+SAFETY_MARGIN. + The timeout is in milliseconds + + This is exactly the same as receive_smb except that it never returns + a session keepalive packet (just as receive_smb used to do). + receive_smb was changed to return keepalives as the oplock processing means this call + should never go into a blocking read. +****************************************************************************/ + +BOOL +client_receive_smb (int fd, char *buffer, unsigned int timeout) +{ + BOOL ret; + + for (;;) + { + ret = receive_smb (fd, buffer, timeout); + + if (!ret) + { + DEBUG (10, ("client_receive_smb failed\n")); + show_msg (buffer); + return ret; + } + + /* Ignore session keepalive packets. */ + if (CVAL (buffer, 0) != 0x85) + break; + } + show_msg (buffer); + return ret; +} + +/**************************************************************************** + send an null session message to a fd +****************************************************************************/ +#if 0 +BOOL +send_null_session_msg (int fd) +{ + ssize_t ret; + uint32 blank = 0; + size_t len = 4; + size_t nwritten = 0; + char *buffer = (char *) ␣ + + while (nwritten < len) + { + ret = write_socket (fd, buffer + nwritten, len - nwritten); + if (ret <= 0) + { + DEBUG (0, + ("send_null_session_msg: Error writing %d bytes to client. %d. Exiting\n", + (int) len, (int) ret)); + close_sockets (); + exit (1); + } + nwritten += ret; + } + + DEBUG (10, ("send_null_session_msg: sent 4 null bytes to client.\n")); + return True; +} + +/**************************************************************************** + send an smb to a fd +****************************************************************************/ +BOOL +send_smb (int fd, char *buffer) +{ + size_t len; + size_t nwritten = 0; + ssize_t ret; + len = smb_len (buffer) + 4; + + while (nwritten < len) + { + ret = write_socket (fd, buffer + nwritten, len - nwritten); + if (ret <= 0) + { + DEBUG (0, ("Error writing %d bytes to client. %d. Exiting\n", (int) len, (int) ret)); + close_sockets (); + exit (1); + } + nwritten += ret; + } + + return True; +} + + + +/**************************************************************************** +send a single packet to a port on another machine +****************************************************************************/ +BOOL +send_one_packet (char *buf, int len, struct in_addr ip, int port, int type) +{ + BOOL ret; + int out_fd; + struct sockaddr_in sock_out; + + if (passive) + return (True); + + /* create a socket to write to */ + out_fd = socket (AF_INET, type, 0); + if (out_fd == -1) + { + DEBUG (0, ("socket failed")); + return False; + } + + /* set the address and port */ + memset ((char *) &sock_out, '\0', sizeof (sock_out)); + putip ((char *) &sock_out.sin_addr, (char *) &ip); + sock_out.sin_port = htons (port); + sock_out.sin_family = AF_INET; + + if (DEBUGLEVEL > 0) + DEBUG (3, ("sending a packet of len %d to (%s) on port %d of type %s\n", + len, inet_ntoa (ip), port, type == SOCK_DGRAM ? "DGRAM" : "STREAM")); + + /* send it */ + ret = (sendto (out_fd, buf, len, 0, (struct sockaddr *) &sock_out, sizeof (sock_out)) >= 0); + + if (!ret) + DEBUG (0, ("Packet send to %s(%d) failed ERRNO=%s\n", + inet_ntoa (ip), port, unix_error_string (errno))); + + close (out_fd); + return (ret); +} +#endif /* 0 */ + +/**************************************************************************** +open a socket of the specified type, port and address for incoming data +****************************************************************************/ +int +open_socket_in (int type, int port, int dlevel, uint32 socket_addr, BOOL rebind) +{ + struct hostent *hp; + struct sockaddr_in sock; + pstring host_name; + int res; + + /* get my host name */ + if (gethostname (host_name, MAXHOSTNAMELEN) == -1) + { + DEBUG (0, ("gethostname failed\n")); + return -1; + } + + /* get host info */ + if ((hp = Get_Hostbyname (host_name)) == 0) + { + DEBUG (0, ("Get_Hostbyname: Unknown host %s\n", host_name)); + return -1; + } + + memset ((char *) &sock, '\0', sizeof (sock)); + memcpy ((char *) &sock.sin_addr, (char *) hp->h_addr, hp->h_length); + +#ifdef HAVE_SOCK_SIN_LEN + sock.sin_len = sizeof (sock); +#endif + sock.sin_port = htons (port); + sock.sin_family = hp->h_addrtype; + sock.sin_addr.s_addr = socket_addr; + res = socket (hp->h_addrtype, type, 0); + if (res == -1) + { + DEBUG (0, ("socket failed\n")); + return -1; + } + + { + int val = 1; + if (rebind) + val = 1; + else + val = 0; + setsockopt (res, SOL_SOCKET, SO_REUSEADDR, (char *) &val, sizeof (val)); + } + + /* now we've got a socket - we need to bind it */ + if (bind (res, (struct sockaddr *) &sock, sizeof (sock)) < 0) + { + if (port) + { + if (port == SMB_PORT || port == NMB_PORT) + DEBUG (dlevel, ("bind failed on port %d socket_addr=%s (%s)\n", + port, inet_ntoa (sock.sin_addr), unix_error_string (errno))); + close (res); + + if (dlevel > 0 && port < 1000) + port = 7999; + + if (port >= 1000 && port < 9000) + return (open_socket_in (type, port + 1, dlevel, socket_addr, rebind)); + } + + return (-1); + } + DEBUG (3, ("bind succeeded on port %d\n", port)); + + return res; +} + + +/**************************************************************************** + create an outgoing socket. timeout is in milliseconds. + **************************************************************************/ +int +open_socket_out (int type, struct in_addr *addr, int port, int timeout) +{ + struct sockaddr_in sock_out; + int res, ret; + int connect_loop = 250; /* 250 milliseconds */ + int loops = (timeout) / connect_loop; + + /* create a socket to write to */ + res = socket (PF_INET, type, 0); + if (res == -1) + { + DEBUG (0, ("socket error\n")); + return -1; + } + + if (type != SOCK_STREAM) + return (res); + + memset ((char *) &sock_out, '\0', sizeof (sock_out)); + putip ((char *) &sock_out.sin_addr, (char *) addr); + + sock_out.sin_port = htons (port); + sock_out.sin_family = PF_INET; + + /* set it non-blocking */ + set_blocking (res, False); + + DEBUG (3, ("Connecting to %s at port %d\n", inet_ntoa (*addr), port)); + + /* and connect it to the destination */ + connect_again: + ret = connect (res, (struct sockaddr *) &sock_out, sizeof (sock_out)); + + /* Some systems return EAGAIN when they mean EINPROGRESS */ + if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY || errno == EAGAIN) && loops--) + { + msleep (connect_loop); + goto connect_again; + } + + if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY || errno == EAGAIN)) + { + DEBUG (1, ("timeout connecting to %s:%d\n", inet_ntoa (*addr), port)); + close (res); + return -1; + } + +#ifdef EISCONN + if (ret < 0 && errno == EISCONN) + { + errno = 0; + ret = 0; + } +#endif + + if (ret < 0) + { + DEBUG (1, ("error connecting to %s:%d (%s)\n", + inet_ntoa (*addr), port, unix_error_string (errno))); + close (res); + return -1; + } + + /* set it blocking again */ + set_blocking (res, True); + + return res; +} + + +/******************************************************************* + Reset the 'done' variables so after a client process is created + from a fork call these calls will be re-done. This should be + expanded if more variables need reseting. + ******************************************************************/ + +static BOOL global_client_name_done = False; +static BOOL global_client_addr_done = False; + +/******************************************************************* + return the DNS name of the client + ******************************************************************/ +char * +client_name (int fd) +{ + struct sockaddr sa; + struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa); + unsigned int length = sizeof (sa); + static pstring name_buf; + struct hostent *hp; + static int last_fd = -1; + + if (global_client_name_done && last_fd == fd) + return name_buf; + + last_fd = fd; + global_client_name_done = False; + + pstrcpy (name_buf, "UNKNOWN"); + + if (fd == -1) + { + return name_buf; + } + + if (getpeername (fd, &sa, &length) < 0) + { + DEBUG (0, ("getpeername failed. Error was %s\n", unix_error_string (errno))); + return name_buf; + } + + /* Look up the remote host name. */ + if ((hp = gethostbyaddr ((char *) &sockin->sin_addr, sizeof (sockin->sin_addr), AF_INET)) == 0) + { + DEBUG (1, ("Gethostbyaddr failed for %s\n", client_addr (fd))); + StrnCpy (name_buf, client_addr (fd), sizeof (name_buf) - 1); + } + else + { + StrnCpy (name_buf, (char *) hp->h_name, sizeof (name_buf) - 1); + if (!matchname (name_buf, sockin->sin_addr)) + { + DEBUG (0, ("Matchname failed on %s %s\n", name_buf, client_addr (fd))); + pstrcpy (name_buf, "UNKNOWN"); + } + } + global_client_name_done = True; + return name_buf; +} + +/******************************************************************* + return the IP addr of the client as a string + ******************************************************************/ +char * +client_addr (int fd) +{ + struct sockaddr sa; + struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa); + unsigned int length = sizeof (sa); + static fstring addr_buf; + static int last_fd = -1; + + if (global_client_addr_done && fd == last_fd) + return addr_buf; + + last_fd = fd; + global_client_addr_done = False; + + fstrcpy (addr_buf, "0.0.0.0"); + + if (fd == -1) + { + return addr_buf; + } + + if (getpeername (fd, &sa, &length) < 0) + { + DEBUG (0, ("getpeername failed. Error was %s\n", unix_error_string (errno))); + return addr_buf; + } + + fstrcpy (addr_buf, (char *) inet_ntoa (sockin->sin_addr)); + + global_client_addr_done = True; + return addr_buf; +} diff --git a/src/vfs/smbfs/helpers/lib/util_str.c b/src/vfs/smbfs/helpers/lib/util_str.c dissimilarity index 64% index f99d013c6..fad4225c9 100644 --- a/src/vfs/smbfs/helpers/lib/util_str.c +++ b/src/vfs/smbfs/helpers/lib/util_str.c @@ -1,1103 +1,1190 @@ -/* - Unix SMB/Netbios implementation. - Version 1.9. - Samba utility functions - - Copyright (C) Andrew Tridgell 1992-1998 - - Copyright (C) 2011 - The Free Software Foundation, Inc. - - This file is part of the Midnight Commander. - - The Midnight Commander is free software: you can redistribute it - and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of the License, - or (at your option) any later version. - - The Midnight Commander is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "includes.h" - -extern int DEBUGLEVEL; - -static char *last_ptr=NULL; - -void set_first_token(char *ptr) -{ - last_ptr = ptr; -} - -/**************************************************************************** - Get the next token from a string, return False if none found - handles double-quotes. -Based on a routine by GJC@VILLAGE.COM. -Extensively modified by Andrew.Tridgell@anu.edu.au -****************************************************************************/ -BOOL next_token(char **ptr,char *buff, const char *sep, size_t bufsize) -{ - char *s; - BOOL quoted; - size_t len=1; - - if (!ptr) ptr = &last_ptr; - if (!ptr) return(False); - - s = *ptr; - - /* default to simple separators */ - if (!sep) sep = " \t\n\r"; - - /* find the first non sep char */ - while(*s && strchr(sep,*s)) s++; - - /* nothing left? */ - if (! *s) return(False); - - /* copy over the token */ - for (quoted = False; len < bufsize && *s && (quoted || !strchr(sep,*s)); s++) - { - if (*s == '\"') { - quoted = !quoted; - } else { - len++; - *buff++ = *s; - } - } - - *ptr = (*s) ? s+1 : s; - *buff = 0; - last_ptr = *ptr; - - return(True); -} - -#if 0 -/**************************************************************************** -Convert list of tokens to array; dependent on above routine. -Uses last_ptr from above - bit of a hack. -****************************************************************************/ -char **toktocliplist(int *ctok, char *sep) -{ - char *s=last_ptr; - int ictok=0; - char **ret, **iret; - - if (!sep) sep = " \t\n\r"; - - while(*s && strchr(sep,*s)) s++; - - /* nothing left? */ - if (!*s) return(NULL); - - do { - ictok++; - while(*s && (!strchr(sep,*s))) s++; - while(*s && strchr(sep,*s)) *s++=0; - } while(*s); - - *ctok=ictok; - s=last_ptr; - - if (!(ret=iret=malloc(ictok*sizeof(char *)))) return NULL; - - while(ictok--) { - *iret++=s; - while(*s++); - while(!*s) s++; - } - - return ret; -} -#endif /*0 */ - -/******************************************************************* - case insensitive string compararison -********************************************************************/ -int StrCaseCmp(const char *s, const char *t) -{ - /* compare until we run out of string, either t or s, or find a difference */ - /* We *must* use toupper rather than tolower here due to the - asynchronous upper to lower mapping. - */ -#if !defined(KANJI_WIN95_COMPATIBILITY) - /* - * For completeness we should put in equivalent code for code pages - * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but - * doubt anyone wants Samba to behave differently from Win95 and WinNT - * here. They both treat full width ascii characters as case senstive - * filenames (ie. they don't do the work we do here). - * JRA. - */ - - if(lp_client_code_page() == KANJI_CODEPAGE) - { - /* Win95 treats full width ascii characters as case sensitive. */ - int diff; - for (;;) - { - if (!*s || !*t) - return toupper (*s) - toupper (*t); - else if (is_sj_alph (*s) && is_sj_alph (*t)) - { - diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1)); - if (diff) - return diff; - s += 2; - t += 2; - } - else if (is_shift_jis (*s) && is_shift_jis (*t)) - { - diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t); - if (diff) - return diff; - diff = ((int) (unsigned char) *(s+1)) - ((int) (unsigned char) *(t+1)); - if (diff) - return diff; - s += 2; - t += 2; - } - else if (is_shift_jis (*s)) - return 1; - else if (is_shift_jis (*t)) - return -1; - else - { - diff = toupper (*s) - toupper (*t); - if (diff) - return diff; - s++; - t++; - } - } - } - else -#endif /* KANJI_WIN95_COMPATIBILITY */ - { - while (*s && *t && toupper(*s) == toupper(*t)) - { - s++; - t++; - } - - return(toupper(*s) - toupper(*t)); - } -} - -/******************************************************************* - case insensitive string compararison, length limited -********************************************************************/ -int StrnCaseCmp(const char *s, const char *t, size_t n) -{ - /* compare until we run out of string, either t or s, or chars */ - /* We *must* use toupper rather than tolower here due to the - asynchronous upper to lower mapping. - */ -#if !defined(KANJI_WIN95_COMPATIBILITY) - /* - * For completeness we should put in equivalent code for code pages - * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but - * doubt anyone wants Samba to behave differently from Win95 and WinNT - * here. They both treat full width ascii characters as case senstive - * filenames (ie. they don't do the work we do here). - * JRA. - */ - - if(lp_client_code_page() == KANJI_CODEPAGE) - { - /* Win95 treats full width ascii characters as case sensitive. */ - int diff; - for (;n > 0;) - { - if (!*s || !*t) - return toupper (*s) - toupper (*t); - else if (is_sj_alph (*s) && is_sj_alph (*t)) - { - diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1)); - if (diff) - return diff; - s += 2; - t += 2; - n -= 2; - } - else if (is_shift_jis (*s) && is_shift_jis (*t)) - { - diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t); - if (diff) - return diff; - diff = ((int) (unsigned char) *(s+1)) - ((int) (unsigned char) *(t+1)); - if (diff) - return diff; - s += 2; - t += 2; - n -= 2; - } - else if (is_shift_jis (*s)) - return 1; - else if (is_shift_jis (*t)) - return -1; - else - { - diff = toupper (*s) - toupper (*t); - if (diff) - return diff; - s++; - t++; - n--; - } - } - return 0; - } - else -#endif /* KANJI_WIN95_COMPATIBILITY */ - { - while (n && *s && *t && toupper(*s) == toupper(*t)) - { - s++; - t++; - n--; - } - - /* not run out of chars - strings are different lengths */ - if (n) - return(toupper(*s) - toupper(*t)); - - /* identical up to where we run out of chars, - and strings are same length */ - return(0); - } -} - -/******************************************************************* - compare 2 strings -********************************************************************/ -BOOL strequal(const char *s1, const char *s2) -{ - if (s1 == s2) return(True); - if (!s1 || !s2) return(False); - - return(StrCaseCmp(s1,s2)==0); -} - -/******************************************************************* - compare 2 strings up to and including the nth char. - ******************************************************************/ -BOOL strnequal(const char *s1,const char *s2,size_t n) -{ - if (s1 == s2) return(True); - if (!s1 || !s2 || !n) return(False); - - return(StrnCaseCmp(s1,s2,n)==0); -} - -/******************************************************************* - compare 2 strings (case sensitive) -********************************************************************/ -BOOL strcsequal(const char *s1,const char *s2) -{ - if (s1 == s2) return(True); - if (!s1 || !s2) return(False); - - return(strcmp(s1,s2)==0); -} - - -/******************************************************************* - convert a string to lower case -********************************************************************/ -void strlower(char *s) -{ - while (*s) - { -#if !defined(KANJI_WIN95_COMPATIBILITY) - /* - * For completeness we should put in equivalent code for code pages - * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but - * doubt anyone wants Samba to behave differently from Win95 and WinNT - * here. They both treat full width ascii characters as case senstive - * filenames (ie. they don't do the work we do here). - * JRA. - */ - - if(lp_client_code_page() == KANJI_CODEPAGE) - { - /* Win95 treats full width ascii characters as case sensitive. */ - if (is_shift_jis (*s)) - { - if (is_sj_upper (s[0], s[1])) - s[1] = sj_tolower2 (s[1]); - s += 2; - } - else if (is_kana (*s)) - { - s++; - } - else - { - if (isupper(*s)) - *s = tolower(*s); - s++; - } - } - else -#endif /* KANJI_WIN95_COMPATIBILITY */ - { - size_t skip = skip_multibyte_char( *s ); - if( skip != 0 ) - s += skip; - else - { - if (isupper(*s)) - *s = tolower(*s); - s++; - } - } - } -} - -/******************************************************************* - convert a string to upper case -********************************************************************/ -void strupper(char *s) -{ - while (*s) - { -#if !defined(KANJI_WIN95_COMPATIBILITY) - /* - * For completeness we should put in equivalent code for code pages - * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but - * doubt anyone wants Samba to behave differently from Win95 and WinNT - * here. They both treat full width ascii characters as case senstive - * filenames (ie. they don't do the work we do here). - * JRA. - */ - - if(lp_client_code_page() == KANJI_CODEPAGE) - { - /* Win95 treats full width ascii characters as case sensitive. */ - if (is_shift_jis (*s)) - { - if (is_sj_lower (s[0], s[1])) - s[1] = sj_toupper2 (s[1]); - s += 2; - } - else if (is_kana (*s)) - { - s++; - } - else - { - if (islower(*s)) - *s = toupper(*s); - s++; - } - } - else -#endif /* KANJI_WIN95_COMPATIBILITY */ - { - size_t skip = skip_multibyte_char( *s ); - if( skip != 0 ) - s += skip; - else - { - if (islower(*s)) - *s = toupper(*s); - s++; - } - } - } -} - -#if 0 -/******************************************************************* - convert a string to "normal" form -********************************************************************/ -void strnorm(char *s) -{ - extern int case_default; - if (case_default == CASE_UPPER) - strupper(s); - else - strlower(s); -} - -/******************************************************************* -check if a string is in "normal" case -********************************************************************/ -BOOL strisnormal(char *s) -{ - extern int case_default; - if (case_default == CASE_UPPER) - return(!strhaslower(s)); - - return(!strhasupper(s)); -} -#endif /* 0 */ - -/**************************************************************************** - string replace -****************************************************************************/ -void string_replace(char *s,char oldc,char newc) -{ - size_t skip; - while (*s) - { - skip = skip_multibyte_char( *s ); - if( skip != 0 ) - s += skip; - else - { - if (oldc == *s) - *s = newc; - s++; - } - } -} - - -/******************************************************************* -skip past some strings in a buffer -********************************************************************/ -char *skip_string(char *buf,size_t n) -{ - while (n--) - buf += strlen(buf) + 1; - return(buf); -} - -/******************************************************************* - Count the number of characters in a string. Normally this will - be the same as the number of bytes in a string for single byte strings, - but will be different for multibyte. - 16.oct.98, jdblair@cobaltnet.com. -********************************************************************/ - -size_t str_charnum(const char *s) -{ - size_t len = 0; - - while (*s != '\0') { - int skip = skip_multibyte_char(*s); - s += (skip ? skip : 1); - len++; - } - return len; -} - -/******************************************************************* -trim the specified elements off the front and back of a string -********************************************************************/ - -BOOL trim_string(char *s,const char *front,const char *back) -{ - BOOL ret = False; - size_t front_len = (front && *front) ? strlen(front) : 0; - size_t back_len = (back && *back) ? strlen(back) : 0; - size_t s_len; - - while (front_len && strncmp(s, front, front_len) == 0) - { - char *p = s; - ret = True; - while (1) - { - if (!(*p = p[front_len])) - break; - p++; - } - } - - /* - * We split out the multibyte code page - * case here for speed purposes. Under a - * multibyte code page we need to walk the - * string forwards only and multiple times. - * Thanks to John Blair for finding this - * one. JRA. - */ - - if(back_len) - { - if(!is_multibyte_codepage()) - { - s_len = strlen(s); - while ((s_len >= back_len) && - (strncmp(s + s_len - back_len, back, back_len)==0)) - { - ret = True; - s[s_len - back_len] = '\0'; - s_len = strlen(s); - } - } - else - { - - /* - * Multibyte code page case. - * Keep going through the string, trying - * to match the 'back' string with the end - * of the string. If we get a match, truncate - * 'back' off the end of the string and - * go through the string again from the - * start. Keep doing this until we have - * gone through the string with no match - * at the string end. - */ - - size_t mb_back_len = str_charnum(back); - size_t mb_s_len = str_charnum(s); - - while(mb_s_len >= mb_back_len) - { - size_t charcount = 0; - char *mbp = s; - - while(charcount < (mb_s_len - mb_back_len)) - { - size_t skip = skip_multibyte_char(*mbp); - mbp += (skip ? skip : 1); - charcount++; - } - - /* - * mbp now points at mb_back_len multibyte - * characters from the end of s. - */ - - if(strcmp(mbp, back) == 0) - { - ret = True; - *mbp = '\0'; - mb_s_len = str_charnum(s); - mbp = s; - } - else - break; - } /* end while mb_s_len... */ - } /* end else .. */ - } /* end if back_len .. */ - - return(ret); -} - -#if 0 -/**************************************************************************** -does a string have any uppercase chars in it? -****************************************************************************/ -BOOL strhasupper(const char *s) -{ - while (*s) - { -#if !defined(KANJI_WIN95_COMPATIBILITY) - /* - * For completeness we should put in equivalent code for code pages - * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but - * doubt anyone wants Samba to behave differently from Win95 and WinNT - * here. They both treat full width ascii characters as case senstive - * filenames (ie. they don't do the work we do here). - * JRA. - */ - - if(lp_client_code_page() == KANJI_CODEPAGE) - { - /* Win95 treats full width ascii characters as case sensitive. */ - if (is_shift_jis (*s)) - s += 2; - else if (is_kana (*s)) - s++; - else - { - if (isupper(*s)) - return(True); - s++; - } - } - else -#endif /* KANJI_WIN95_COMPATIBILITY */ - { - size_t skip = skip_multibyte_char( *s ); - if( skip != 0 ) - s += skip; - else { - if (isupper(*s)) - return(True); - s++; - } - } - } - return(False); -} - - -/**************************************************************************** -does a string have any lowercase chars in it? -****************************************************************************/ -BOOL strhaslower(const char *s) -{ - while (*s) - { -#if !defined(KANJI_WIN95_COMPATIBILITY) - /* - * For completeness we should put in equivalent code for code pages - * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but - * doubt anyone wants Samba to behave differently from Win95 and WinNT - * here. They both treat full width ascii characters as case senstive - * filenames (ie. they don't do the work we do here). - * JRA. - */ - - if(lp_client_code_page() == KANJI_CODEPAGE) - { - /* Win95 treats full width ascii characters as case sensitive. */ - if (is_shift_jis (*s)) - { - if (is_sj_upper (s[0], s[1])) - return(True); - if (is_sj_lower (s[0], s[1])) - return (True); - s += 2; - } - else if (is_kana (*s)) - { - s++; - } - else - { - if (islower(*s)) - return(True); - s++; - } - } - else -#endif /* KANJI_WIN95_COMPATIBILITY */ - { - size_t skip = skip_multibyte_char( *s ); - if( skip != 0 ) - s += skip; - else { - if (islower(*s)) - return(True); - s++; - } - } - } - return(False); -} -#endif /*0 */ - -/**************************************************************************** -find the number of chars in a string -****************************************************************************/ -size_t count_chars(const char *s,char c) -{ - size_t count=0; - -#if !defined(KANJI_WIN95_COMPATIBILITY) - /* - * For completeness we should put in equivalent code for code pages - * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but - * doubt anyone wants Samba to behave differently from Win95 and WinNT - * here. They both treat full width ascii characters as case senstive - * filenames (ie. they don't do the work we do here). - * JRA. - */ - - if(lp_client_code_page() == KANJI_CODEPAGE) - { - /* Win95 treats full width ascii characters as case sensitive. */ - while (*s) - { - if (is_shift_jis (*s)) - s += 2; - else - { - if (*s == c) - count++; - s++; - } - } - } - else -#endif /* KANJI_WIN95_COMPATIBILITY */ - { - while (*s) - { - size_t skip = skip_multibyte_char( *s ); - if( skip != 0 ) - s += skip; - else { - if (*s == c) - count++; - s++; - } - } - } - return(count); -} - - - -/******************************************************************* -safe string copy into a known length string. maxlength does not -include the terminating zero. -********************************************************************/ -char *safe_strcpy(char *dest,const char *src, size_t maxlength) -{ - size_t len; - - if (!dest) { - DEBUG(0,("ERROR: NULL dest in safe_strcpy\n")); - return NULL; - } - - if (!src) { - *dest = 0; - return dest; - } - - len = strlen(src); - - if (len > maxlength) { - DEBUG(0,("ERROR: string overflow by %d in safe_strcpy [%.50s]\n", - (int)(len-maxlength), src)); - len = maxlength; - } - - memcpy(dest, src, len); - dest[len] = 0; - return dest; -} - -/******************************************************************* -safe string cat into a string. maxlength does not -include the terminating zero. -********************************************************************/ -char *safe_strcat(char *dest, const char *src, size_t maxlength) -{ - size_t src_len, dest_len; - - if (!dest) { - DEBUG(0,("ERROR: NULL dest in safe_strcat\n")); - return NULL; - } - - if (!src) { - return dest; - } - - src_len = strlen(src); - dest_len = strlen(dest); - - if (src_len + dest_len > maxlength) { - DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n", - (int)(src_len + dest_len - maxlength), src)); - src_len = maxlength - dest_len; - } - - memcpy(&dest[dest_len], src, src_len); - dest[dest_len + src_len] = 0; - return dest; -} - -/**************************************************************************** -this is a safer strcpy(), meant to prevent core dumps when nasty things happen -****************************************************************************/ -char *StrCpy(char *dest,const char *src) -{ - char *d = dest; - - /* I don't want to get lazy with these ... */ - SMB_ASSERT(dest && src); - - if (!dest) return(NULL); - if (!src) { - *dest = 0; - return(dest); - } - while ((*d++ = *src++)) ; - return(dest); -} - -/**************************************************************************** -like strncpy but always null terminates. Make sure there is room! -****************************************************************************/ -char *StrnCpy(char *dest,const char *src,size_t n) -{ - char *d = dest; - if (!dest) return(NULL); - if (!src) { - *dest = 0; - return(dest); - } - while (n-- && (*d++ = *src++)) ; - *d = 0; - return(dest); -} - -#if 0 -/**************************************************************************** -like strncpy but copies up to the character marker. always null terminates. -returns a pointer to the character marker in the source string (src). -****************************************************************************/ -char *strncpyn(char *dest, const char *src,size_t n, char c) -{ - char *p; - size_t str_len; - - p = strchr(src, c); - if (p == NULL) - { - DEBUG(5, ("strncpyn: separator character (%c) not found\n", c)); - return NULL; - } - - str_len = PTR_DIFF(p, src); - strncpy(dest, src, MIN(n, str_len)); - dest[str_len] = '\0'; - - return p; -} - - -/************************************************************* - Routine to get hex characters and turn them into a 16 byte array. - the array can be variable length, and any non-hex-numeric - characters are skipped. "0xnn" or "0Xnn" is specially catered - for. - - valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n" - -**************************************************************/ -size_t strhex_to_str(char *p, size_t len, const char *strhex) -{ - size_t i; - size_t num_chars = 0; - unsigned char lonybble, hinybble; - char *hexchars = "0123456789ABCDEF"; - char *p1 = NULL, *p2 = NULL; - - for (i = 0; i < len && strhex[i] != 0; i++) - { - if (strnequal(hexchars, "0x", 2)) - { - i++; /* skip two chars */ - continue; - } - - if (!(p1 = strchr(hexchars, toupper(strhex[i])))) - { - break; - } - - i++; /* next hex digit */ - - if (!(p2 = strchr(hexchars, toupper(strhex[i])))) - { - break; - } - - /* get the two nybbles */ - hinybble = PTR_DIFF(p1, hexchars); - lonybble = PTR_DIFF(p2, hexchars); - - p[num_chars] = (hinybble << 4) | lonybble; - num_chars++; - - p1 = NULL; - p2 = NULL; - } - return num_chars; -} - -/**************************************************************************** -check if a string is part of a list -****************************************************************************/ -BOOL in_list(char *s,char *list,BOOL casesensitive) -{ - pstring tok; - char *p=list; - - if (!list) return(False); - - while (next_token(&p,tok,LIST_SEP,sizeof(tok))) { - if (casesensitive) { - if (strcmp(tok,s) == 0) - return(True); - } else { - if (StrCaseCmp(tok,s) == 0) - return(True); - } - } - return(False); -} -#endif /*0 */ - -/* this is used to prevent lots of mallocs of size 1 */ -static char *null_string = NULL; - -/**************************************************************************** -set a string value, allocing the space for the string -****************************************************************************/ -BOOL string_init(char **dest,const char *src) -{ - size_t l; - if (!src) - src = ""; - - l = strlen(src); - - if (l == 0) - { - if (!null_string) { - if((null_string = (char *)malloc(1)) == NULL) { - DEBUG(0,("string_init: malloc fail for null_string.\n")); - return False; - } - *null_string = 0; - } - *dest = null_string; - } - else - { - (*dest) = (char *)malloc(l+1); - if ((*dest) == NULL) { - DEBUG(0,("Out of memory in string_init\n")); - return False; - } - - pstrcpy(*dest,src); - } - return(True); -} - -/**************************************************************************** -free a string value -****************************************************************************/ -void string_free(char **s) -{ - if (!s || !(*s)) return; - if (*s == null_string) - *s = NULL; - if (*s) free(*s); - *s = NULL; -} - -/**************************************************************************** -set a string value, allocing the space for the string, and deallocating any -existing space -****************************************************************************/ -BOOL string_set(char **dest,const char *src) -{ - string_free(dest); - - return(string_init(dest,src)); -} - - -/**************************************************************************** -substitute a string for a pattern in another string. Make sure there is -enough room! - -This routine looks for pattern in s and replaces it with -insert. It may do multiple replacements. - -any of " ; ' or ` in the insert string are replaced with _ -****************************************************************************/ -void string_sub(char *s,const char *pattern,const char *insert) -{ - char *p; - size_t ls,lp,li, i; - - if (!insert || !pattern || !s) return; - - ls = strlen(s); - lp = strlen(pattern); - li = strlen(insert); - - if (!*pattern) return; - - while (lp <= ls && (p = strstr(s,pattern))) { - memmove(p+li,p+lp,ls + 1 - (PTR_DIFF(p,s) + lp)); - for (i=0;i. + */ + +#include "includes.h" + +extern int DEBUGLEVEL; + +static char *last_ptr = NULL; + +void +set_first_token (char *ptr) +{ + last_ptr = ptr; +} + +/**************************************************************************** + Get the next token from a string, return False if none found + handles double-quotes. +Based on a routine by GJC@VILLAGE.COM. +Extensively modified by Andrew.Tridgell@anu.edu.au +****************************************************************************/ +BOOL +next_token (char **ptr, char *buff, const char *sep, size_t bufsize) +{ + char *s; + BOOL quoted; + size_t len = 1; + + if (!ptr) + ptr = &last_ptr; + if (!ptr) + return (False); + + s = *ptr; + + /* default to simple separators */ + if (!sep) + sep = " \t\n\r"; + + /* find the first non sep char */ + while (*s && strchr (sep, *s)) + s++; + + /* nothing left? */ + if (!*s) + return (False); + + /* copy over the token */ + for (quoted = False; len < bufsize && *s && (quoted || !strchr (sep, *s)); s++) + { + if (*s == '\"') + { + quoted = !quoted; + } + else + { + len++; + *buff++ = *s; + } + } + + *ptr = (*s) ? s + 1 : s; + *buff = 0; + last_ptr = *ptr; + + return (True); +} + +#if 0 +/**************************************************************************** +Convert list of tokens to array; dependent on above routine. +Uses last_ptr from above - bit of a hack. +****************************************************************************/ +char ** +toktocliplist (int *ctok, char *sep) +{ + char *s = last_ptr; + int ictok = 0; + char **ret, **iret; + + if (!sep) + sep = " \t\n\r"; + + while (*s && strchr (sep, *s)) + s++; + + /* nothing left? */ + if (!*s) + return (NULL); + + do + { + ictok++; + while (*s && (!strchr (sep, *s))) + s++; + while (*s && strchr (sep, *s)) + *s++ = 0; + } + while (*s); + + *ctok = ictok; + s = last_ptr; + + if (!(ret = iret = malloc (ictok * sizeof (char *)))) + return NULL; + + while (ictok--) + { + *iret++ = s; + while (*s++); + while (!*s) + s++; + } + + return ret; +} +#endif /*0 */ + +/******************************************************************* + case insensitive string compararison +********************************************************************/ +int +StrCaseCmp (const char *s, const char *t) +{ + /* compare until we run out of string, either t or s, or find a difference */ + /* We *must* use toupper rather than tolower here due to the + asynchronous upper to lower mapping. + */ +#if !defined(KANJI_WIN95_COMPATIBILITY) + /* + * For completeness we should put in equivalent code for code pages + * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but + * doubt anyone wants Samba to behave differently from Win95 and WinNT + * here. They both treat full width ascii characters as case senstive + * filenames (ie. they don't do the work we do here). + * JRA. + */ + + if (lp_client_code_page () == KANJI_CODEPAGE) + { + /* Win95 treats full width ascii characters as case sensitive. */ + int diff; + for (;;) + { + if (!*s || !*t) + return toupper (*s) - toupper (*t); + else if (is_sj_alph (*s) && is_sj_alph (*t)) + { + diff = sj_toupper2 (*(s + 1)) - sj_toupper2 (*(t + 1)); + if (diff) + return diff; + s += 2; + t += 2; + } + else if (is_shift_jis (*s) && is_shift_jis (*t)) + { + diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t); + if (diff) + return diff; + diff = ((int) (unsigned char) *(s + 1)) - ((int) (unsigned char) *(t + 1)); + if (diff) + return diff; + s += 2; + t += 2; + } + else if (is_shift_jis (*s)) + return 1; + else if (is_shift_jis (*t)) + return -1; + else + { + diff = toupper (*s) - toupper (*t); + if (diff) + return diff; + s++; + t++; + } + } + } + else +#endif /* KANJI_WIN95_COMPATIBILITY */ + { + while (*s && *t && toupper (*s) == toupper (*t)) + { + s++; + t++; + } + + return (toupper (*s) - toupper (*t)); + } +} + +/******************************************************************* + case insensitive string compararison, length limited +********************************************************************/ +int +StrnCaseCmp (const char *s, const char *t, size_t n) +{ + /* compare until we run out of string, either t or s, or chars */ + /* We *must* use toupper rather than tolower here due to the + asynchronous upper to lower mapping. + */ +#if !defined(KANJI_WIN95_COMPATIBILITY) + /* + * For completeness we should put in equivalent code for code pages + * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but + * doubt anyone wants Samba to behave differently from Win95 and WinNT + * here. They both treat full width ascii characters as case senstive + * filenames (ie. they don't do the work we do here). + * JRA. + */ + + if (lp_client_code_page () == KANJI_CODEPAGE) + { + /* Win95 treats full width ascii characters as case sensitive. */ + int diff; + for (; n > 0;) + { + if (!*s || !*t) + return toupper (*s) - toupper (*t); + else if (is_sj_alph (*s) && is_sj_alph (*t)) + { + diff = sj_toupper2 (*(s + 1)) - sj_toupper2 (*(t + 1)); + if (diff) + return diff; + s += 2; + t += 2; + n -= 2; + } + else if (is_shift_jis (*s) && is_shift_jis (*t)) + { + diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t); + if (diff) + return diff; + diff = ((int) (unsigned char) *(s + 1)) - ((int) (unsigned char) *(t + 1)); + if (diff) + return diff; + s += 2; + t += 2; + n -= 2; + } + else if (is_shift_jis (*s)) + return 1; + else if (is_shift_jis (*t)) + return -1; + else + { + diff = toupper (*s) - toupper (*t); + if (diff) + return diff; + s++; + t++; + n--; + } + } + return 0; + } + else +#endif /* KANJI_WIN95_COMPATIBILITY */ + { + while (n && *s && *t && toupper (*s) == toupper (*t)) + { + s++; + t++; + n--; + } + + /* not run out of chars - strings are different lengths */ + if (n) + return (toupper (*s) - toupper (*t)); + + /* identical up to where we run out of chars, + and strings are same length */ + return (0); + } +} + +/******************************************************************* + compare 2 strings +********************************************************************/ +BOOL +strequal (const char *s1, const char *s2) +{ + if (s1 == s2) + return (True); + if (!s1 || !s2) + return (False); + + return (StrCaseCmp (s1, s2) == 0); +} + +/******************************************************************* + compare 2 strings up to and including the nth char. + ******************************************************************/ +BOOL +strnequal (const char *s1, const char *s2, size_t n) +{ + if (s1 == s2) + return (True); + if (!s1 || !s2 || !n) + return (False); + + return (StrnCaseCmp (s1, s2, n) == 0); +} + +/******************************************************************* + compare 2 strings (case sensitive) +********************************************************************/ +BOOL +strcsequal (const char *s1, const char *s2) +{ + if (s1 == s2) + return (True); + if (!s1 || !s2) + return (False); + + return (strcmp (s1, s2) == 0); +} + + +/******************************************************************* + convert a string to lower case +********************************************************************/ +void +strlower (char *s) +{ + while (*s) + { +#if !defined(KANJI_WIN95_COMPATIBILITY) + /* + * For completeness we should put in equivalent code for code pages + * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but + * doubt anyone wants Samba to behave differently from Win95 and WinNT + * here. They both treat full width ascii characters as case senstive + * filenames (ie. they don't do the work we do here). + * JRA. + */ + + if (lp_client_code_page () == KANJI_CODEPAGE) + { + /* Win95 treats full width ascii characters as case sensitive. */ + if (is_shift_jis (*s)) + { + if (is_sj_upper (s[0], s[1])) + s[1] = sj_tolower2 (s[1]); + s += 2; + } + else if (is_kana (*s)) + { + s++; + } + else + { + if (isupper (*s)) + *s = tolower (*s); + s++; + } + } + else +#endif /* KANJI_WIN95_COMPATIBILITY */ + { + size_t skip = skip_multibyte_char (*s); + if (skip != 0) + s += skip; + else + { + if (isupper (*s)) + *s = tolower (*s); + s++; + } + } + } +} + +/******************************************************************* + convert a string to upper case +********************************************************************/ +void +strupper (char *s) +{ + while (*s) + { +#if !defined(KANJI_WIN95_COMPATIBILITY) + /* + * For completeness we should put in equivalent code for code pages + * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but + * doubt anyone wants Samba to behave differently from Win95 and WinNT + * here. They both treat full width ascii characters as case senstive + * filenames (ie. they don't do the work we do here). + * JRA. + */ + + if (lp_client_code_page () == KANJI_CODEPAGE) + { + /* Win95 treats full width ascii characters as case sensitive. */ + if (is_shift_jis (*s)) + { + if (is_sj_lower (s[0], s[1])) + s[1] = sj_toupper2 (s[1]); + s += 2; + } + else if (is_kana (*s)) + { + s++; + } + else + { + if (islower (*s)) + *s = toupper (*s); + s++; + } + } + else +#endif /* KANJI_WIN95_COMPATIBILITY */ + { + size_t skip = skip_multibyte_char (*s); + if (skip != 0) + s += skip; + else + { + if (islower (*s)) + *s = toupper (*s); + s++; + } + } + } +} + +#if 0 +/******************************************************************* + convert a string to "normal" form +********************************************************************/ +void +strnorm (char *s) +{ + extern int case_default; + if (case_default == CASE_UPPER) + strupper (s); + else + strlower (s); +} + +/******************************************************************* +check if a string is in "normal" case +********************************************************************/ +BOOL +strisnormal (char *s) +{ + extern int case_default; + if (case_default == CASE_UPPER) + return (!strhaslower (s)); + + return (!strhasupper (s)); +} +#endif /* 0 */ + +/**************************************************************************** + string replace +****************************************************************************/ +void +string_replace (char *s, char oldc, char newc) +{ + size_t skip; + while (*s) + { + skip = skip_multibyte_char (*s); + if (skip != 0) + s += skip; + else + { + if (oldc == *s) + *s = newc; + s++; + } + } +} + + +/******************************************************************* +skip past some strings in a buffer +********************************************************************/ +char * +skip_string (char *buf, size_t n) +{ + while (n--) + buf += strlen (buf) + 1; + return (buf); +} + +/******************************************************************* + Count the number of characters in a string. Normally this will + be the same as the number of bytes in a string for single byte strings, + but will be different for multibyte. + 16.oct.98, jdblair@cobaltnet.com. +********************************************************************/ + +size_t +str_charnum (const char *s) +{ + size_t len = 0; + + while (*s != '\0') + { + int skip = skip_multibyte_char (*s); + s += (skip ? skip : 1); + len++; + } + return len; +} + +/******************************************************************* +trim the specified elements off the front and back of a string +********************************************************************/ + +BOOL +trim_string (char *s, const char *front, const char *back) +{ + BOOL ret = False; + size_t front_len = (front && *front) ? strlen (front) : 0; + size_t back_len = (back && *back) ? strlen (back) : 0; + size_t s_len; + + while (front_len && strncmp (s, front, front_len) == 0) + { + char *p = s; + ret = True; + while (1) + { + if (!(*p = p[front_len])) + break; + p++; + } + } + + /* + * We split out the multibyte code page + * case here for speed purposes. Under a + * multibyte code page we need to walk the + * string forwards only and multiple times. + * Thanks to John Blair for finding this + * one. JRA. + */ + + if (back_len) + { + if (!is_multibyte_codepage ()) + { + s_len = strlen (s); + while ((s_len >= back_len) && (strncmp (s + s_len - back_len, back, back_len) == 0)) + { + ret = True; + s[s_len - back_len] = '\0'; + s_len = strlen (s); + } + } + else + { + + /* + * Multibyte code page case. + * Keep going through the string, trying + * to match the 'back' string with the end + * of the string. If we get a match, truncate + * 'back' off the end of the string and + * go through the string again from the + * start. Keep doing this until we have + * gone through the string with no match + * at the string end. + */ + + size_t mb_back_len = str_charnum (back); + size_t mb_s_len = str_charnum (s); + + while (mb_s_len >= mb_back_len) + { + size_t charcount = 0; + char *mbp = s; + + while (charcount < (mb_s_len - mb_back_len)) + { + size_t skip = skip_multibyte_char (*mbp); + mbp += (skip ? skip : 1); + charcount++; + } + + /* + * mbp now points at mb_back_len multibyte + * characters from the end of s. + */ + + if (strcmp (mbp, back) == 0) + { + ret = True; + *mbp = '\0'; + mb_s_len = str_charnum (s); + mbp = s; + } + else + break; + } /* end while mb_s_len... */ + } /* end else .. */ + } /* end if back_len .. */ + + return (ret); +} + +#if 0 +/**************************************************************************** +does a string have any uppercase chars in it? +****************************************************************************/ +BOOL +strhasupper (const char *s) +{ + while (*s) + { +#if !defined(KANJI_WIN95_COMPATIBILITY) + /* + * For completeness we should put in equivalent code for code pages + * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but + * doubt anyone wants Samba to behave differently from Win95 and WinNT + * here. They both treat full width ascii characters as case senstive + * filenames (ie. they don't do the work we do here). + * JRA. + */ + + if (lp_client_code_page () == KANJI_CODEPAGE) + { + /* Win95 treats full width ascii characters as case sensitive. */ + if (is_shift_jis (*s)) + s += 2; + else if (is_kana (*s)) + s++; + else + { + if (isupper (*s)) + return (True); + s++; + } + } + else +#endif /* KANJI_WIN95_COMPATIBILITY */ + { + size_t skip = skip_multibyte_char (*s); + if (skip != 0) + s += skip; + else + { + if (isupper (*s)) + return (True); + s++; + } + } + } + return (False); +} + + +/**************************************************************************** +does a string have any lowercase chars in it? +****************************************************************************/ +BOOL +strhaslower (const char *s) +{ + while (*s) + { +#if !defined(KANJI_WIN95_COMPATIBILITY) + /* + * For completeness we should put in equivalent code for code pages + * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but + * doubt anyone wants Samba to behave differently from Win95 and WinNT + * here. They both treat full width ascii characters as case senstive + * filenames (ie. they don't do the work we do here). + * JRA. + */ + + if (lp_client_code_page () == KANJI_CODEPAGE) + { + /* Win95 treats full width ascii characters as case sensitive. */ + if (is_shift_jis (*s)) + { + if (is_sj_upper (s[0], s[1])) + return (True); + if (is_sj_lower (s[0], s[1])) + return (True); + s += 2; + } + else if (is_kana (*s)) + { + s++; + } + else + { + if (islower (*s)) + return (True); + s++; + } + } + else +#endif /* KANJI_WIN95_COMPATIBILITY */ + { + size_t skip = skip_multibyte_char (*s); + if (skip != 0) + s += skip; + else + { + if (islower (*s)) + return (True); + s++; + } + } + } + return (False); +} +#endif /*0 */ + +/**************************************************************************** +find the number of chars in a string +****************************************************************************/ +size_t +count_chars (const char *s, char c) +{ + size_t count = 0; + +#if !defined(KANJI_WIN95_COMPATIBILITY) + /* + * For completeness we should put in equivalent code for code pages + * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but + * doubt anyone wants Samba to behave differently from Win95 and WinNT + * here. They both treat full width ascii characters as case senstive + * filenames (ie. they don't do the work we do here). + * JRA. + */ + + if (lp_client_code_page () == KANJI_CODEPAGE) + { + /* Win95 treats full width ascii characters as case sensitive. */ + while (*s) + { + if (is_shift_jis (*s)) + s += 2; + else + { + if (*s == c) + count++; + s++; + } + } + } + else +#endif /* KANJI_WIN95_COMPATIBILITY */ + { + while (*s) + { + size_t skip = skip_multibyte_char (*s); + if (skip != 0) + s += skip; + else + { + if (*s == c) + count++; + s++; + } + } + } + return (count); +} + + + +/******************************************************************* +safe string copy into a known length string. maxlength does not +include the terminating zero. +********************************************************************/ +char * +safe_strcpy (char *dest, const char *src, size_t maxlength) +{ + size_t len; + + if (!dest) + { + DEBUG (0, ("ERROR: NULL dest in safe_strcpy\n")); + return NULL; + } + + if (!src) + { + *dest = 0; + return dest; + } + + len = strlen (src); + + if (len > maxlength) + { + DEBUG (0, ("ERROR: string overflow by %d in safe_strcpy [%.50s]\n", + (int) (len - maxlength), src)); + len = maxlength; + } + + memcpy (dest, src, len); + dest[len] = 0; + return dest; +} + +/******************************************************************* +safe string cat into a string. maxlength does not +include the terminating zero. +********************************************************************/ +char * +safe_strcat (char *dest, const char *src, size_t maxlength) +{ + size_t src_len, dest_len; + + if (!dest) + { + DEBUG (0, ("ERROR: NULL dest in safe_strcat\n")); + return NULL; + } + + if (!src) + { + return dest; + } + + src_len = strlen (src); + dest_len = strlen (dest); + + if (src_len + dest_len > maxlength) + { + DEBUG (0, ("ERROR: string overflow by %d in safe_strcat [%.50s]\n", + (int) (src_len + dest_len - maxlength), src)); + src_len = maxlength - dest_len; + } + + memcpy (&dest[dest_len], src, src_len); + dest[dest_len + src_len] = 0; + return dest; +} + +/**************************************************************************** +this is a safer strcpy(), meant to prevent core dumps when nasty things happen +****************************************************************************/ +char * +StrCpy (char *dest, const char *src) +{ + char *d = dest; + + /* I don't want to get lazy with these ... */ + SMB_ASSERT (dest && src); + + if (!dest) + return (NULL); + if (!src) + { + *dest = 0; + return (dest); + } + while ((*d++ = *src++)); + return (dest); +} + +/**************************************************************************** +like strncpy but always null terminates. Make sure there is room! +****************************************************************************/ +char * +StrnCpy (char *dest, const char *src, size_t n) +{ + char *d = dest; + if (!dest) + return (NULL); + if (!src) + { + *dest = 0; + return (dest); + } + while (n-- && (*d++ = *src++)); + *d = 0; + return (dest); +} + +#if 0 +/**************************************************************************** +like strncpy but copies up to the character marker. always null terminates. +returns a pointer to the character marker in the source string (src). +****************************************************************************/ +char * +strncpyn (char *dest, const char *src, size_t n, char c) +{ + char *p; + size_t str_len; + + p = strchr (src, c); + if (p == NULL) + { + DEBUG (5, ("strncpyn: separator character (%c) not found\n", c)); + return NULL; + } + + str_len = PTR_DIFF (p, src); + strncpy (dest, src, MIN (n, str_len)); + dest[str_len] = '\0'; + + return p; +} + + +/************************************************************* + Routine to get hex characters and turn them into a 16 byte array. + the array can be variable length, and any non-hex-numeric + characters are skipped. "0xnn" or "0Xnn" is specially catered + for. + + valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n" + +**************************************************************/ +size_t +strhex_to_str (char *p, size_t len, const char *strhex) +{ + size_t i; + size_t num_chars = 0; + unsigned char lonybble, hinybble; + char *hexchars = "0123456789ABCDEF"; + char *p1 = NULL, *p2 = NULL; + + for (i = 0; i < len && strhex[i] != 0; i++) + { + if (strnequal (hexchars, "0x", 2)) + { + i++; /* skip two chars */ + continue; + } + + if (!(p1 = strchr (hexchars, toupper (strhex[i])))) + { + break; + } + + i++; /* next hex digit */ + + if (!(p2 = strchr (hexchars, toupper (strhex[i])))) + { + break; + } + + /* get the two nybbles */ + hinybble = PTR_DIFF (p1, hexchars); + lonybble = PTR_DIFF (p2, hexchars); + + p[num_chars] = (hinybble << 4) | lonybble; + num_chars++; + + p1 = NULL; + p2 = NULL; + } + return num_chars; +} + +/**************************************************************************** +check if a string is part of a list +****************************************************************************/ +BOOL +in_list (char *s, char *list, BOOL casesensitive) +{ + pstring tok; + char *p = list; + + if (!list) + return (False); + + while (next_token (&p, tok, LIST_SEP, sizeof (tok))) + { + if (casesensitive) + { + if (strcmp (tok, s) == 0) + return (True); + } + else + { + if (StrCaseCmp (tok, s) == 0) + return (True); + } + } + return (False); +} +#endif /*0 */ + +/* this is used to prevent lots of mallocs of size 1 */ +static char *null_string = NULL; + +/**************************************************************************** +set a string value, allocing the space for the string +****************************************************************************/ +BOOL +string_init (char **dest, const char *src) +{ + size_t l; + if (!src) + src = ""; + + l = strlen (src); + + if (l == 0) + { + if (!null_string) + { + if ((null_string = (char *) malloc (1)) == NULL) + { + DEBUG (0, ("string_init: malloc fail for null_string.\n")); + return False; + } + *null_string = 0; + } + *dest = null_string; + } + else + { + (*dest) = (char *) malloc (l + 1); + if ((*dest) == NULL) + { + DEBUG (0, ("Out of memory in string_init\n")); + return False; + } + + pstrcpy (*dest, src); + } + return (True); +} + +/**************************************************************************** +free a string value +****************************************************************************/ +void +string_free (char **s) +{ + if (!s || !(*s)) + return; + if (*s == null_string) + *s = NULL; + if (*s) + free (*s); + *s = NULL; +} + +/**************************************************************************** +set a string value, allocing the space for the string, and deallocating any +existing space +****************************************************************************/ +BOOL +string_set (char **dest, const char *src) +{ + string_free (dest); + + return (string_init (dest, src)); +} + + +/**************************************************************************** +substitute a string for a pattern in another string. Make sure there is +enough room! + +This routine looks for pattern in s and replaces it with +insert. It may do multiple replacements. + +any of " ; ' or ` in the insert string are replaced with _ +****************************************************************************/ +void +string_sub (char *s, const char *pattern, const char *insert) +{ + char *p; + size_t ls, lp, li, i; + + if (!insert || !pattern || !s) + return; + + ls = strlen (s); + lp = strlen (pattern); + li = strlen (insert); + + if (!*pattern) + return; + + while (lp <= ls && (p = strstr (s, pattern))) + { + memmove (p + li, p + lp, ls + 1 - (PTR_DIFF (p, s) + lp)); + for (i = 0; i < li; i++) + { + switch (insert[i]) + { + case '`': + case '"': + case '\'': + case ';': + p[i] = '_'; + break; + default: + p[i] = insert[i]; + } + } + s = p + li; + ls += (li - lp); + } +} + +#if 0 +/**************************************************************************** +similar to string_sub() but allows for any character to be substituted. +Use with caution! +****************************************************************************/ +void +all_string_sub (char *s, const char *pattern, const char *insert) +{ + char *p; + size_t ls, lp, li; + + if (!insert || !pattern || !s) + return; + + ls = strlen (s); + lp = strlen (pattern); + li = strlen (insert); + + if (!*pattern) + return; + + while (lp <= ls && (p = strstr (s, pattern))) + { + memmove (p + li, p + lp, ls + 1 - (PTR_DIFF (p, s) + lp)); + memcpy (p, insert, li); + s = p + li; + ls += (li - lp); + } +} + + +/**************************************************************************** + splits out the front and back at a separator. +****************************************************************************/ +void +split_at_last_component (char *path, char *front, char sep, char *back) +{ + char *p = strrchr (path, sep); + + if (p != NULL) + { + *p = 0; + } + if (front != NULL) + { + pstrcpy (front, path); + } + if (p != NULL) + { + if (back != NULL) + { + pstrcpy (back, p + 1); + } + *p = '\\'; + } + else + { + if (back != NULL) + { + back[0] = 0; + } + } +} +#endif /*0 */ diff --git a/src/vfs/smbfs/helpers/libsmb/clientgen.c b/src/vfs/smbfs/helpers/libsmb/clientgen.c dissimilarity index 80% index cb57a20aa..f293ba389 100644 --- a/src/vfs/smbfs/helpers/libsmb/clientgen.c +++ b/src/vfs/smbfs/helpers/libsmb/clientgen.c @@ -1,2856 +1,3090 @@ -/* - Unix SMB/Netbios implementation. - Version 1.9. - SMB client generic functions - - Copyright (C) Andrew Tridgell 1994-1998 - - Copyright (C) 2011 - The Free Software Foundation, Inc. - - This file is part of the Midnight Commander. - - The Midnight Commander is free software: you can redistribute it - and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of the License, - or (at your option) any later version. - - The Midnight Commander is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#define NO_SYSLOG - -#include "includes.h" -#include "trans2.h" - - -extern int DEBUGLEVEL; -extern pstring user_socket_options; - -/* - * Change the port number used to call on - */ -int cli_set_port(struct cli_state *cli, int port) -{ - if (port > 0) - cli -> port = port; - - return cli -> port; -} - -/**************************************************************************** -recv an smb -****************************************************************************/ -static BOOL cli_receive_smb(struct cli_state *cli) -{ - return client_receive_smb(cli->fd,cli->inbuf,cli->timeout); -} - -/**************************************************************************** - send an smb to a fd and re-establish if necessary -****************************************************************************/ -static BOOL cli_send_smb(struct cli_state *cli) -{ - size_t len; - size_t nwritten=0; - ssize_t ret; - BOOL reestablished=False; - - len = smb_len(cli->outbuf) + 4; - - while (nwritten < len) { - ret = write_socket(cli->fd,cli->outbuf+nwritten,len - nwritten); - if (ret <= 0 && errno == EPIPE && !reestablished) { - if (cli_reestablish_connection(cli)) { - reestablished = True; - nwritten=0; - continue; - } - } - if (ret <= 0) { - DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n", - (int)len,(int)ret)); - close_sockets(); - exit(1); - } - nwritten += ret; - } - - return True; -} - -/***************************************************** - RAP error codes - a small start but will be extended. -*******************************************************/ - -struct -{ - int err; - const char *message; -} const rap_errmap[] = -{ - {5, "User has insufficient privilege" }, - {86, "The specified password is invalid" }, - {2226, "Operation only permitted on a Primary Domain Controller" }, - {2242, "The password of this user has expired." }, - {2243, "The password of this user cannot change." }, - {2244, "This password cannot be used now (password history conflict)." }, - {2245, "The password is shorter than required." }, - {2246, "The password of this user is too recent to change."}, - {0, NULL} -}; - -/**************************************************************************** - return a description of an SMB error -****************************************************************************/ -static char *cli_smb_errstr(struct cli_state *cli) -{ - return smb_errstr(cli->inbuf); -} - -/****************************************************** - Return an error message - either an SMB error or a RAP - error. -*******************************************************/ - -char *cli_errstr(struct cli_state *cli) -{ - static fstring error_message; - uint8 errclass; - uint32 errnum; - uint32 nt_rpc_error; - int i; - - /* - * Errors are of three kinds - smb errors, - * dealt with by cli_smb_errstr, NT errors, - * whose code is in cli.nt_error, and rap - * errors, whose error code is in cli.rap_error. - */ - - cli_error(cli, &errclass, &errnum, &nt_rpc_error); - - if (errclass != 0) - { - return cli_smb_errstr(cli); - } - - /* - * Was it an NT error ? - */ - - if (nt_rpc_error) - { - const char *nt_msg = get_nt_error_msg(nt_rpc_error); - - if (nt_msg == NULL) - { - slprintf(error_message, sizeof(fstring) - 1, "NT code %d", nt_rpc_error); - } - else - { - fstrcpy(error_message, nt_msg); - } - - return error_message; - } - - /* - * Must have been a rap error. - */ - - slprintf(error_message, sizeof(error_message) - 1, "code %d", cli->rap_error); - - for (i = 0; rap_errmap[i].message != NULL; i++) - { - if (rap_errmap[i].err == cli->rap_error) - { - fstrcpy( error_message, rap_errmap[i].message); - break; - } - } - - return error_message; -} - -/**************************************************************************** -setup basics in a outgoing packet -****************************************************************************/ -static void cli_setup_packet(struct cli_state *cli) -{ - cli->rap_error = 0; - cli->nt_error = 0; - SSVAL(cli->outbuf,smb_pid,cli->pid); - SSVAL(cli->outbuf,smb_uid,cli->vuid); - SSVAL(cli->outbuf,smb_mid,cli->mid); - if (cli->protocol > PROTOCOL_CORE) { - SCVAL(cli->outbuf,smb_flg,0x8); - SSVAL(cli->outbuf,smb_flg2,0x1); - } -} - -#if 0 -/***************************************************************************** - Convert a character pointer in a cli_call_api() response to a form we can use. - This function contains code to prevent core dumps if the server returns - invalid data. -*****************************************************************************/ -static char *fix_char_ptr(unsigned int datap, unsigned int converter, - char *rdata, int rdrcnt) -{ - if (datap == 0) { /* turn NULL pointers into zero length strings */ - return ""; - } else { - unsigned int offset = datap - converter; - - if (offset >= rdrcnt) { - DEBUG(1,("bad char ptr: datap=%u, converter=%u rdrcnt=%d>", - datap, converter, rdrcnt)); - return ""; - } else { - return &rdata[offset]; - } - } -} -#endif /* 0 */ -/**************************************************************************** - send a SMB trans or trans2 request - ****************************************************************************/ -static BOOL cli_send_trans(struct cli_state *cli, int trans, - const char *name, int pipe_name_len, - int fid, int flags, - uint16 *setup, int lsetup, int msetup, - char *param, int lparam, int mparam, - char *data, int ldata, int mdata) -{ - int i; - int this_ldata,this_lparam; - int tot_data=0,tot_param=0; - char *outdata,*outparam; - char *p; - - this_lparam = MIN(lparam,cli->max_xmit - (500+lsetup*2)); /* hack */ - this_ldata = MIN(ldata,cli->max_xmit - (500+lsetup*2+this_lparam)); - - memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,14+lsetup,0,True); - CVAL(cli->outbuf,smb_com) = trans; - SSVAL(cli->outbuf,smb_tid, cli->cnum); - cli_setup_packet(cli); - - outparam = smb_buf(cli->outbuf)+(trans==SMBtrans ? pipe_name_len+1 : 3); - outdata = outparam+this_lparam; - - /* primary request */ - SSVAL(cli->outbuf,smb_tpscnt,lparam); /* tpscnt */ - SSVAL(cli->outbuf,smb_tdscnt,ldata); /* tdscnt */ - SSVAL(cli->outbuf,smb_mprcnt,mparam); /* mprcnt */ - SSVAL(cli->outbuf,smb_mdrcnt,mdata); /* mdrcnt */ - SCVAL(cli->outbuf,smb_msrcnt,msetup); /* msrcnt */ - SSVAL(cli->outbuf,smb_flags,flags); /* flags */ - SIVAL(cli->outbuf,smb_timeout,0); /* timeout */ - SSVAL(cli->outbuf,smb_pscnt,this_lparam); /* pscnt */ - SSVAL(cli->outbuf,smb_psoff,smb_offset(outparam,cli->outbuf)); /* psoff */ - SSVAL(cli->outbuf,smb_dscnt,this_ldata); /* dscnt */ - SSVAL(cli->outbuf,smb_dsoff,smb_offset(outdata,cli->outbuf)); /* dsoff */ - SCVAL(cli->outbuf,smb_suwcnt,lsetup); /* suwcnt */ - for (i=0;ioutbuf,smb_setup+i*2,setup[i]); - p = smb_buf(cli->outbuf); - if (trans==SMBtrans) { - memcpy(p,name, pipe_name_len + 1); /* name[] */ - } else { - *p++ = 0; /* put in a null smb_name */ - *p++ = 'D'; *p++ = ' '; /* observed in OS/2 */ - } - if (this_lparam) /* param[] */ - memcpy(outparam,param,this_lparam); - if (this_ldata) /* data[] */ - memcpy(outdata,data,this_ldata); - set_message(cli->outbuf,14+lsetup, /* wcnt, bcc */ - PTR_DIFF(outdata+this_ldata,smb_buf(cli->outbuf)),False); - - show_msg(cli->outbuf); - cli_send_smb(cli); - - if (this_ldata < ldata || this_lparam < lparam) { - /* receive interim response */ - if (!cli_receive_smb(cli) || - CVAL(cli->inbuf,smb_rcls) != 0) { - return(False); - } - - tot_data = this_ldata; - tot_param = this_lparam; - - while (tot_data < ldata || tot_param < lparam) { - this_lparam = MIN(lparam-tot_param,cli->max_xmit - 500); /* hack */ - this_ldata = MIN(ldata-tot_data,cli->max_xmit - (500+this_lparam)); - - set_message(cli->outbuf,trans==SMBtrans?8:9,0,True); - CVAL(cli->outbuf,smb_com) = trans==SMBtrans ? SMBtranss : SMBtranss2; - - outparam = smb_buf(cli->outbuf); - outdata = outparam+this_lparam; - - /* secondary request */ - SSVAL(cli->outbuf,smb_tpscnt,lparam); /* tpscnt */ - SSVAL(cli->outbuf,smb_tdscnt,ldata); /* tdscnt */ - SSVAL(cli->outbuf,smb_spscnt,this_lparam); /* pscnt */ - SSVAL(cli->outbuf,smb_spsoff,smb_offset(outparam,cli->outbuf)); /* psoff */ - SSVAL(cli->outbuf,smb_spsdisp,tot_param); /* psdisp */ - SSVAL(cli->outbuf,smb_sdscnt,this_ldata); /* dscnt */ - SSVAL(cli->outbuf,smb_sdsoff,smb_offset(outdata,cli->outbuf)); /* dsoff */ - SSVAL(cli->outbuf,smb_sdsdisp,tot_data); /* dsdisp */ - if (trans==SMBtrans2) - SSVALS(cli->outbuf,smb_sfid,fid); /* fid */ - if (this_lparam) /* param[] */ - memcpy(outparam,param,this_lparam); - if (this_ldata) /* data[] */ - memcpy(outdata,data,this_ldata); - set_message(cli->outbuf,trans==SMBtrans?8:9, /* wcnt, bcc */ - PTR_DIFF(outdata+this_ldata,smb_buf(cli->outbuf)),False); - - show_msg(cli->outbuf); - cli_send_smb(cli); - - tot_data += this_ldata; - tot_param += this_lparam; - } - } - - return(True); -} - - -/**************************************************************************** - receive a SMB trans or trans2 response allocating the necessary memory - ****************************************************************************/ -static BOOL cli_receive_trans(struct cli_state *cli,int trans, - char **param, int *param_len, - char **data, int *data_len) -{ - int total_data=0; - int total_param=0; - int this_data,this_param; - uint8 eclass; - uint32 ecode; - - *data_len = *param_len = 0; - - if (!cli_receive_smb(cli)) - return False; - - show_msg(cli->inbuf); - - /* sanity check */ - if (CVAL(cli->inbuf,smb_com) != trans) { - DEBUG(0,("Expected %s response, got command 0x%02x\n", - trans==SMBtrans?"SMBtrans":"SMBtrans2", - CVAL(cli->inbuf,smb_com))); - return(False); - } - - /* - * An NT RPC pipe call can return ERRDOS, ERRmoredata - * to a trans call. This is not an error and should not - * be treated as such. - */ - - if (cli_error(cli, &eclass, &ecode, NULL)) - { - if(cli->nt_pipe_fnum == 0 || !(eclass == ERRDOS && ecode == ERRmoredata)) - return(False); - } - - /* parse out the lengths */ - total_data = SVAL(cli->inbuf,smb_tdrcnt); - total_param = SVAL(cli->inbuf,smb_tprcnt); - - /* allocate it */ - *data = Realloc(*data,total_data); - *param = Realloc(*param,total_param); - - while (1) { - this_data = SVAL(cli->inbuf,smb_drcnt); - this_param = SVAL(cli->inbuf,smb_prcnt); - - if (this_data + *data_len > total_data || - this_param + *param_len > total_param) { - DEBUG(1,("Data overflow in cli_receive_trans\n")); - return False; - } - - if (this_data) - memcpy(*data + SVAL(cli->inbuf,smb_drdisp), - smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_droff), - this_data); - if (this_param) - memcpy(*param + SVAL(cli->inbuf,smb_prdisp), - smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_proff), - this_param); - *data_len += this_data; - *param_len += this_param; - - /* parse out the total lengths again - they can shrink! */ - total_data = SVAL(cli->inbuf,smb_tdrcnt); - total_param = SVAL(cli->inbuf,smb_tprcnt); - - if (total_data <= *data_len && total_param <= *param_len) - break; - - if (!cli_receive_smb(cli)) - return False; - - show_msg(cli->inbuf); - - /* sanity check */ - if (CVAL(cli->inbuf,smb_com) != trans) { - DEBUG(0,("Expected %s response, got command 0x%02x\n", - trans==SMBtrans?"SMBtrans":"SMBtrans2", - CVAL(cli->inbuf,smb_com))); - return(False); - } - if (cli_error(cli, &eclass, &ecode, NULL)) - { - if(cli->nt_pipe_fnum == 0 || !(eclass == ERRDOS && ecode == ERRmoredata)) - return(False); - } - } - - return(True); -} - -#if 0 -/**************************************************************************** -Call a remote api on an arbitrary pipe. takes param, data and setup buffers. -****************************************************************************/ -BOOL cli_api_pipe(struct cli_state *cli, char *pipe_name, int pipe_name_len, - uint16 *setup, uint32 setup_count, uint32 max_setup_count, - char *params, uint32 param_count, uint32 max_param_count, - char *data, uint32 data_count, uint32 max_data_count, - char **rparam, uint32 *rparam_count, - char **rdata, uint32 *rdata_count) -{ - if (pipe_name_len == 0) - pipe_name_len = strlen(pipe_name); - - cli_send_trans(cli, SMBtrans, - pipe_name, pipe_name_len, - 0,0, /* fid, flags */ - setup, setup_count, max_setup_count, - params, param_count, max_param_count, - data, data_count, max_data_count); - - return (cli_receive_trans(cli, SMBtrans, - rparam, (int *)rparam_count, - rdata, (int *)rdata_count)); -} -#endif /*0 */ - -/**************************************************************************** -call a remote api -****************************************************************************/ -BOOL cli_api(struct cli_state *cli, - char *param, int prcnt, int mprcnt, - char *data, int drcnt, int mdrcnt, - char **rparam, int *rprcnt, - char **rdata, int *rdrcnt) -{ - cli_send_trans(cli,SMBtrans, - PIPE_LANMAN,strlen(PIPE_LANMAN), /* Name, length */ - 0,0, /* fid, flags */ - NULL,0,0, /* Setup, length, max */ - param, prcnt, mprcnt, /* Params, length, max */ - data, drcnt, mdrcnt /* Data, length, max */ - ); - - return (cli_receive_trans(cli,SMBtrans, - rparam, rprcnt, - rdata, rdrcnt)); -} - -#if 0 -/**************************************************************************** -perform a NetWkstaUserLogon -****************************************************************************/ -BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) -{ - char *rparam = NULL; - char *rdata = NULL; - char *p; - int rdrcnt,rprcnt; - pstring param; - - memset(param, 0, sizeof(param)); - - /* send a SMBtrans command with api NetWkstaUserLogon */ - p = param; - SSVAL(p,0,132); /* api number */ - p += 2; - pstrcpy(p,"OOWb54WrLh"); - p = skip_string(p,1); - pstrcpy(p,"WB21BWDWWDDDDDDDzzzD"); - p = skip_string(p,1); - SSVAL(p,0,1); - p += 2; - pstrcpy(p,user); - strupper(p); - p += 21; - p++; - p += 15; - p++; - pstrcpy(p, workstation); - strupper(p); - p += 16; - SSVAL(p, 0, CLI_BUFFER_SIZE); - p += 2; - SSVAL(p, 0, CLI_BUFFER_SIZE); - p += 2; - - if (cli_api(cli, - param, PTR_DIFF(p,param),1024, /* param, length, max */ - NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */ - &rparam, &rprcnt, /* return params, return size */ - &rdata, &rdrcnt /* return data, return size */ - )) { - cli->rap_error = SVAL(rparam,0); - p = rdata; - - if (cli->rap_error == 0) { - DEBUG(4,("NetWkstaUserLogon success\n")); - cli->privileges = SVAL(p, 24); - fstrcpy(cli->eff_name,p+2); - } else { - DEBUG(1,("NetwkstaUserLogon gave error %d\n", cli->rap_error)); - } - } - - if (rparam) - free(rparam); - if (rdata) - free(rdata); - return (cli->rap_error == 0); -} -#endif /*0 */ - -/**************************************************************************** -call a NetShareEnum - try and browse available connections on a host -****************************************************************************/ -int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, const char *, void *), void * state) -{ - char *rparam = NULL; - char *rdata = NULL; - char *p; - int rdrcnt,rprcnt; - pstring param; - int count = -1; - - /* now send a SMBtrans command with api RNetShareEnum */ - p = param; - SSVAL(p,0,0); /* api number */ - p += 2; - pstrcpy(p,"WrLeh"); - p = skip_string(p,1); - pstrcpy(p,"B13BWz"); - p = skip_string(p,1); - SSVAL(p,0,1); - /* - * Win2k needs a *smaller* buffer than 0xFFFF here - - * it returns "out of server memory" with 0xFFFF !!! JRA. - */ - SSVAL(p,2,0xFFE0); - p += 4; - - if (cli_api(cli, - param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */ - NULL, 0, 0xFFE0, /* data, length, maxlen - Win2k needs a small buffer here too ! */ - &rparam, &rprcnt, /* return params, length */ - &rdata, &rdrcnt)) /* return data, length */ - { - int res = SVAL(rparam,0); - int converter=SVAL(rparam,2); - int i; - - if (res == 0 || res == ERRmoredata) { - count=SVAL(rparam,4); - p = rdata; - - for (i=0;i rdrcnt) continue; - - stype = IVAL(p,18) & ~SV_TYPE_LOCAL_LIST_ONLY; - - fn(sname, stype, cmnt, state); - } - } - } - - if (rparam) - free(rparam); - if (rdata) - free(rdata); - - return(count > 0); -} - - - - -static struct { - int prot; - const char *name; - } -const prots[] = - { - {PROTOCOL_CORE,"PC NETWORK PROGRAM 1.0"}, - {PROTOCOL_COREPLUS,"MICROSOFT NETWORKS 1.03"}, - {PROTOCOL_LANMAN1,"MICROSOFT NETWORKS 3.0"}, - {PROTOCOL_LANMAN1,"LANMAN1.0"}, - {PROTOCOL_LANMAN2,"LM1.2X002"}, - {PROTOCOL_LANMAN2,"Samba"}, - {PROTOCOL_NT1,"NT LANMAN 1.0"}, - {PROTOCOL_NT1,"NT LM 0.12"}, - {-1,NULL} - }; - - -/**************************************************************************** -send a session setup -****************************************************************************/ -BOOL cli_session_setup(struct cli_state *cli, - char *user, - char *pass, int passlen, - char *ntpass, int ntpasslen, - char *workgroup) -{ - char *p; - fstring pword, ntpword; - - if (cli->protocol < PROTOCOL_LANMAN1) - return True; - - if ((size_t) passlen > sizeof(pword)-1 || (size_t)ntpasslen > sizeof(ntpword)-1) { - return False; - } - - if (((passlen == 0) || (passlen == 1)) && (pass[0] == '\0')) { - /* Null session connect. */ - pword[0] = '\0'; - ntpword[0] = '\0'; - } else { - if ((cli->sec_mode & 2) && passlen != 24) { - passlen = 24; - ntpasslen = 24; - SMBencrypt((uchar *)pass,(uchar *)cli->cryptkey,(uchar *)pword); - SMBNTencrypt((uchar *)ntpass,(uchar *)cli->cryptkey,(uchar *)ntpword); - } else { - fstrcpy(pword, pass); - fstrcpy(ntpword, ""); - ntpasslen = 0; - } - } - - /* if in share level security then don't send a password now */ - if (!(cli->sec_mode & 1)) { - fstrcpy(pword, ""); - passlen=1; - fstrcpy(ntpword, ""); - ntpasslen=1; - } - - /* send a session setup command */ - memset(cli->outbuf,'\0',smb_size); - - if (cli->protocol < PROTOCOL_NT1) - { - set_message(cli->outbuf,10,1 + strlen(user) + passlen,True); - CVAL(cli->outbuf,smb_com) = SMBsesssetupX; - cli_setup_packet(cli); - - CVAL(cli->outbuf,smb_vwv0) = 0xFF; - SSVAL(cli->outbuf,smb_vwv2,cli->max_xmit); - SSVAL(cli->outbuf,smb_vwv3,2); - SSVAL(cli->outbuf,smb_vwv4,1); - SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); - SSVAL(cli->outbuf,smb_vwv7,passlen); - p = smb_buf(cli->outbuf); - memcpy(p,pword,passlen); - p += passlen; - pstrcpy(p,user); - strupper(p); - unix_to_dos (p, True); - } - else - { - set_message(cli->outbuf,13,0,True); - CVAL(cli->outbuf,smb_com) = SMBsesssetupX; - cli_setup_packet(cli); - - CVAL(cli->outbuf,smb_vwv0) = 0xFF; - SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE); - SSVAL(cli->outbuf,smb_vwv3,2); - SSVAL(cli->outbuf,smb_vwv4,cli->pid); - SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); - SSVAL(cli->outbuf,smb_vwv7,passlen); - SSVAL(cli->outbuf,smb_vwv8,ntpasslen); - SSVAL(cli->outbuf,smb_vwv11,0); - p = smb_buf(cli->outbuf); - memcpy(p,pword,passlen); - p += SVAL(cli->outbuf,smb_vwv7); - memcpy(p,ntpword,ntpasslen); - p += SVAL(cli->outbuf,smb_vwv8); - pstrcpy(p,user); - strupper(p); - unix_to_dos (p, True); - p = skip_string(p,1); - pstrcpy(p,workgroup); - strupper(p); - p = skip_string(p,1); - pstrcpy(p,"Unix");p = skip_string(p,1); - pstrcpy(p,"Samba");p = skip_string(p,1); - set_message(cli->outbuf,13,PTR_DIFF(p,smb_buf(cli->outbuf)),False); - } - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) - return False; - - show_msg(cli->inbuf); - - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return False; - } - - /* use the returned vuid from now on */ - cli->vuid = SVAL(cli->inbuf,smb_uid); - - if (cli->protocol >= PROTOCOL_NT1) { - /* - * Save off some of the connected server - * info. - */ - char *server_domain,*server_os,*server_type; - server_os = smb_buf(cli->inbuf); - server_type = skip_string(server_os,1); - server_domain = skip_string(server_type,1); - fstrcpy(cli->server_os, server_os); - fstrcpy(cli->server_type, server_type); - fstrcpy(cli->server_domain, server_domain); - } - - fstrcpy(cli->user_name, user); - - return True; -} - -/**************************************************************************** - Send a uloggoff. -*****************************************************************************/ -#if 0 -BOOL cli_ulogoff(struct cli_state *cli) -{ - memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,2,0,True); - CVAL(cli->outbuf,smb_com) = SMBulogoffX; - cli_setup_packet(cli); - SSVAL(cli->outbuf,smb_vwv0,0xFF); - SSVAL(cli->outbuf,smb_vwv2,0); /* no additional info */ - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) - return False; - - return CVAL(cli->inbuf,smb_rcls) == 0; -} -#endif /*0 */ - -/**************************************************************************** -send a tconX -****************************************************************************/ -BOOL cli_send_tconX(struct cli_state *cli, - const char *share, const char *dev, const char *pass, int passlen) -{ - fstring fullshare, pword; - char *p; - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); - - fstrcpy(cli->share, share); - - /* in user level security don't send a password now */ - if (cli->sec_mode & 1) { - passlen = 1; - pass = ""; - } - - if ((cli->sec_mode & 2) && *pass && passlen != 24) { - passlen = 24; - SMBencrypt((uchar *)pass,(uchar *)cli->cryptkey,(uchar *)pword); - } else { - memcpy(pword, pass, passlen); - } - - slprintf(fullshare, sizeof(fullshare)-1, - "\\\\%s\\%s", cli->desthost, share); - unix_to_dos(fullshare, True); - strupper(fullshare); - - set_message(cli->outbuf,4, - 2 + strlen(fullshare) + passlen + strlen(dev),True); - CVAL(cli->outbuf,smb_com) = SMBtconX; - cli_setup_packet(cli); - - SSVAL(cli->outbuf,smb_vwv0,0xFF); - SSVAL(cli->outbuf,smb_vwv3,passlen); - - p = smb_buf(cli->outbuf); - memcpy(p,pword,passlen); - p += passlen; - fstrcpy(p,fullshare); - p = skip_string(p,1); - pstrcpy(p,dev); - - SCVAL(cli->inbuf,smb_rcls, 1); - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) - return False; - - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return False; - } - - fstrcpy(cli->dev, "A:"); - - if (cli->protocol >= PROTOCOL_NT1) { - fstrcpy(cli->dev, smb_buf(cli->inbuf)); - } - - if (strcasecmp(share,"IPC$")==0) { - fstrcpy(cli->dev, "IPC"); - } - - /* only grab the device if we have a recent protocol level */ - if (cli->protocol >= PROTOCOL_NT1 && - smb_buflen(cli->inbuf) == 3) { - /* almost certainly win95 - enable bug fixes */ - cli->win95 = True; - } - - cli->cnum = SVAL(cli->inbuf,smb_tid); - return True; -} - -#if 0 -/**************************************************************************** -send a tree disconnect -****************************************************************************/ -BOOL cli_tdis(struct cli_state *cli) -{ - memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,0,0,True); - CVAL(cli->outbuf,smb_com) = SMBtdis; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) - return False; - - return CVAL(cli->inbuf,smb_rcls) == 0; -} -#endif /*0 */ - -/**************************************************************************** -rename a file -****************************************************************************/ -BOOL cli_rename(struct cli_state *cli, char *fname_src, char *fname_dst) -{ - char *p; - - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); - - set_message(cli->outbuf,1, 4 + strlen(fname_src) + strlen(fname_dst), True); - - CVAL(cli->outbuf,smb_com) = SMBmv; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - SSVAL(cli->outbuf,smb_vwv0,aSYSTEM | aHIDDEN); - - p = smb_buf(cli->outbuf); - *p++ = 4; - pstrcpy(p,fname_src); - p = skip_string(p,1); - *p++ = 4; - pstrcpy(p,fname_dst); - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return False; - } - - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return False; - } - - return True; -} - -/**************************************************************************** -delete a file -****************************************************************************/ -BOOL cli_unlink(struct cli_state *cli, char *fname) -{ - char *p; - - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); - - set_message(cli->outbuf,1, 2 + strlen(fname),True); - - CVAL(cli->outbuf,smb_com) = SMBunlink; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - SSVAL(cli->outbuf,smb_vwv0,aSYSTEM | aHIDDEN); - - p = smb_buf(cli->outbuf); - *p++ = 4; - pstrcpy(p,fname); - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return False; - } - - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return False; - } - - return True; -} - -/**************************************************************************** -create a directory -****************************************************************************/ -BOOL cli_mkdir(struct cli_state *cli, char *dname) -{ - char *p; - - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); - - set_message(cli->outbuf,0, 2 + strlen(dname),True); - - CVAL(cli->outbuf,smb_com) = SMBmkdir; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - p = smb_buf(cli->outbuf); - *p++ = 4; - pstrcpy(p,dname); - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return False; - } - - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return False; - } - - return True; -} - -/**************************************************************************** -remove a directory -****************************************************************************/ -BOOL cli_rmdir(struct cli_state *cli, char *dname) -{ - char *p; - - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); - - set_message(cli->outbuf,0, 2 + strlen(dname),True); - - CVAL(cli->outbuf,smb_com) = SMBrmdir; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - p = smb_buf(cli->outbuf); - *p++ = 4; - pstrcpy(p,dname); - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return False; - } - - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return False; - } - - return True; -} - -#if 0 -/**************************************************************************** -open a file -****************************************************************************/ -int cli_nt_create(struct cli_state *cli, char *fname) -{ - char *p; - - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); - - set_message(cli->outbuf,24,1 + strlen(fname),True); - - CVAL(cli->outbuf,smb_com) = SMBntcreateX; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - SSVAL(cli->outbuf,smb_vwv0,0xFF); - SIVAL(cli->outbuf,smb_ntcreate_Flags, 0x06); - SIVAL(cli->outbuf,smb_ntcreate_RootDirectoryFid, 0x0); - SIVAL(cli->outbuf,smb_ntcreate_DesiredAccess, 0x2019f); - SIVAL(cli->outbuf,smb_ntcreate_FileAttributes, 0x0); - SIVAL(cli->outbuf,smb_ntcreate_ShareAccess, 0x03); - SIVAL(cli->outbuf,smb_ntcreate_CreateDisposition, 0x01); - SIVAL(cli->outbuf,smb_ntcreate_CreateOptions, 0x0); - SIVAL(cli->outbuf,smb_ntcreate_ImpersonationLevel, 0x02); - SSVAL(cli->outbuf,smb_ntcreate_NameLength, strlen(fname)); - - p = smb_buf(cli->outbuf); - pstrcpy(p,fname); - p = skip_string(p,1); - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return -1; - } - - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return -1; - } - - return SVAL(cli->inbuf,smb_vwv2 + 1); -} -#endif /*0 */ - -/**************************************************************************** -open a file -****************************************************************************/ -int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) -{ - char *p; - unsigned openfn=0; - unsigned accessmode=0; - - /* you must open for RW not just write - otherwise getattrE doesn't - work! */ - if ((flags & O_ACCMODE) == O_WRONLY && strncmp(cli->dev, "LPT", 3)) { - flags = (flags & ~O_ACCMODE) | O_RDWR; - } - - if (flags & O_CREAT) - openfn |= (1<<4); - if (!(flags & O_EXCL)) { - if (flags & O_TRUNC) - openfn |= (1<<1); - else - openfn |= (1<<0); - } - - accessmode = (share_mode<<4); - - if ((flags & O_ACCMODE) == O_RDWR) { - accessmode |= 2; - } else if ((flags & O_ACCMODE) == O_WRONLY) { - accessmode |= 1; - } - -#if defined(O_SYNC) - if ((flags & O_SYNC) == O_SYNC) { - accessmode |= (1<<14); - } -#endif /* O_SYNC */ - - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); - - set_message(cli->outbuf,15,1 + strlen(fname),True); - - CVAL(cli->outbuf,smb_com) = SMBopenX; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - SSVAL(cli->outbuf,smb_vwv0,0xFF); - SSVAL(cli->outbuf,smb_vwv2,0); /* no additional info */ - SSVAL(cli->outbuf,smb_vwv3,accessmode); - SSVAL(cli->outbuf,smb_vwv4,aSYSTEM | aHIDDEN); - SSVAL(cli->outbuf,smb_vwv5,0); - SSVAL(cli->outbuf,smb_vwv8,openfn); - - p = smb_buf(cli->outbuf); - pstrcpy(p,fname); - p = skip_string(p,1); - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return -1; - } - - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return -1; - } - - return SVAL(cli->inbuf,smb_vwv2); -} - - - - -/**************************************************************************** - close a file -****************************************************************************/ -BOOL cli_close(struct cli_state *cli, int fnum) -{ - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); - - set_message(cli->outbuf,3,0,True); - - CVAL(cli->outbuf,smb_com) = SMBclose; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - SSVAL(cli->outbuf,smb_vwv0,fnum); - SIVALS(cli->outbuf,smb_vwv1,-1); - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return False; - } - - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return False; - } - - return True; -} - -#if 0 -/**************************************************************************** - lock a file -****************************************************************************/ -BOOL cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int timeout) -{ - char *p; - int saved_timeout = cli->timeout; - - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0', smb_size); - - set_message(cli->outbuf,8,10,True); - - CVAL(cli->outbuf,smb_com) = SMBlockingX; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - CVAL(cli->outbuf,smb_vwv0) = 0xFF; - SSVAL(cli->outbuf,smb_vwv2,fnum); - CVAL(cli->outbuf,smb_vwv3) = 0; - SIVALS(cli->outbuf, smb_vwv4, timeout); - SSVAL(cli->outbuf,smb_vwv6,0); - SSVAL(cli->outbuf,smb_vwv7,1); - - p = smb_buf(cli->outbuf); - SSVAL(p, 0, cli->pid); - SIVAL(p, 2, offset); - SIVAL(p, 6, len); - cli_send_smb(cli); - - cli->timeout = (timeout == -1) ? 0x7FFFFFFF : timeout; - - if (!cli_receive_smb(cli)) { - cli->timeout = saved_timeout; - return False; - } - - cli->timeout = saved_timeout; - - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return False; - } - - return True; -} - -/**************************************************************************** - unlock a file -****************************************************************************/ -BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int timeout) -{ - char *p; - - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); - - set_message(cli->outbuf,8,10,True); - - CVAL(cli->outbuf,smb_com) = SMBlockingX; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - CVAL(cli->outbuf,smb_vwv0) = 0xFF; - SSVAL(cli->outbuf,smb_vwv2,fnum); - CVAL(cli->outbuf,smb_vwv3) = 0; - SIVALS(cli->outbuf, smb_vwv4, timeout); - SSVAL(cli->outbuf,smb_vwv6,1); - SSVAL(cli->outbuf,smb_vwv7,0); - - p = smb_buf(cli->outbuf); - SSVAL(p, 0, cli->pid); - SIVAL(p, 2, offset); - SIVAL(p, 6, len); - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return False; - } - - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return False; - } - - return True; -} -#endif /*0 */ - - -/**************************************************************************** -issue a single SMBread and don't wait for a reply -****************************************************************************/ -static void cli_issue_read(struct cli_state *cli, int fnum, off_t offset, - size_t size, int i) -{ - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); - - set_message(cli->outbuf,10,0,True); - - CVAL(cli->outbuf,smb_com) = SMBreadX; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - CVAL(cli->outbuf,smb_vwv0) = 0xFF; - SSVAL(cli->outbuf,smb_vwv2,fnum); - SIVAL(cli->outbuf,smb_vwv3,offset); - SSVAL(cli->outbuf,smb_vwv5,size); - SSVAL(cli->outbuf,smb_vwv6,size); - SSVAL(cli->outbuf,smb_mid,cli->mid + i); - - cli_send_smb(cli); -} - -/**************************************************************************** - read from a file -****************************************************************************/ -size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size) -{ - char *p; - int total = -1; - int issued=0; - int received=0; - int mpx = MAX(cli->max_mux-1, 1); - int block = (cli->max_xmit - (smb_size+32)) & ~1023; - int mid; - int blocks = (size + (block-1)) / block; - - if (size == 0) return 0; - - while (received < blocks) { - int size2; - - while (issued - received < mpx && issued < blocks) { - int size1 = MIN(block, (int) size-issued*block); - cli_issue_read(cli, fnum, offset+issued*block, size1, issued); - issued++; - } - - if (!cli_receive_smb(cli)) { - return total; - } - - received++; - mid = SVAL(cli->inbuf, smb_mid) - cli->mid; - size2 = SVAL(cli->inbuf, smb_vwv5); - - if (CVAL(cli->inbuf,smb_rcls) != 0) { - blocks = MIN(blocks, mid-1); - continue; - } - - if (size2 <= 0) { - blocks = MIN(blocks, mid-1); - /* this distinguishes EOF from an error */ - total = MAX(total, 0); - continue; - } - - if (size2 > block) { - DEBUG(0,("server returned more than we wanted!\n")); - exit(1); - } - if (mid >= issued) { - DEBUG(0,("invalid mid from server!\n")); - exit(1); - } - p = smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_vwv6); - - memcpy(buf+mid*block, p, size2); - - total = MAX(total, mid*block + size2); - } - - while (received < issued) { - cli_receive_smb(cli); - received++; - } - - return total; -} - - -/**************************************************************************** -issue a single SMBwrite and don't wait for a reply -****************************************************************************/ -static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint16 mode, const char *buf, - size_t size, int i) -{ - char *p; - - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); - - set_message(cli->outbuf,12,size,True); - - CVAL(cli->outbuf,smb_com) = SMBwriteX; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - CVAL(cli->outbuf,smb_vwv0) = 0xFF; - SSVAL(cli->outbuf,smb_vwv2,fnum); - - SIVAL(cli->outbuf,smb_vwv3,offset); - SIVAL(cli->outbuf,smb_vwv5,IS_BITS_SET_ALL(mode, 0x0008) ? 0xFFFFFFFF : 0); - SSVAL(cli->outbuf,smb_vwv7,mode); - - SSVAL(cli->outbuf,smb_vwv8,IS_BITS_SET_ALL(mode, 0x0008) ? size : 0); - SSVAL(cli->outbuf,smb_vwv10,size); - SSVAL(cli->outbuf,smb_vwv11, - smb_buf(cli->outbuf) - smb_base(cli->outbuf)); - - p = smb_base(cli->outbuf) + SVAL(cli->outbuf,smb_vwv11); - memcpy(p, buf, size); - - SSVAL(cli->outbuf,smb_mid,cli->mid + i); - - show_msg(cli->outbuf); - cli_send_smb(cli); -} - -/**************************************************************************** - write to a file - write_mode: 0x0001 disallow write cacheing - 0x0002 return bytes remaining - 0x0004 use raw named pipe protocol - 0x0008 start of message mode named pipe protocol -****************************************************************************/ -ssize_t cli_write(struct cli_state *cli, - int fnum, uint16 write_mode, - const char *buf, off_t offset, size_t size) -{ - int bwritten = 0; - int issued = 0; - int received = 0; - int mpx = MAX(cli->max_mux-1, 1); - int block = (cli->max_xmit - (smb_size+32)) & ~1023; - int blocks = (size + (block-1)) / block; - - while (received < blocks) { - - while ((issued - received < mpx) && (issued < blocks)) - { - int bsent = issued * block; - int size1 = MIN(block, (int) size - bsent); - - cli_issue_write(cli, fnum, offset + bsent, - write_mode, - buf + bsent, - size1, issued); - issued++; - } - - if (!cli_receive_smb(cli)) - { - return bwritten; - } - - received++; - - if (CVAL(cli->inbuf,smb_rcls) != 0) - { - break; - } - - bwritten += SVAL(cli->inbuf, smb_vwv2); - } - - while (received < issued && cli_receive_smb(cli)) - { - received++; - } - - return bwritten; -} - -#if 0 -/**************************************************************************** - write to a file using a SMBwrite and not bypassing 0 byte writes -****************************************************************************/ -ssize_t cli_smbwrite(struct cli_state *cli, - int fnum, const char *buf, off_t offset, size_t size) -{ - char *p; - - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); - - set_message(cli->outbuf,5, 3 + size,True); - - CVAL(cli->outbuf,smb_com) = SMBwrite; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - SSVAL(cli->outbuf,smb_vwv0,fnum); - SSVAL(cli->outbuf,smb_vwv1,size); - SIVAL(cli->outbuf,smb_vwv2,offset); - SSVAL(cli->outbuf,smb_vwv4,0); - - p = smb_buf(cli->outbuf); - *p++ = 1; - SSVAL(p, 0, size); - memcpy(p+2, buf, size); - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return False; - } - - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return -1; - } - - return SVAL(cli->inbuf,smb_vwv0); -} -#endif /*0 */ - -/**************************************************************************** -do a SMBgetattrE call -****************************************************************************/ -BOOL cli_getattrE(struct cli_state *cli, int fd, - uint16 *attr, size_t *size, - time_t *c_time, time_t *a_time, time_t *m_time) -{ - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); - - set_message(cli->outbuf,2,0,True); - - CVAL(cli->outbuf,smb_com) = SMBgetattrE; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - SSVAL(cli->outbuf,smb_vwv0,fd); - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return False; - } - - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return False; - } - - if (size) { - *size = IVAL(cli->inbuf, smb_vwv6); - } - - if (attr) { - *attr = SVAL(cli->inbuf,smb_vwv10); - } - - if (c_time) { - *c_time = make_unix_date3(cli->inbuf+smb_vwv0); - } - - if (a_time) { - *a_time = make_unix_date3(cli->inbuf+smb_vwv2); - } - - if (m_time) { - *m_time = make_unix_date3(cli->inbuf+smb_vwv4); - } - - return True; -} - - -/**************************************************************************** -do a SMBgetatr call -****************************************************************************/ -BOOL cli_getatr(struct cli_state *cli, char *fname, - uint16 *attr, size_t *size, time_t *t) -{ - char *p; - - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); - - set_message(cli->outbuf,0,strlen(fname)+2,True); - - CVAL(cli->outbuf,smb_com) = SMBgetatr; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - p = smb_buf(cli->outbuf); - *p = 4; - pstrcpy(p+1, fname); - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return False; - } - - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return False; - } - - if (size) { - *size = IVAL(cli->inbuf, smb_vwv3); - } - - if (t) { - *t = make_unix_date3(cli->inbuf+smb_vwv1); - } - - if (attr) { - *attr = SVAL(cli->inbuf,smb_vwv0); - } - - - return True; -} - - -/**************************************************************************** -do a SMBsetatr call -****************************************************************************/ -BOOL cli_setatr(struct cli_state *cli, char *fname, uint16 attr, time_t t) -{ - char *p; - - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); - - set_message(cli->outbuf,8,strlen(fname)+4,True); - - CVAL(cli->outbuf,smb_com) = SMBsetatr; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - SSVAL(cli->outbuf,smb_vwv0, attr); - put_dos_date3(cli->outbuf,smb_vwv1, t); - - p = smb_buf(cli->outbuf); - *p = 4; - pstrcpy(p+1, fname); - p = skip_string(p,1); - *p = 4; - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return False; - } - - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return False; - } - - return True; -} - -#if 0 -/**************************************************************************** -send a qpathinfo call -****************************************************************************/ -BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, - time_t *c_time, time_t *a_time, time_t *m_time, - size_t *size, uint16 *mode) -{ - int data_len = 0; - int param_len = 0; - uint16 setup = TRANSACT2_QPATHINFO; - pstring param; - char *rparam=NULL, *rdata=NULL; - int count=8; - BOOL ret; - time_t (*date_fn)(void *); - - param_len = strlen(fname) + 7; - - memset(param, 0, param_len); - SSVAL(param, 0, SMB_INFO_STANDARD); - pstrcpy(¶m[6], fname); - - do { - ret = (cli_send_trans(cli, SMBtrans2, - NULL, 0, /* Name, length */ - -1, 0, /* fid, flags */ - &setup, 1, 0, /* setup, length, max */ - param, param_len, 10, /* param, length, max */ - NULL, data_len, cli->max_xmit /* data, length, max */ - ) && - cli_receive_trans(cli, SMBtrans2, - &rparam, ¶m_len, - &rdata, &data_len)); - if (!ret) { - /* we need to work around a Win95 bug - sometimes - it gives ERRSRV/ERRerror temprarily */ - uint8 eclass; - uint32 ecode; - cli_error(cli, &eclass, &ecode, NULL); - if (eclass != ERRSRV || ecode != ERRerror) break; - msleep(100); - } - } while (count-- && ret==False); - - if (!ret || !rdata || data_len < 22) { - return False; - } - - if (cli->win95) { - date_fn = make_unix_date; - } else { - date_fn = make_unix_date2; - } - - if (c_time) { - *c_time = date_fn(rdata+0); - } - if (a_time) { - *a_time = date_fn(rdata+4); - } - if (m_time) { - *m_time = date_fn(rdata+8); - } - if (size) { - *size = IVAL(rdata, 12); - } - if (mode) { - *mode = SVAL(rdata,l1_attrFile); - } - - if (rdata) free(rdata); - if (rparam) free(rparam); - return True; -} - -/**************************************************************************** -send a qpathinfo call with the SMB_QUERY_FILE_ALL_INFO info level -****************************************************************************/ -BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, - time_t *c_time, time_t *a_time, time_t *m_time, - time_t *w_time, size_t *size, uint16 *mode, - SMB_INO_T *ino) -{ - int data_len = 0; - int param_len = 0; - uint16 setup = TRANSACT2_QPATHINFO; - pstring param; - char *rparam=NULL, *rdata=NULL; - - param_len = strlen(fname) + 7; - - memset(param, 0, param_len); - SSVAL(param, 0, SMB_QUERY_FILE_ALL_INFO); - pstrcpy(¶m[6], fname); - - if (!cli_send_trans(cli, SMBtrans2, - NULL, 0, /* name, length */ - -1, 0, /* fid, flags */ - &setup, 1, 0, /* setup, length, max */ - param, param_len, 10, /* param, length, max */ - NULL, data_len, cli->max_xmit /* data, length, max */ - )) { - return False; - } - - if (!cli_receive_trans(cli, SMBtrans2, - &rparam, ¶m_len, - &rdata, &data_len)) { - return False; - } - - if (!rdata || data_len < 22) { - return False; - } - - if (c_time) { - *c_time = interpret_long_date(rdata+0) - cli->serverzone; - } - if (a_time) { - *a_time = interpret_long_date(rdata+8) - cli->serverzone; - } - if (m_time) { - *m_time = interpret_long_date(rdata+16) - cli->serverzone; - } - if (w_time) { - *w_time = interpret_long_date(rdata+24) - cli->serverzone; - } - if (mode) { - *mode = SVAL(rdata, 32); - } - if (size) { - *size = IVAL(rdata, 48); - } - if (ino) { - *ino = IVAL(rdata, 64); - } - - if (rdata) free(rdata); - if (rparam) free(rparam); - return True; -} -#endif /* 0 */ - -/**************************************************************************** -send a qfileinfo call -****************************************************************************/ -BOOL cli_qfileinfo(struct cli_state *cli, int fnum, - uint16 *mode, size_t *size, - time_t *c_time, time_t *a_time, time_t *m_time, - time_t *w_time, SMB_INO_T *ino) -{ - int data_len = 0; - int param_len = 0; - uint16 setup = TRANSACT2_QFILEINFO; - pstring param; - char *rparam=NULL, *rdata=NULL; - - /* if its a win95 server then fail this - win95 totally screws it - up */ - if (cli->win95) return False; - - param_len = 4; - - memset(param, 0, param_len); - SSVAL(param, 0, fnum); - SSVAL(param, 2, SMB_QUERY_FILE_ALL_INFO); - - if (!cli_send_trans(cli, SMBtrans2, - NULL, 0, /* name, length */ - -1, 0, /* fid, flags */ - &setup, 1, 0, /* setup, length, max */ - param, param_len, 2, /* param, length, max */ - NULL, data_len, cli->max_xmit /* data, length, max */ - )) { - return False; - } - - if (!cli_receive_trans(cli, SMBtrans2, - &rparam, ¶m_len, - &rdata, &data_len)) { - return False; - } - - if (!rdata || data_len < 68) { - return False; - } - - if (c_time) { - *c_time = interpret_long_date(rdata+0) - cli->serverzone; - } - if (a_time) { - *a_time = interpret_long_date(rdata+8) - cli->serverzone; - } - if (m_time) { - *m_time = interpret_long_date(rdata+16) - cli->serverzone; - } - if (w_time) { - *w_time = interpret_long_date(rdata+24) - cli->serverzone; - } - if (mode) { - *mode = SVAL(rdata, 32); - } - if (size) { - *size = IVAL(rdata, 48); - } - if (ino) { - *ino = IVAL(rdata, 64); - } - - if (rdata) free(rdata); - if (rparam) free(rparam); - return True; -} - - -/**************************************************************************** -interpret a long filename structure - this is mostly guesses at the moment -The length of the structure is returned -The structure of a long filename depends on the info level. 260 is used -by NT and 2 is used by OS/2 -****************************************************************************/ -static int interpret_long_filename(int level,char *p,file_info *finfo) -{ - extern file_info const def_finfo; - - if (finfo) - memcpy(finfo,&def_finfo,sizeof(*finfo)); - - switch (level) - { - case 1: /* OS/2 understands this */ - if (finfo) { - /* these dates are converted to GMT by make_unix_date */ - finfo->ctime = make_unix_date2(p+4); - finfo->atime = make_unix_date2(p+8); - finfo->mtime = make_unix_date2(p+12); - finfo->size = IVAL(p,16); - finfo->mode = CVAL(p,24); - pstrcpy(finfo->name,p+27); - } - return(28 + CVAL(p,26)); - - case 2: /* this is what OS/2 uses mostly */ - if (finfo) { - /* these dates are converted to GMT by make_unix_date */ - finfo->ctime = make_unix_date2(p+4); - finfo->atime = make_unix_date2(p+8); - finfo->mtime = make_unix_date2(p+12); - finfo->size = IVAL(p,16); - finfo->mode = CVAL(p,24); - pstrcpy(finfo->name,p+31); - } - return(32 + CVAL(p,30)); - - /* levels 3 and 4 are untested */ - case 3: - if (finfo) { - /* these dates are probably like the other ones */ - finfo->ctime = make_unix_date2(p+8); - finfo->atime = make_unix_date2(p+12); - finfo->mtime = make_unix_date2(p+16); - finfo->size = IVAL(p,20); - finfo->mode = CVAL(p,28); - pstrcpy(finfo->name,p+33); - } - return(SVAL(p,4)+4); - - case 4: - if (finfo) { - /* these dates are probably like the other ones */ - finfo->ctime = make_unix_date2(p+8); - finfo->atime = make_unix_date2(p+12); - finfo->mtime = make_unix_date2(p+16); - finfo->size = IVAL(p,20); - finfo->mode = CVAL(p,28); - pstrcpy(finfo->name,p+37); - } - return(SVAL(p,4)+4); - - case 260: /* NT uses this, but also accepts 2 */ - if (finfo) { - int ret = SVAL(p,0); - int namelen; - p += 4; /* next entry offset */ - p += 4; /* fileindex */ - - /* these dates appear to arrive in a - weird way. It seems to be localtime - plus the serverzone given in the - initial connect. This is GMT when - DST is not in effect and one hour - from GMT otherwise. Can this really - be right?? - - I suppose this could be called - kludge-GMT. Is is the GMT you get - by using the current DST setting on - a different localtime. It will be - cheap to calculate, I suppose, as - no DST tables will be needed */ - - finfo->ctime = interpret_long_date(p); p += 8; - finfo->atime = interpret_long_date(p); p += 8; - finfo->mtime = interpret_long_date(p); p += 8; p += 8; - finfo->size = IVAL(p,0); p += 8; - p += 8; /* alloc size */ - finfo->mode = CVAL(p,0); p += 4; - namelen = IVAL(p,0); p += 4; - p += 4; /* EA size */ - p += 2; /* short name len? */ - p += 24; /* short name? */ - StrnCpy(finfo->name,p,namelen); - return(ret); - } - return(SVAL(p,0)); - } - - DEBUG(1,("Unknown long filename format %d\n",level)); - return(SVAL(p,0)); -} - - -/**************************************************************************** - do a directory listing, calling fn on each file found - ****************************************************************************/ -int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, - void (*fn)(file_info *, const char *, void *), void *state) -{ - int max_matches = 512; - /* NT uses 260, OS/2 uses 2. Both accept 1. */ - int info_level = cli->protocol 200) { - DEBUG(0,("Error: Looping in FIND_NEXT??\n")); - break; - } - - param_len = 12+strlen(mask)+1; - - if (First) { - setup = TRANSACT2_FINDFIRST; - SSVAL(param,0,attribute); /* attribute */ - SSVAL(param,2,max_matches); /* max count */ - SSVAL(param,4,8+4+2); /* resume required + close on end + continue */ - SSVAL(param,6,info_level); - SIVAL(param,8,0); - pstrcpy(param+12,mask); - } else { - setup = TRANSACT2_FINDNEXT; - SSVAL(param,0,ff_dir_handle); - SSVAL(param,2,max_matches); /* max count */ - SSVAL(param,4,info_level); - SIVAL(param,6,ff_resume_key); /* ff_resume_key */ - SSVAL(param,10,8+4+2); /* resume required + close on end + continue */ - pstrcpy(param+12,mask); - - DEBUG(5,("hand=0x%X resume=%d ff_lastname=%d mask=%s\n", - ff_dir_handle,ff_resume_key,ff_lastname,mask)); - } - - if (!cli_send_trans(cli, SMBtrans2, - NULL, 0, /* Name, length */ - -1, 0, /* fid, flags */ - &setup, 1, 0, /* setup, length, max */ - param, param_len, 10, /* param, length, max */ - NULL, 0, - cli->max_xmit /* data, length, max */ - )) { - break; - } - - if (!cli_receive_trans(cli, SMBtrans2, - &rparam, ¶m_len, - &rdata, &data_len)) { - /* we need to work around a Win95 bug - sometimes - it gives ERRSRV/ERRerror temprarily */ - uint8 eclass; - uint32 ecode; - cli_error(cli, &eclass, &ecode, NULL); - if (eclass != ERRSRV || ecode != ERRerror) break; - msleep(100); - continue; - } - - if (total_received == -1) total_received = 0; - - /* parse out some important return info */ - p = rparam; - if (First) { - ff_dir_handle = SVAL(p,0); - ff_searchcount = SVAL(p,2); - ff_eos = SVAL(p,4); - ff_lastname = SVAL(p,8); - } else { - ff_searchcount = SVAL(p,0); - ff_eos = SVAL(p,2); - ff_lastname = SVAL(p,6); - } - - if (ff_searchcount == 0) - break; - - /* point to the data bytes */ - p = rdata; - - /* we might need the lastname for continuations */ - if (ff_lastname > 0) { - switch(info_level) - { - case 260: - ff_resume_key =0; - StrnCpy(mask,p+ff_lastname, - data_len-ff_lastname); - break; - case 1: - pstrcpy(mask,p + ff_lastname + 1); - ff_resume_key = 0; - break; - } - } else { - pstrcpy(mask,""); - } - - /* and add them to the dirlist pool */ - dirlist = Realloc(dirlist,dirlist_len + data_len); - - if (!dirlist) { - DEBUG(0,("Failed to expand dirlist\n")); - break; - } - - /* put in a length for the last entry, to ensure we can chain entries - into the next packet */ - for (p2=p,i=0;i<(ff_searchcount-1);i++) - p2 += interpret_long_filename(info_level,p2,NULL); - SSVAL(p2,0,data_len - PTR_DIFF(p2,p)); - - /* grab the data for later use */ - memcpy(dirlist+dirlist_len,p,data_len); - dirlist_len += data_len; - - total_received += ff_searchcount; - - if (rdata) free(rdata); rdata = NULL; - if (rparam) free(rparam); rparam = NULL; - - DEBUG(3,("received %d entries (eos=%d resume=%d)\n", - ff_searchcount,ff_eos,ff_resume_key)); - - First = False; - } - - for (p=dirlist,i=0;ioutbuf,'\0',smb_size); - - /* setup the protocol strings */ - for (plength=0,numprots=0; - prots[numprots].name && prots[numprots].prot<=cli->protocol; - numprots++) - plength += strlen(prots[numprots].name)+2; - - set_message(cli->outbuf,0,plength,True); - - p = smb_buf(cli->outbuf); - for (numprots=0; - prots[numprots].name && prots[numprots].prot<=cli->protocol; - numprots++) { - *p++ = 2; - pstrcpy(p,prots[numprots].name); - p += strlen(p) + 1; - } - - CVAL(cli->outbuf,smb_com) = SMBnegprot; - cli_setup_packet(cli); - - CVAL(smb_buf(cli->outbuf),0) = 2; - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) - return False; - - show_msg(cli->inbuf); - - if (CVAL(cli->inbuf,smb_rcls) != 0 || - ((int)SVAL(cli->inbuf,smb_vwv0) >= numprots)) { - return(False); - } - - cli->protocol = prots[SVAL(cli->inbuf,smb_vwv0)].prot; - - - if (cli->protocol >= PROTOCOL_NT1) { - /* NT protocol */ - cli->sec_mode = CVAL(cli->inbuf,smb_vwv1); - cli->max_mux = SVAL(cli->inbuf, smb_vwv1+1); - cli->max_xmit = IVAL(cli->inbuf,smb_vwv3+1); - cli->sesskey = IVAL(cli->inbuf,smb_vwv7+1); - cli->serverzone = SVALS(cli->inbuf,smb_vwv15+1)*60; - /* this time arrives in real GMT */ - cli->servertime = interpret_long_date(cli->inbuf+smb_vwv11+1); - memcpy(cli->cryptkey,smb_buf(cli->inbuf),8); - cli->capabilities = IVAL(cli->inbuf,smb_vwv9+1); - if (cli->capabilities & 1) { - cli->readbraw_supported = True; - cli->writebraw_supported = True; - } - } else if (cli->protocol >= PROTOCOL_LANMAN1) { - cli->sec_mode = SVAL(cli->inbuf,smb_vwv1); - cli->max_xmit = SVAL(cli->inbuf,smb_vwv2); - cli->sesskey = IVAL(cli->inbuf,smb_vwv6); - cli->serverzone = SVALS(cli->inbuf,smb_vwv10)*60; - /* this time is converted to GMT by make_unix_date */ - cli->servertime = make_unix_date(cli->inbuf+smb_vwv8); - cli->readbraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x1) != 0); - cli->writebraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x2) != 0); - memcpy(cli->cryptkey,smb_buf(cli->inbuf),8); - } else { - /* the old core protocol */ - cli->sec_mode = 0; - cli->serverzone = TimeDiff(time(NULL)); - } - - cli->max_xmit = MIN(cli->max_xmit, CLI_BUFFER_SIZE); - - return True; -} - - -/**************************************************************************** - send a session request. see rfc1002.txt 4.3 and 4.3.2 -****************************************************************************/ -BOOL cli_session_request(struct cli_state *cli, - struct nmb_name *calling, struct nmb_name *called) -{ - char *p; - int len = 4; - /* send a session request (RFC 1002) */ - - memcpy(&(cli->calling), calling, sizeof(*calling)); - memcpy(&(cli->called ), called , sizeof(*called )); - - /* put in the destination name */ - p = cli->outbuf+len; - name_mangle(cli->called .name, p, cli->called .name_type); - len += name_len(p); - - /* and my name */ - p = cli->outbuf+len; - name_mangle(cli->calling.name, p, cli->calling.name_type); - len += name_len(p); - - /* setup the packet length */ - _smb_setlen(cli->outbuf,len); - CVAL(cli->outbuf,0) = 0x81; - -#ifdef WITH_SSL -retry: -#endif /* WITH_SSL */ - - cli_send_smb(cli); - DEBUG(5,("Sent session request\n")); - - if (!cli_receive_smb(cli)) - return False; - - if (CVAL(cli->inbuf,0) == 0x84) { - /* C. Hoch 9/14/95 Start */ - /* For information, here is the response structure. - * We do the byte-twiddling to for portability. - struct RetargetResponse{ - unsigned char type; - unsigned char flags; - int16 length; - int32 ip_addr; - int16 port; - }; - */ - int port = (CVAL(cli->inbuf,8)<<8)+CVAL(cli->inbuf,9); - /* SESSION RETARGET */ - putip((char *)&cli->dest_ip,cli->inbuf+4); - - close_sockets(); - cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, port, LONG_CONNECT_TIMEOUT); - if (cli->fd == -1) - return False; - - DEBUG(3,("Retargeted\n")); - - set_socket_options(cli->fd,user_socket_options); - - /* Try again */ - return cli_session_request(cli, calling, called); - } /* C. Hoch 9/14/95 End */ - -#ifdef WITH_SSL - if (CVAL(cli->inbuf,0) == 0x83 && CVAL(cli->inbuf,4) == 0x8e){ /* use ssl */ - if (!sslutil_fd_is_ssl(cli->fd)){ - if (sslutil_connect(cli->fd) == 0) - goto retry; - } - } -#endif /* WITH_SSL */ - - if (CVAL(cli->inbuf,0) != 0x82) { - /* This is the wrong place to put the error... JRA. */ - cli->rap_error = CVAL(cli->inbuf,0); - return False; - } - return(True); -} - - -/**************************************************************************** -open the client sockets -****************************************************************************/ -BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) -{ - extern struct in_addr ipzero; - - fstrcpy(cli->desthost, host); - - if (!ip || ip_equal(*ip, ipzero)) { - if (!resolve_name( cli->desthost, &cli->dest_ip, 0x20)) { - return False; - } - if (ip) *ip = cli->dest_ip; - } else { - cli->dest_ip = *ip; - } - - if (cli -> port == 0) cli -> port = 139; /* Set to default */ - - cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, - cli -> port, cli->timeout); - if (cli->fd == -1) - return False; - - return True; -} - - -/**************************************************************************** -initialise a client structure -****************************************************************************/ -struct cli_state *cli_initialise(struct cli_state *cli) -{ - if (!cli) { - cli = (struct cli_state *)malloc(sizeof(*cli)); - if (!cli) - return NULL; - ZERO_STRUCTP(cli); - } - - if (cli->initialised) { - cli_shutdown(cli); - } - - ZERO_STRUCTP(cli); - - cli->port = 0; - cli->fd = -1; - cli->cnum = -1; - cli->pid = (uint16)getpid(); - cli->mid = 1; - cli->vuid = UID_FIELD_INVALID; - cli->protocol = PROTOCOL_NT1; - cli->timeout = 20000; /* Timeout is in milliseconds. */ - cli->bufsize = CLI_BUFFER_SIZE+4; - cli->max_xmit = cli->bufsize; - cli->outbuf = (char *)malloc(cli->bufsize); - cli->inbuf = (char *)malloc(cli->bufsize); - if (!cli->outbuf || !cli->inbuf) - { - return False; - } - - cli->initialised = 1; - - return cli; -} - -/**************************************************************************** -shutdown a client structure -****************************************************************************/ -void cli_shutdown(struct cli_state *cli) -{ - if (cli->outbuf) - { - free(cli->outbuf); - } - if (cli->inbuf) - { - free(cli->inbuf); - } -#ifdef WITH_SSL - if (cli->fd != -1) - sslutil_disconnect(cli->fd); -#endif /* WITH_SSL */ - if (cli->fd != -1) - close(cli->fd); - memset(cli, 0, sizeof(*cli)); -} - - -/**************************************************************************** - return error codes for the last packet - returns 0 if there was no error and the best approx of a unix errno - otherwise - - for 32 bit "warnings", a return code of 0 is expected. - -****************************************************************************/ -int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num, uint32 *nt_rpc_error) -{ - int flgs2 = SVAL(cli->inbuf,smb_flg2); - char rcls; - int code; - - if (eclass) *eclass = 0; - if (num ) *num = 0; - if (nt_rpc_error) *nt_rpc_error = cli->nt_error; - - if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) { - /* 32 bit error codes detected */ - uint32 nt_err = IVAL(cli->inbuf,smb_rcls); - if (num) *num = nt_err; - DEBUG(10,("cli_error: 32 bit codes: code=%08x\n", nt_err)); - if (!IS_BITS_SET_ALL(nt_err, 0xc0000000)) return 0; - - switch (nt_err & 0xFFFFFF) { - case NT_STATUS_ACCESS_VIOLATION: return EACCES; - case NT_STATUS_NO_SUCH_FILE: return ENOENT; - case NT_STATUS_NO_SUCH_DEVICE: return ENODEV; - case NT_STATUS_INVALID_HANDLE: return EBADF; - case NT_STATUS_NO_MEMORY: return ENOMEM; - case NT_STATUS_ACCESS_DENIED: return EACCES; - case NT_STATUS_OBJECT_NAME_NOT_FOUND: return ENOENT; - case NT_STATUS_SHARING_VIOLATION: return EBUSY; - case NT_STATUS_OBJECT_PATH_INVALID: return ENOTDIR; - case NT_STATUS_OBJECT_NAME_COLLISION: return EEXIST; - } - - /* for all other cases - a default code */ - return EINVAL; - } - - rcls = CVAL(cli->inbuf,smb_rcls); - code = SVAL(cli->inbuf,smb_err); - if (rcls == 0) return 0; - - if (eclass) *eclass = rcls; - if (num ) *num = code; - - if (rcls == ERRDOS) { - switch (code) { - case ERRbadfile: return ENOENT; - case ERRbadpath: return ENOTDIR; - case ERRnoaccess: return EACCES; - case ERRfilexists: return EEXIST; - case ERRrename: return EEXIST; - case ERRbadshare: return EBUSY; - case ERRlock: return EBUSY; - } - } - if (rcls == ERRSRV) { - switch (code) { - case ERRbadpw: return EPERM; - case ERRaccess: return EACCES; - case ERRnoresource: return ENOMEM; - case ERRinvdevice: return ENODEV; - case ERRinvnetname: return ENODEV; - } - } - /* for other cases */ - return EINVAL; -} - -/**************************************************************************** -set socket options on a open connection -****************************************************************************/ -void cli_sockopt(struct cli_state *cli, char *options) -{ - set_socket_options(cli->fd, options); -} - -/**************************************************************************** -set the PID to use for smb messages. Return the old pid. -****************************************************************************/ -uint16 cli_setpid(struct cli_state *cli, uint16 pid) -{ - uint16 ret = cli->pid; - cli->pid = pid; - return ret; -} - -/**************************************************************************** -re-establishes a connection -****************************************************************************/ -BOOL cli_reestablish_connection(struct cli_state *cli) -{ - struct nmb_name calling; - struct nmb_name called; - fstring dest_host; - fstring share; - fstring dev; - BOOL do_tcon = False; - int oldfd = cli->fd; - - if (!cli->initialised || cli->fd == -1) - { - DEBUG(3,("cli_reestablish_connection: not connected\n")); - return False; - } - - /* copy the parameters necessary to re-establish the connection */ - - if (cli->cnum != 0) - { - fstrcpy(share, cli->share); - fstrcpy(dev , cli->dev); - do_tcon = True; - } - - memcpy(&called , &(cli->called ), sizeof(called )); - memcpy(&calling, &(cli->calling), sizeof(calling)); - fstrcpy(dest_host, cli->full_dest_host_name); - - DEBUG(5,("cli_reestablish_connection: %s connecting to %s (ip %s) - %s [%s]\n", - nmb_namestr(&calling), nmb_namestr(&called), - inet_ntoa(cli->dest_ip), - cli->user_name, cli->domain)); - - cli->fd = -1; - - if (cli_establish_connection(cli, - dest_host, &cli->dest_ip, - &calling, &called, - share, dev, False, do_tcon)) { - if (cli->fd != oldfd) { - if (dup2(cli->fd, oldfd) == oldfd) { - close(cli->fd); - } - } - return True; - } - return False; -} - -/**************************************************************************** -establishes a connection right up to doing tconX, reading in a password. -****************************************************************************/ -BOOL cli_establish_connection(struct cli_state *cli, - char *dest_host, struct in_addr *dest_ip, - struct nmb_name *calling, struct nmb_name *called, - char *service, char *service_type, - BOOL do_shutdown, BOOL do_tcon) -{ - DEBUG(5,("cli_establish_connection: %s connecting to %s (%s) - %s [%s]\n", - nmb_namestr(calling), nmb_namestr(called), inet_ntoa(*dest_ip), - cli->user_name, cli->domain)); - - /* establish connection */ - - if ((!cli->initialised)) - { - return False; - } - - if (cli->fd == -1) - { - if (!cli_connect(cli, dest_host, dest_ip)) - { - DEBUG(1,("cli_establish_connection: failed to connect to %s (%s)\n", - nmb_namestr(calling), inet_ntoa(*dest_ip))); - return False; - } - } - - if (!cli_session_request(cli, calling, called)) - { - DEBUG(1,("failed session request\n")); - if (do_shutdown) - cli_shutdown(cli); - return False; - } - - if (!cli_negprot(cli)) - { - DEBUG(1,("failed negprot\n")); - if (do_shutdown) - cli_shutdown(cli); - return False; - } - - if (cli->pwd.cleartext || cli->pwd.null_pwd) - { - fstring passwd; - int pass_len; - - if (cli->pwd.null_pwd) - { - /* attempt null session */ - passwd[0] = 0; - pass_len = 1; - } - else - { - /* attempt clear-text session */ - pwd_get_cleartext(&(cli->pwd), passwd); - pass_len = strlen(passwd); - } - - /* attempt clear-text session */ - if (!cli_session_setup(cli, cli->user_name, - passwd, pass_len, - NULL, 0, - cli->domain)) - { - DEBUG(1,("failed session setup\n")); - if (do_shutdown) - { - cli_shutdown(cli); - } - return False; - } - if (do_tcon) - { - if (!cli_send_tconX(cli, service, service_type, - (char*)passwd, strlen(passwd))) - { - DEBUG(1,("failed tcon_X\n")); - if (do_shutdown) - { - cli_shutdown(cli); - } - return False; - } - } - } - else - { - /* attempt encrypted session */ - unsigned char nt_sess_pwd[24]; - unsigned char lm_sess_pwd[24]; - - /* creates (storing a copy of) and then obtains a 24 byte password OWF */ - pwd_make_lm_nt_owf(&(cli->pwd), cli->cryptkey); - pwd_get_lm_nt_owf(&(cli->pwd), lm_sess_pwd, nt_sess_pwd); - - /* attempt encrypted session */ - if (!cli_session_setup(cli, cli->user_name, - (char*)lm_sess_pwd, sizeof(lm_sess_pwd), - (char*)nt_sess_pwd, sizeof(nt_sess_pwd), - cli->domain)) - { - DEBUG(1,("failed session setup\n")); - if (do_shutdown) - cli_shutdown(cli); - return False; - } - - if (do_tcon) - { - if (!cli_send_tconX(cli, service, service_type, - (char*)nt_sess_pwd, sizeof(nt_sess_pwd))) - { - DEBUG(1,("failed tcon_X\n")); - if (do_shutdown) - cli_shutdown(cli); - return False; - } - } - } - - if (do_shutdown) - cli_shutdown(cli); - - return True; -} - - -/**************************************************************************** -check for existance of a dir -****************************************************************************/ -BOOL cli_chkpath(struct cli_state *cli, char *path) -{ - pstring path2; - char *p; - - safe_strcpy(path2,path,sizeof(pstring)-1); - trim_string(path2,NULL,"\\"); - if (!*path2) *path2 = '\\'; - - memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,0,4 + strlen(path2),True); - SCVAL(cli->outbuf,smb_com,SMBchkpth); - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - p = smb_buf(cli->outbuf); - *p++ = 4; - safe_strcpy(p,path2,strlen(path2)); - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return False; - } - - if (cli_error(cli, NULL, NULL, NULL)) return False; - - return True; -} - -#if 0 -/**************************************************************************** -start a message sequence -****************************************************************************/ -BOOL cli_message_start(struct cli_state *cli, char *host, char *username, - int *grp) -{ - char *p; - - /* send a SMBsendstrt command */ - memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,0,0,True); - CVAL(cli->outbuf,smb_com) = SMBsendstrt; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - p = smb_buf(cli->outbuf); - *p++ = 4; - pstrcpy(p,username); - p = skip_string(p,1); - *p++ = 4; - pstrcpy(p,host); - p = skip_string(p,1); - - set_message(cli->outbuf,0,PTR_DIFF(p,smb_buf(cli->outbuf)),False); - - cli_send_smb(cli); - - if (!cli_receive_smb(cli)) { - return False; - } - - if (cli_error(cli, NULL, NULL, NULL)) return False; - - *grp = SVAL(cli->inbuf,smb_vwv0); - - return True; -} - - -/**************************************************************************** -send a message -****************************************************************************/ -BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp) -{ - char *p; - - memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,1,len+3,True); - CVAL(cli->outbuf,smb_com) = SMBsendtxt; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - SSVAL(cli->outbuf,smb_vwv0,grp); - - p = smb_buf(cli->outbuf); - *p = 1; - SSVAL(p,1,len); - memcpy(p+3,msg,len); - cli_send_smb(cli); - - if (!cli_receive_smb(cli)) { - return False; - } - - if (cli_error(cli, NULL, NULL, NULL)) return False; - - return True; -} - -/**************************************************************************** -end a message -****************************************************************************/ -BOOL cli_message_end(struct cli_state *cli, int grp) -{ - memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,1,0,True); - CVAL(cli->outbuf,smb_com) = SMBsendend; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - - SSVAL(cli->outbuf,smb_vwv0,grp); - - cli_setup_packet(cli); - - cli_send_smb(cli); - - if (!cli_receive_smb(cli)) { - return False; - } - - if (cli_error(cli, NULL, NULL, NULL)) return False; - - return True; -} -#endif /*0 */ - -#if 0 /* May be useful one day */ -/**************************************************************************** -query disk space -****************************************************************************/ -BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail) -{ - memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,0,0,True); - CVAL(cli->outbuf,smb_com) = SMBdskattr; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return False; - } - - *bsize = SVAL(cli->inbuf,smb_vwv1)*SVAL(cli->inbuf,smb_vwv2); - *total = SVAL(cli->inbuf,smb_vwv0); - *avail = SVAL(cli->inbuf,smb_vwv3); - - return True; -} -#endif /* 0 */ +/* + Unix SMB/Netbios implementation. + Version 1.9. + SMB client generic functions + + Copyright (C) Andrew Tridgell 1994-1998 + + Copyright (C) 2011 + The Free Software Foundation, Inc. + + This file is part of the Midnight Commander. + + The Midnight Commander is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + The Midnight Commander is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + */ + +#define NO_SYSLOG + +#include "includes.h" +#include "trans2.h" + + +extern int DEBUGLEVEL; +extern pstring user_socket_options; + +/* + * Change the port number used to call on + */ +int +cli_set_port (struct cli_state *cli, int port) +{ + if (port > 0) + cli->port = port; + + return cli->port; +} + +/**************************************************************************** +recv an smb +****************************************************************************/ +static BOOL +cli_receive_smb (struct cli_state *cli) +{ + return client_receive_smb (cli->fd, cli->inbuf, cli->timeout); +} + +/**************************************************************************** + send an smb to a fd and re-establish if necessary +****************************************************************************/ +static BOOL +cli_send_smb (struct cli_state *cli) +{ + size_t len; + size_t nwritten = 0; + ssize_t ret; + BOOL reestablished = False; + + len = smb_len (cli->outbuf) + 4; + + while (nwritten < len) + { + ret = write_socket (cli->fd, cli->outbuf + nwritten, len - nwritten); + if (ret <= 0 && errno == EPIPE && !reestablished) + { + if (cli_reestablish_connection (cli)) + { + reestablished = True; + nwritten = 0; + continue; + } + } + if (ret <= 0) + { + DEBUG (0, ("Error writing %d bytes to client. %d. Exiting\n", (int) len, (int) ret)); + close_sockets (); + exit (1); + } + nwritten += ret; + } + + return True; +} + +/***************************************************** + RAP error codes - a small start but will be extended. +*******************************************************/ + +struct +{ + int err; + const char *message; +} const rap_errmap[] = { + {5, "User has insufficient privilege"}, + {86, "The specified password is invalid"}, + {2226, "Operation only permitted on a Primary Domain Controller"}, + {2242, "The password of this user has expired."}, + {2243, "The password of this user cannot change."}, + {2244, "This password cannot be used now (password history conflict)."}, + {2245, "The password is shorter than required."}, + {2246, "The password of this user is too recent to change."}, + {0, NULL} +}; + +/**************************************************************************** + return a description of an SMB error +****************************************************************************/ +static char * +cli_smb_errstr (struct cli_state *cli) +{ + return smb_errstr (cli->inbuf); +} + +/****************************************************** + Return an error message - either an SMB error or a RAP + error. +*******************************************************/ + +char * +cli_errstr (struct cli_state *cli) +{ + static fstring error_message; + uint8 errclass; + uint32 errnum; + uint32 nt_rpc_error; + int i; + + /* + * Errors are of three kinds - smb errors, + * dealt with by cli_smb_errstr, NT errors, + * whose code is in cli.nt_error, and rap + * errors, whose error code is in cli.rap_error. + */ + + cli_error (cli, &errclass, &errnum, &nt_rpc_error); + + if (errclass != 0) + { + return cli_smb_errstr (cli); + } + + /* + * Was it an NT error ? + */ + + if (nt_rpc_error) + { + const char *nt_msg = get_nt_error_msg (nt_rpc_error); + + if (nt_msg == NULL) + { + slprintf (error_message, sizeof (fstring) - 1, "NT code %d", nt_rpc_error); + } + else + { + fstrcpy (error_message, nt_msg); + } + + return error_message; + } + + /* + * Must have been a rap error. + */ + + slprintf (error_message, sizeof (error_message) - 1, "code %d", cli->rap_error); + + for (i = 0; rap_errmap[i].message != NULL; i++) + { + if (rap_errmap[i].err == cli->rap_error) + { + fstrcpy (error_message, rap_errmap[i].message); + break; + } + } + + return error_message; +} + +/**************************************************************************** +setup basics in a outgoing packet +****************************************************************************/ +static void +cli_setup_packet (struct cli_state *cli) +{ + cli->rap_error = 0; + cli->nt_error = 0; + SSVAL (cli->outbuf, smb_pid, cli->pid); + SSVAL (cli->outbuf, smb_uid, cli->vuid); + SSVAL (cli->outbuf, smb_mid, cli->mid); + if (cli->protocol > PROTOCOL_CORE) + { + SCVAL (cli->outbuf, smb_flg, 0x8); + SSVAL (cli->outbuf, smb_flg2, 0x1); + } +} + +#if 0 +/***************************************************************************** + Convert a character pointer in a cli_call_api() response to a form we can use. + This function contains code to prevent core dumps if the server returns + invalid data. +*****************************************************************************/ +static char * +fix_char_ptr (unsigned int datap, unsigned int converter, char *rdata, int rdrcnt) +{ + if (datap == 0) + { /* turn NULL pointers into zero length strings */ + return ""; + } + else + { + unsigned int offset = datap - converter; + + if (offset >= rdrcnt) + { + DEBUG (1, ("bad char ptr: datap=%u, converter=%u rdrcnt=%d>", + datap, converter, rdrcnt)); + return ""; + } + else + { + return &rdata[offset]; + } + } +} +#endif /* 0 */ +/**************************************************************************** + send a SMB trans or trans2 request + ****************************************************************************/ +static BOOL +cli_send_trans (struct cli_state *cli, int trans, + const char *name, int pipe_name_len, + int fid, int flags, + uint16 * setup, int lsetup, int msetup, + char *param, int lparam, int mparam, char *data, int ldata, int mdata) +{ + int i; + int this_ldata, this_lparam; + int tot_data = 0, tot_param = 0; + char *outdata, *outparam; + char *p; + + this_lparam = MIN (lparam, cli->max_xmit - (500 + lsetup * 2)); /* hack */ + this_ldata = MIN (ldata, cli->max_xmit - (500 + lsetup * 2 + this_lparam)); + + memset (cli->outbuf, '\0', smb_size); + set_message (cli->outbuf, 14 + lsetup, 0, True); + CVAL (cli->outbuf, smb_com) = trans; + SSVAL (cli->outbuf, smb_tid, cli->cnum); + cli_setup_packet (cli); + + outparam = smb_buf (cli->outbuf) + (trans == SMBtrans ? pipe_name_len + 1 : 3); + outdata = outparam + this_lparam; + + /* primary request */ + SSVAL (cli->outbuf, smb_tpscnt, lparam); /* tpscnt */ + SSVAL (cli->outbuf, smb_tdscnt, ldata); /* tdscnt */ + SSVAL (cli->outbuf, smb_mprcnt, mparam); /* mprcnt */ + SSVAL (cli->outbuf, smb_mdrcnt, mdata); /* mdrcnt */ + SCVAL (cli->outbuf, smb_msrcnt, msetup); /* msrcnt */ + SSVAL (cli->outbuf, smb_flags, flags); /* flags */ + SIVAL (cli->outbuf, smb_timeout, 0); /* timeout */ + SSVAL (cli->outbuf, smb_pscnt, this_lparam); /* pscnt */ + SSVAL (cli->outbuf, smb_psoff, smb_offset (outparam, cli->outbuf)); /* psoff */ + SSVAL (cli->outbuf, smb_dscnt, this_ldata); /* dscnt */ + SSVAL (cli->outbuf, smb_dsoff, smb_offset (outdata, cli->outbuf)); /* dsoff */ + SCVAL (cli->outbuf, smb_suwcnt, lsetup); /* suwcnt */ + for (i = 0; i < lsetup; i++) /* setup[] */ + SSVAL (cli->outbuf, smb_setup + i * 2, setup[i]); + p = smb_buf (cli->outbuf); + if (trans == SMBtrans) + { + memcpy (p, name, pipe_name_len + 1); /* name[] */ + } + else + { + *p++ = 0; /* put in a null smb_name */ + *p++ = 'D'; + *p++ = ' '; /* observed in OS/2 */ + } + if (this_lparam) /* param[] */ + memcpy (outparam, param, this_lparam); + if (this_ldata) /* data[] */ + memcpy (outdata, data, this_ldata); + set_message (cli->outbuf, 14 + lsetup, /* wcnt, bcc */ + PTR_DIFF (outdata + this_ldata, smb_buf (cli->outbuf)), False); + + show_msg (cli->outbuf); + cli_send_smb (cli); + + if (this_ldata < ldata || this_lparam < lparam) + { + /* receive interim response */ + if (!cli_receive_smb (cli) || CVAL (cli->inbuf, smb_rcls) != 0) + { + return (False); + } + + tot_data = this_ldata; + tot_param = this_lparam; + + while (tot_data < ldata || tot_param < lparam) + { + this_lparam = MIN (lparam - tot_param, cli->max_xmit - 500); /* hack */ + this_ldata = MIN (ldata - tot_data, cli->max_xmit - (500 + this_lparam)); + + set_message (cli->outbuf, trans == SMBtrans ? 8 : 9, 0, True); + CVAL (cli->outbuf, smb_com) = trans == SMBtrans ? SMBtranss : SMBtranss2; + + outparam = smb_buf (cli->outbuf); + outdata = outparam + this_lparam; + + /* secondary request */ + SSVAL (cli->outbuf, smb_tpscnt, lparam); /* tpscnt */ + SSVAL (cli->outbuf, smb_tdscnt, ldata); /* tdscnt */ + SSVAL (cli->outbuf, smb_spscnt, this_lparam); /* pscnt */ + SSVAL (cli->outbuf, smb_spsoff, smb_offset (outparam, cli->outbuf)); /* psoff */ + SSVAL (cli->outbuf, smb_spsdisp, tot_param); /* psdisp */ + SSVAL (cli->outbuf, smb_sdscnt, this_ldata); /* dscnt */ + SSVAL (cli->outbuf, smb_sdsoff, smb_offset (outdata, cli->outbuf)); /* dsoff */ + SSVAL (cli->outbuf, smb_sdsdisp, tot_data); /* dsdisp */ + if (trans == SMBtrans2) + SSVALS (cli->outbuf, smb_sfid, fid); /* fid */ + if (this_lparam) /* param[] */ + memcpy (outparam, param, this_lparam); + if (this_ldata) /* data[] */ + memcpy (outdata, data, this_ldata); + set_message (cli->outbuf, trans == SMBtrans ? 8 : 9, /* wcnt, bcc */ + PTR_DIFF (outdata + this_ldata, smb_buf (cli->outbuf)), False); + + show_msg (cli->outbuf); + cli_send_smb (cli); + + tot_data += this_ldata; + tot_param += this_lparam; + } + } + + return (True); +} + + +/**************************************************************************** + receive a SMB trans or trans2 response allocating the necessary memory + ****************************************************************************/ +static BOOL +cli_receive_trans (struct cli_state *cli, int trans, + char **param, int *param_len, char **data, int *data_len) +{ + int total_data = 0; + int total_param = 0; + int this_data, this_param; + uint8 eclass; + uint32 ecode; + + *data_len = *param_len = 0; + + if (!cli_receive_smb (cli)) + return False; + + show_msg (cli->inbuf); + + /* sanity check */ + if (CVAL (cli->inbuf, smb_com) != trans) + { + DEBUG (0, ("Expected %s response, got command 0x%02x\n", + trans == SMBtrans ? "SMBtrans" : "SMBtrans2", CVAL (cli->inbuf, smb_com))); + return (False); + } + + /* + * An NT RPC pipe call can return ERRDOS, ERRmoredata + * to a trans call. This is not an error and should not + * be treated as such. + */ + + if (cli_error (cli, &eclass, &ecode, NULL)) + { + if (cli->nt_pipe_fnum == 0 || !(eclass == ERRDOS && ecode == ERRmoredata)) + return (False); + } + + /* parse out the lengths */ + total_data = SVAL (cli->inbuf, smb_tdrcnt); + total_param = SVAL (cli->inbuf, smb_tprcnt); + + /* allocate it */ + *data = Realloc (*data, total_data); + *param = Realloc (*param, total_param); + + while (1) + { + this_data = SVAL (cli->inbuf, smb_drcnt); + this_param = SVAL (cli->inbuf, smb_prcnt); + + if (this_data + *data_len > total_data || this_param + *param_len > total_param) + { + DEBUG (1, ("Data overflow in cli_receive_trans\n")); + return False; + } + + if (this_data) + memcpy (*data + SVAL (cli->inbuf, smb_drdisp), + smb_base (cli->inbuf) + SVAL (cli->inbuf, smb_droff), this_data); + if (this_param) + memcpy (*param + SVAL (cli->inbuf, smb_prdisp), + smb_base (cli->inbuf) + SVAL (cli->inbuf, smb_proff), this_param); + *data_len += this_data; + *param_len += this_param; + + /* parse out the total lengths again - they can shrink! */ + total_data = SVAL (cli->inbuf, smb_tdrcnt); + total_param = SVAL (cli->inbuf, smb_tprcnt); + + if (total_data <= *data_len && total_param <= *param_len) + break; + + if (!cli_receive_smb (cli)) + return False; + + show_msg (cli->inbuf); + + /* sanity check */ + if (CVAL (cli->inbuf, smb_com) != trans) + { + DEBUG (0, ("Expected %s response, got command 0x%02x\n", + trans == SMBtrans ? "SMBtrans" : "SMBtrans2", CVAL (cli->inbuf, smb_com))); + return (False); + } + if (cli_error (cli, &eclass, &ecode, NULL)) + { + if (cli->nt_pipe_fnum == 0 || !(eclass == ERRDOS && ecode == ERRmoredata)) + return (False); + } + } + + return (True); +} + +#if 0 +/**************************************************************************** +Call a remote api on an arbitrary pipe. takes param, data and setup buffers. +****************************************************************************/ +BOOL +cli_api_pipe (struct cli_state * cli, char *pipe_name, int pipe_name_len, + uint16 * setup, uint32 setup_count, uint32 max_setup_count, + char *params, uint32 param_count, uint32 max_param_count, + char *data, uint32 data_count, uint32 max_data_count, + char **rparam, uint32 * rparam_count, char **rdata, uint32 * rdata_count) +{ + if (pipe_name_len == 0) + pipe_name_len = strlen (pipe_name); + + cli_send_trans (cli, SMBtrans, pipe_name, pipe_name_len, 0, 0, /* fid, flags */ + setup, setup_count, max_setup_count, + params, param_count, max_param_count, data, data_count, max_data_count); + + return (cli_receive_trans (cli, SMBtrans, + rparam, (int *) rparam_count, rdata, (int *) rdata_count)); +} +#endif /*0 */ + +/**************************************************************************** +call a remote api +****************************************************************************/ +BOOL +cli_api (struct cli_state *cli, + char *param, int prcnt, int mprcnt, + char *data, int drcnt, int mdrcnt, char **rparam, int *rprcnt, char **rdata, int *rdrcnt) +{ + cli_send_trans (cli, SMBtrans, PIPE_LANMAN, strlen (PIPE_LANMAN), /* Name, length */ + 0, 0, /* fid, flags */ + NULL, 0, 0, /* Setup, length, max */ + param, prcnt, mprcnt, /* Params, length, max */ + data, drcnt, mdrcnt /* Data, length, max */ + ); + + return (cli_receive_trans (cli, SMBtrans, rparam, rprcnt, rdata, rdrcnt)); +} + +#if 0 +/**************************************************************************** +perform a NetWkstaUserLogon +****************************************************************************/ +BOOL +cli_NetWkstaUserLogon (struct cli_state * cli, char *user, char *workstation) +{ + char *rparam = NULL; + char *rdata = NULL; + char *p; + int rdrcnt, rprcnt; + pstring param; + + memset (param, 0, sizeof (param)); + + /* send a SMBtrans command with api NetWkstaUserLogon */ + p = param; + SSVAL (p, 0, 132); /* api number */ + p += 2; + pstrcpy (p, "OOWb54WrLh"); + p = skip_string (p, 1); + pstrcpy (p, "WB21BWDWWDDDDDDDzzzD"); + p = skip_string (p, 1); + SSVAL (p, 0, 1); + p += 2; + pstrcpy (p, user); + strupper (p); + p += 21; + p++; + p += 15; + p++; + pstrcpy (p, workstation); + strupper (p); + p += 16; + SSVAL (p, 0, CLI_BUFFER_SIZE); + p += 2; + SSVAL (p, 0, CLI_BUFFER_SIZE); + p += 2; + + if (cli_api (cli, param, PTR_DIFF (p, param), 1024, /* param, length, max */ + NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */ + &rparam, &rprcnt, /* return params, return size */ + &rdata, &rdrcnt /* return data, return size */ + )) + { + cli->rap_error = SVAL (rparam, 0); + p = rdata; + + if (cli->rap_error == 0) + { + DEBUG (4, ("NetWkstaUserLogon success\n")); + cli->privileges = SVAL (p, 24); + fstrcpy (cli->eff_name, p + 2); + } + else + { + DEBUG (1, ("NetwkstaUserLogon gave error %d\n", cli->rap_error)); + } + } + + if (rparam) + free (rparam); + if (rdata) + free (rdata); + return (cli->rap_error == 0); +} +#endif /*0 */ + +/**************************************************************************** +call a NetShareEnum - try and browse available connections on a host +****************************************************************************/ +int +cli_RNetShareEnum (struct cli_state *cli, void (*fn) (const char *, uint32, const char *, void *), + void *state) +{ + char *rparam = NULL; + char *rdata = NULL; + char *p; + int rdrcnt, rprcnt; + pstring param; + int count = -1; + + /* now send a SMBtrans command with api RNetShareEnum */ + p = param; + SSVAL (p, 0, 0); /* api number */ + p += 2; + pstrcpy (p, "WrLeh"); + p = skip_string (p, 1); + pstrcpy (p, "B13BWz"); + p = skip_string (p, 1); + SSVAL (p, 0, 1); + /* + * Win2k needs a *smaller* buffer than 0xFFFF here - + * it returns "out of server memory" with 0xFFFF !!! JRA. + */ + SSVAL (p, 2, 0xFFE0); + p += 4; + + if (cli_api (cli, param, PTR_DIFF (p, param), 1024, /* Param, length, maxlen */ + NULL, 0, 0xFFE0, /* data, length, maxlen - Win2k needs a small buffer here too ! */ + &rparam, &rprcnt, /* return params, length */ + &rdata, &rdrcnt)) /* return data, length */ + { + int res = SVAL (rparam, 0); + int converter = SVAL (rparam, 2); + int i; + + if (res == 0 || res == ERRmoredata) + { + count = SVAL (rparam, 4); + p = rdata; + + for (i = 0; i < count; i++, p += 20) + { + char *sname = p; + int type = SVAL (p, 14); + int comment_offset = IVAL (p, 16) & 0xFFFF; + const char *cmnt = comment_offset ? (rdata + comment_offset - converter) : ""; + fn (sname, type, cmnt, state); + } + } + else + { + DEBUG (4, ("NetShareEnum res=%d\n", res)); + } + } + else + { + DEBUG (4, ("NetShareEnum failed\n")); + } + + if (rparam) + free (rparam); + if (rdata) + free (rdata); + + return count; +} + + +/**************************************************************************** +call a NetServerEnum for the specified workgroup and servertype mask. +This function then calls the specified callback function for each name returned. + +The callback function takes 3 arguments: the machine name, the server type and +the comment. +****************************************************************************/ +BOOL +cli_NetServerEnum (struct cli_state * cli, char *workgroup, uint32 stype, + void (*fn) (const char *, uint32, const char *, void *), void *state) +{ + char *rparam = NULL; + char *rdata = NULL; + int rdrcnt, rprcnt; + char *p; + pstring param; + int uLevel = 1; + int count = -1; + + /* send a SMBtrans command with api NetServerEnum */ + p = param; + SSVAL (p, 0, 0x68); /* api number */ + p += 2; + pstrcpy (p, "WrLehDz"); + p = skip_string (p, 1); + + pstrcpy (p, "B16BBDz"); + + p = skip_string (p, 1); + SSVAL (p, 0, uLevel); + SSVAL (p, 2, CLI_BUFFER_SIZE); + p += 4; + SIVAL (p, 0, stype); + p += 4; + + pstrcpy (p, workgroup); + p = skip_string (p, 1); + + if (cli_api (cli, param, PTR_DIFF (p, param), 8, /* params, length, max */ + NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */ + &rparam, &rprcnt, /* return params, return size */ + &rdata, &rdrcnt /* return data, return size */ + )) + { + int res = SVAL (rparam, 0); + int converter = SVAL (rparam, 2); + int i; + + if (res == 0 || res == ERRmoredata) + { + count = SVAL (rparam, 4); + p = rdata; + + for (i = 0; i < count; i++, p += 26) + { + char *sname = p; + int comment_offset = (IVAL (p, 22) & 0xFFFF) - converter; + const char *cmnt = comment_offset ? (rdata + comment_offset) : ""; + if (comment_offset < 0 || comment_offset > rdrcnt) + continue; + + stype = IVAL (p, 18) & ~SV_TYPE_LOCAL_LIST_ONLY; + + fn (sname, stype, cmnt, state); + } + } + } + + if (rparam) + free (rparam); + if (rdata) + free (rdata); + + return (count > 0); +} + + + + +static struct +{ + int prot; + const char *name; +} +const prots[] = { + {PROTOCOL_CORE, "PC NETWORK PROGRAM 1.0"}, + {PROTOCOL_COREPLUS, "MICROSOFT NETWORKS 1.03"}, + {PROTOCOL_LANMAN1, "MICROSOFT NETWORKS 3.0"}, + {PROTOCOL_LANMAN1, "LANMAN1.0"}, + {PROTOCOL_LANMAN2, "LM1.2X002"}, + {PROTOCOL_LANMAN2, "Samba"}, + {PROTOCOL_NT1, "NT LANMAN 1.0"}, + {PROTOCOL_NT1, "NT LM 0.12"}, + {-1, NULL} +}; + + +/**************************************************************************** +send a session setup +****************************************************************************/ +BOOL +cli_session_setup (struct cli_state *cli, + char *user, + char *pass, int passlen, char *ntpass, int ntpasslen, char *workgroup) +{ + char *p; + fstring pword, ntpword; + + if (cli->protocol < PROTOCOL_LANMAN1) + return True; + + if ((size_t) passlen > sizeof (pword) - 1 || (size_t) ntpasslen > sizeof (ntpword) - 1) + { + return False; + } + + if (((passlen == 0) || (passlen == 1)) && (pass[0] == '\0')) + { + /* Null session connect. */ + pword[0] = '\0'; + ntpword[0] = '\0'; + } + else + { + if ((cli->sec_mode & 2) && passlen != 24) + { + passlen = 24; + ntpasslen = 24; + SMBencrypt ((uchar *) pass, (uchar *) cli->cryptkey, (uchar *) pword); + SMBNTencrypt ((uchar *) ntpass, (uchar *) cli->cryptkey, (uchar *) ntpword); + } + else + { + fstrcpy (pword, pass); + fstrcpy (ntpword, ""); + ntpasslen = 0; + } + } + + /* if in share level security then don't send a password now */ + if (!(cli->sec_mode & 1)) + { + fstrcpy (pword, ""); + passlen = 1; + fstrcpy (ntpword, ""); + ntpasslen = 1; + } + + /* send a session setup command */ + memset (cli->outbuf, '\0', smb_size); + + if (cli->protocol < PROTOCOL_NT1) + { + set_message (cli->outbuf, 10, 1 + strlen (user) + passlen, True); + CVAL (cli->outbuf, smb_com) = SMBsesssetupX; + cli_setup_packet (cli); + + CVAL (cli->outbuf, smb_vwv0) = 0xFF; + SSVAL (cli->outbuf, smb_vwv2, cli->max_xmit); + SSVAL (cli->outbuf, smb_vwv3, 2); + SSVAL (cli->outbuf, smb_vwv4, 1); + SIVAL (cli->outbuf, smb_vwv5, cli->sesskey); + SSVAL (cli->outbuf, smb_vwv7, passlen); + p = smb_buf (cli->outbuf); + memcpy (p, pword, passlen); + p += passlen; + pstrcpy (p, user); + strupper (p); + unix_to_dos (p, True); + } + else + { + set_message (cli->outbuf, 13, 0, True); + CVAL (cli->outbuf, smb_com) = SMBsesssetupX; + cli_setup_packet (cli); + + CVAL (cli->outbuf, smb_vwv0) = 0xFF; + SSVAL (cli->outbuf, smb_vwv2, CLI_BUFFER_SIZE); + SSVAL (cli->outbuf, smb_vwv3, 2); + SSVAL (cli->outbuf, smb_vwv4, cli->pid); + SIVAL (cli->outbuf, smb_vwv5, cli->sesskey); + SSVAL (cli->outbuf, smb_vwv7, passlen); + SSVAL (cli->outbuf, smb_vwv8, ntpasslen); + SSVAL (cli->outbuf, smb_vwv11, 0); + p = smb_buf (cli->outbuf); + memcpy (p, pword, passlen); + p += SVAL (cli->outbuf, smb_vwv7); + memcpy (p, ntpword, ntpasslen); + p += SVAL (cli->outbuf, smb_vwv8); + pstrcpy (p, user); + strupper (p); + unix_to_dos (p, True); + p = skip_string (p, 1); + pstrcpy (p, workgroup); + strupper (p); + p = skip_string (p, 1); + pstrcpy (p, "Unix"); + p = skip_string (p, 1); + pstrcpy (p, "Samba"); + p = skip_string (p, 1); + set_message (cli->outbuf, 13, PTR_DIFF (p, smb_buf (cli->outbuf)), False); + } + + cli_send_smb (cli); + if (!cli_receive_smb (cli)) + return False; + + show_msg (cli->inbuf); + + if (CVAL (cli->inbuf, smb_rcls) != 0) + { + return False; + } + + /* use the returned vuid from now on */ + cli->vuid = SVAL (cli->inbuf, smb_uid); + + if (cli->protocol >= PROTOCOL_NT1) + { + /* + * Save off some of the connected server + * info. + */ + char *server_domain, *server_os, *server_type; + server_os = smb_buf (cli->inbuf); + server_type = skip_string (server_os, 1); + server_domain = skip_string (server_type, 1); + fstrcpy (cli->server_os, server_os); + fstrcpy (cli->server_type, server_type); + fstrcpy (cli->server_domain, server_domain); + } + + fstrcpy (cli->user_name, user); + + return True; +} + +/**************************************************************************** + Send a uloggoff. +*****************************************************************************/ +#if 0 +BOOL +cli_ulogoff (struct cli_state * cli) +{ + memset (cli->outbuf, '\0', smb_size); + set_message (cli->outbuf, 2, 0, True); + CVAL (cli->outbuf, smb_com) = SMBulogoffX; + cli_setup_packet (cli); + SSVAL (cli->outbuf, smb_vwv0, 0xFF); + SSVAL (cli->outbuf, smb_vwv2, 0); /* no additional info */ + + cli_send_smb (cli); + if (!cli_receive_smb (cli)) + return False; + + return CVAL (cli->inbuf, smb_rcls) == 0; +} +#endif /*0 */ + +/**************************************************************************** +send a tconX +****************************************************************************/ +BOOL +cli_send_tconX (struct cli_state * cli, + const char *share, const char *dev, const char *pass, int passlen) +{ + fstring fullshare, pword; + char *p; + memset (cli->outbuf, '\0', smb_size); + memset (cli->inbuf, '\0', smb_size); + + fstrcpy (cli->share, share); + + /* in user level security don't send a password now */ + if (cli->sec_mode & 1) + { + passlen = 1; + pass = ""; + } + + if ((cli->sec_mode & 2) && *pass && passlen != 24) + { + passlen = 24; + SMBencrypt ((uchar *) pass, (uchar *) cli->cryptkey, (uchar *) pword); + } + else + { + memcpy (pword, pass, passlen); + } + + slprintf (fullshare, sizeof (fullshare) - 1, "\\\\%s\\%s", cli->desthost, share); + unix_to_dos (fullshare, True); + strupper (fullshare); + + set_message (cli->outbuf, 4, 2 + strlen (fullshare) + passlen + strlen (dev), True); + CVAL (cli->outbuf, smb_com) = SMBtconX; + cli_setup_packet (cli); + + SSVAL (cli->outbuf, smb_vwv0, 0xFF); + SSVAL (cli->outbuf, smb_vwv3, passlen); + + p = smb_buf (cli->outbuf); + memcpy (p, pword, passlen); + p += passlen; + fstrcpy (p, fullshare); + p = skip_string (p, 1); + pstrcpy (p, dev); + + SCVAL (cli->inbuf, smb_rcls, 1); + + cli_send_smb (cli); + if (!cli_receive_smb (cli)) + return False; + + if (CVAL (cli->inbuf, smb_rcls) != 0) + { + return False; + } + + fstrcpy (cli->dev, "A:"); + + if (cli->protocol >= PROTOCOL_NT1) + { + fstrcpy (cli->dev, smb_buf (cli->inbuf)); + } + + if (strcasecmp (share, "IPC$") == 0) + { + fstrcpy (cli->dev, "IPC"); + } + + /* only grab the device if we have a recent protocol level */ + if (cli->protocol >= PROTOCOL_NT1 && smb_buflen (cli->inbuf) == 3) + { + /* almost certainly win95 - enable bug fixes */ + cli->win95 = True; + } + + cli->cnum = SVAL (cli->inbuf, smb_tid); + return True; +} + +#if 0 +/**************************************************************************** +send a tree disconnect +****************************************************************************/ +BOOL +cli_tdis (struct cli_state * cli) +{ + memset (cli->outbuf, '\0', smb_size); + set_message (cli->outbuf, 0, 0, True); + CVAL (cli->outbuf, smb_com) = SMBtdis; + SSVAL (cli->outbuf, smb_tid, cli->cnum); + cli_setup_packet (cli); + + cli_send_smb (cli); + if (!cli_receive_smb (cli)) + return False; + + return CVAL (cli->inbuf, smb_rcls) == 0; +} +#endif /*0 */ + +/**************************************************************************** +rename a file +****************************************************************************/ +BOOL +cli_rename (struct cli_state * cli, char *fname_src, char *fname_dst) +{ + char *p; + + memset (cli->outbuf, '\0', smb_size); + memset (cli->inbuf, '\0', smb_size); + + set_message (cli->outbuf, 1, 4 + strlen (fname_src) + strlen (fname_dst), True); + + CVAL (cli->outbuf, smb_com) = SMBmv; + SSVAL (cli->outbuf, smb_tid, cli->cnum); + cli_setup_packet (cli); + + SSVAL (cli->outbuf, smb_vwv0, aSYSTEM | aHIDDEN); + + p = smb_buf (cli->outbuf); + *p++ = 4; + pstrcpy (p, fname_src); + p = skip_string (p, 1); + *p++ = 4; + pstrcpy (p, fname_dst); + + cli_send_smb (cli); + if (!cli_receive_smb (cli)) + { + return False; + } + + if (CVAL (cli->inbuf, smb_rcls) != 0) + { + return False; + } + + return True; +} + +/**************************************************************************** +delete a file +****************************************************************************/ +BOOL +cli_unlink (struct cli_state * cli, char *fname) +{ + char *p; + + memset (cli->outbuf, '\0', smb_size); + memset (cli->inbuf, '\0', smb_size); + + set_message (cli->outbuf, 1, 2 + strlen (fname), True); + + CVAL (cli->outbuf, smb_com) = SMBunlink; + SSVAL (cli->outbuf, smb_tid, cli->cnum); + cli_setup_packet (cli); + + SSVAL (cli->outbuf, smb_vwv0, aSYSTEM | aHIDDEN); + + p = smb_buf (cli->outbuf); + *p++ = 4; + pstrcpy (p, fname); + + cli_send_smb (cli); + if (!cli_receive_smb (cli)) + { + return False; + } + + if (CVAL (cli->inbuf, smb_rcls) != 0) + { + return False; + } + + return True; +} + +/**************************************************************************** +create a directory +****************************************************************************/ +BOOL +cli_mkdir (struct cli_state * cli, char *dname) +{ + char *p; + + memset (cli->outbuf, '\0', smb_size); + memset (cli->inbuf, '\0', smb_size); + + set_message (cli->outbuf, 0, 2 + strlen (dname), True); + + CVAL (cli->outbuf, smb_com) = SMBmkdir; + SSVAL (cli->outbuf, smb_tid, cli->cnum); + cli_setup_packet (cli); + + p = smb_buf (cli->outbuf); + *p++ = 4; + pstrcpy (p, dname); + + cli_send_smb (cli); + if (!cli_receive_smb (cli)) + { + return False; + } + + if (CVAL (cli->inbuf, smb_rcls) != 0) + { + return False; + } + + return True; +} + +/**************************************************************************** +remove a directory +****************************************************************************/ +BOOL +cli_rmdir (struct cli_state * cli, char *dname) +{ + char *p; + + memset (cli->outbuf, '\0', smb_size); + memset (cli->inbuf, '\0', smb_size); + + set_message (cli->outbuf, 0, 2 + strlen (dname), True); + + CVAL (cli->outbuf, smb_com) = SMBrmdir; + SSVAL (cli->outbuf, smb_tid, cli->cnum); + cli_setup_packet (cli); + + p = smb_buf (cli->outbuf); + *p++ = 4; + pstrcpy (p, dname); + + cli_send_smb (cli); + if (!cli_receive_smb (cli)) + { + return False; + } + + if (CVAL (cli->inbuf, smb_rcls) != 0) + { + return False; + } + + return True; +} + +#if 0 +/**************************************************************************** +open a file +****************************************************************************/ +int +cli_nt_create (struct cli_state *cli, char *fname) +{ + char *p; + + memset (cli->outbuf, '\0', smb_size); + memset (cli->inbuf, '\0', smb_size); + + set_message (cli->outbuf, 24, 1 + strlen (fname), True); + + CVAL (cli->outbuf, smb_com) = SMBntcreateX; + SSVAL (cli->outbuf, smb_tid, cli->cnum); + cli_setup_packet (cli); + + SSVAL (cli->outbuf, smb_vwv0, 0xFF); + SIVAL (cli->outbuf, smb_ntcreate_Flags, 0x06); + SIVAL (cli->outbuf, smb_ntcreate_RootDirectoryFid, 0x0); + SIVAL (cli->outbuf, smb_ntcreate_DesiredAccess, 0x2019f); + SIVAL (cli->outbuf, smb_ntcreate_FileAttributes, 0x0); + SIVAL (cli->outbuf, smb_ntcreate_ShareAccess, 0x03); + SIVAL (cli->outbuf, smb_ntcreate_CreateDisposition, 0x01); + SIVAL (cli->outbuf, smb_ntcreate_CreateOptions, 0x0); + SIVAL (cli->outbuf, smb_ntcreate_ImpersonationLevel, 0x02); + SSVAL (cli->outbuf, smb_ntcreate_NameLength, strlen (fname)); + + p = smb_buf (cli->outbuf); + pstrcpy (p, fname); + p = skip_string (p, 1); + + cli_send_smb (cli); + if (!cli_receive_smb (cli)) + { + return -1; + } + + if (CVAL (cli->inbuf, smb_rcls) != 0) + { + return -1; + } + + return SVAL (cli->inbuf, smb_vwv2 + 1); +} +#endif /*0 */ + +/**************************************************************************** +open a file +****************************************************************************/ +int +cli_open (struct cli_state *cli, char *fname, int flags, int share_mode) +{ + char *p; + unsigned openfn = 0; + unsigned accessmode = 0; + + /* you must open for RW not just write - otherwise getattrE doesn't + work! */ + if ((flags & O_ACCMODE) == O_WRONLY && strncmp (cli->dev, "LPT", 3)) + { + flags = (flags & ~O_ACCMODE) | O_RDWR; + } + + if (flags & O_CREAT) + openfn |= (1 << 4); + if (!(flags & O_EXCL)) + { + if (flags & O_TRUNC) + openfn |= (1 << 1); + else + openfn |= (1 << 0); + } + + accessmode = (share_mode << 4); + + if ((flags & O_ACCMODE) == O_RDWR) + { + accessmode |= 2; + } + else if ((flags & O_ACCMODE) == O_WRONLY) + { + accessmode |= 1; + } + +#if defined(O_SYNC) + if ((flags & O_SYNC) == O_SYNC) + { + accessmode |= (1 << 14); + } +#endif /* O_SYNC */ + + memset (cli->outbuf, '\0', smb_size); + memset (cli->inbuf, '\0', smb_size); + + set_message (cli->outbuf, 15, 1 + strlen (fname), True); + + CVAL (cli->outbuf, smb_com) = SMBopenX; + SSVAL (cli->outbuf, smb_tid, cli->cnum); + cli_setup_packet (cli); + + SSVAL (cli->outbuf, smb_vwv0, 0xFF); + SSVAL (cli->outbuf, smb_vwv2, 0); /* no additional info */ + SSVAL (cli->outbuf, smb_vwv3, accessmode); + SSVAL (cli->outbuf, smb_vwv4, aSYSTEM | aHIDDEN); + SSVAL (cli->outbuf, smb_vwv5, 0); + SSVAL (cli->outbuf, smb_vwv8, openfn); + + p = smb_buf (cli->outbuf); + pstrcpy (p, fname); + p = skip_string (p, 1); + + cli_send_smb (cli); + if (!cli_receive_smb (cli)) + { + return -1; + } + + if (CVAL (cli->inbuf, smb_rcls) != 0) + { + return -1; + } + + return SVAL (cli->inbuf, smb_vwv2); +} + + + + +/**************************************************************************** + close a file +****************************************************************************/ +BOOL +cli_close (struct cli_state * cli, int fnum) +{ + memset (cli->outbuf, '\0', smb_size); + memset (cli->inbuf, '\0', smb_size); + + set_message (cli->outbuf, 3, 0, True); + + CVAL (cli->outbuf, smb_com) = SMBclose; + SSVAL (cli->outbuf, smb_tid, cli->cnum); + cli_setup_packet (cli); + + SSVAL (cli->outbuf, smb_vwv0, fnum); + SIVALS (cli->outbuf, smb_vwv1, -1); + + cli_send_smb (cli); + if (!cli_receive_smb (cli)) + { + return False; + } + + if (CVAL (cli->inbuf, smb_rcls) != 0) + { + return False; + } + + return True; +} + +#if 0 +/**************************************************************************** + lock a file +****************************************************************************/ +BOOL +cli_lock (struct cli_state * cli, int fnum, uint32 offset, uint32 len, int timeout) +{ + char *p; + int saved_timeout = cli->timeout; + + memset (cli->outbuf, '\0', smb_size); + memset (cli->inbuf, '\0', smb_size); + + set_message (cli->outbuf, 8, 10, True); + + CVAL (cli->outbuf, smb_com) = SMBlockingX; + SSVAL (cli->outbuf, smb_tid, cli->cnum); + cli_setup_packet (cli); + + CVAL (cli->outbuf, smb_vwv0) = 0xFF; + SSVAL (cli->outbuf, smb_vwv2, fnum); + CVAL (cli->outbuf, smb_vwv3) = 0; + SIVALS (cli->outbuf, smb_vwv4, timeout); + SSVAL (cli->outbuf, smb_vwv6, 0); + SSVAL (cli->outbuf, smb_vwv7, 1); + + p = smb_buf (cli->outbuf); + SSVAL (p, 0, cli->pid); + SIVAL (p, 2, offset); + SIVAL (p, 6, len); + cli_send_smb (cli); + + cli->timeout = (timeout == -1) ? 0x7FFFFFFF : timeout; + + if (!cli_receive_smb (cli)) + { + cli->timeout = saved_timeout; + return False; + } + + cli->timeout = saved_timeout; + + if (CVAL (cli->inbuf, smb_rcls) != 0) + { + return False; + } + + return True; +} + +/**************************************************************************** + unlock a file +****************************************************************************/ +BOOL +cli_unlock (struct cli_state * cli, int fnum, uint32 offset, uint32 len, int timeout) +{ + char *p; + + memset (cli->outbuf, '\0', smb_size); + memset (cli->inbuf, '\0', smb_size); + + set_message (cli->outbuf, 8, 10, True); + + CVAL (cli->outbuf, smb_com) = SMBlockingX; + SSVAL (cli->outbuf, smb_tid, cli->cnum); + cli_setup_packet (cli); + + CVAL (cli->outbuf, smb_vwv0) = 0xFF; + SSVAL (cli->outbuf, smb_vwv2, fnum); + CVAL (cli->outbuf, smb_vwv3) = 0; + SIVALS (cli->outbuf, smb_vwv4, timeout); + SSVAL (cli->outbuf, smb_vwv6, 1); + SSVAL (cli->outbuf, smb_vwv7, 0); + + p = smb_buf (cli->outbuf); + SSVAL (p, 0, cli->pid); + SIVAL (p, 2, offset); + SIVAL (p, 6, len); + + cli_send_smb (cli); + if (!cli_receive_smb (cli)) + { + return False; + } + + if (CVAL (cli->inbuf, smb_rcls) != 0) + { + return False; + } + + return True; +} +#endif /*0 */ + + +/**************************************************************************** +issue a single SMBread and don't wait for a reply +****************************************************************************/ +static void +cli_issue_read (struct cli_state *cli, int fnum, off_t offset, size_t size, int i) +{ + memset (cli->outbuf, '\0', smb_size); + memset (cli->inbuf, '\0', smb_size); + + set_message (cli->outbuf, 10, 0, True); + + CVAL (cli->outbuf, smb_com) = SMBreadX; + SSVAL (cli->outbuf, smb_tid, cli->cnum); + cli_setup_packet (cli); + + CVAL (cli->outbuf, smb_vwv0) = 0xFF; + SSVAL (cli->outbuf, smb_vwv2, fnum); + SIVAL (cli->outbuf, smb_vwv3, offset); + SSVAL (cli->outbuf, smb_vwv5, size); + SSVAL (cli->outbuf, smb_vwv6, size); + SSVAL (cli->outbuf, smb_mid, cli->mid + i); + + cli_send_smb (cli); +} + +/**************************************************************************** + read from a file +****************************************************************************/ +size_t +cli_read (struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size) +{ + char *p; + int total = -1; + int issued = 0; + int received = 0; + int mpx = MAX (cli->max_mux - 1, 1); + int block = (cli->max_xmit - (smb_size + 32)) & ~1023; + int mid; + int blocks = (size + (block - 1)) / block; + + if (size == 0) + return 0; + + while (received < blocks) + { + int size2; + + while (issued - received < mpx && issued < blocks) + { + int size1 = MIN (block, (int) size - issued * block); + cli_issue_read (cli, fnum, offset + issued * block, size1, issued); + issued++; + } + + if (!cli_receive_smb (cli)) + { + return total; + } + + received++; + mid = SVAL (cli->inbuf, smb_mid) - cli->mid; + size2 = SVAL (cli->inbuf, smb_vwv5); + + if (CVAL (cli->inbuf, smb_rcls) != 0) + { + blocks = MIN (blocks, mid - 1); + continue; + } + + if (size2 <= 0) + { + blocks = MIN (blocks, mid - 1); + /* this distinguishes EOF from an error */ + total = MAX (total, 0); + continue; + } + + if (size2 > block) + { + DEBUG (0, ("server returned more than we wanted!\n")); + exit (1); + } + if (mid >= issued) + { + DEBUG (0, ("invalid mid from server!\n")); + exit (1); + } + p = smb_base (cli->inbuf) + SVAL (cli->inbuf, smb_vwv6); + + memcpy (buf + mid * block, p, size2); + + total = MAX (total, mid * block + size2); + } + + while (received < issued) + { + cli_receive_smb (cli); + received++; + } + + return total; +} + + +/**************************************************************************** +issue a single SMBwrite and don't wait for a reply +****************************************************************************/ +static void +cli_issue_write (struct cli_state *cli, int fnum, off_t offset, uint16 mode, const char *buf, + size_t size, int i) +{ + char *p; + + memset (cli->outbuf, '\0', smb_size); + memset (cli->inbuf, '\0', smb_size); + + set_message (cli->outbuf, 12, size, True); + + CVAL (cli->outbuf, smb_com) = SMBwriteX; + SSVAL (cli->outbuf, smb_tid, cli->cnum); + cli_setup_packet (cli); + + CVAL (cli->outbuf, smb_vwv0) = 0xFF; + SSVAL (cli->outbuf, smb_vwv2, fnum); + + SIVAL (cli->outbuf, smb_vwv3, offset); + SIVAL (cli->outbuf, smb_vwv5, IS_BITS_SET_ALL (mode, 0x0008) ? 0xFFFFFFFF : 0); + SSVAL (cli->outbuf, smb_vwv7, mode); + + SSVAL (cli->outbuf, smb_vwv8, IS_BITS_SET_ALL (mode, 0x0008) ? size : 0); + SSVAL (cli->outbuf, smb_vwv10, size); + SSVAL (cli->outbuf, smb_vwv11, smb_buf (cli->outbuf) - smb_base (cli->outbuf)); + + p = smb_base (cli->outbuf) + SVAL (cli->outbuf, smb_vwv11); + memcpy (p, buf, size); + + SSVAL (cli->outbuf, smb_mid, cli->mid + i); + + show_msg (cli->outbuf); + cli_send_smb (cli); +} + +/**************************************************************************** + write to a file + write_mode: 0x0001 disallow write cacheing + 0x0002 return bytes remaining + 0x0004 use raw named pipe protocol + 0x0008 start of message mode named pipe protocol +****************************************************************************/ +ssize_t +cli_write (struct cli_state *cli, + int fnum, uint16 write_mode, const char *buf, off_t offset, size_t size) +{ + int bwritten = 0; + int issued = 0; + int received = 0; + int mpx = MAX (cli->max_mux - 1, 1); + int block = (cli->max_xmit - (smb_size + 32)) & ~1023; + int blocks = (size + (block - 1)) / block; + + while (received < blocks) + { + + while ((issued - received < mpx) && (issued < blocks)) + { + int bsent = issued * block; + int size1 = MIN (block, (int) size - bsent); + + cli_issue_write (cli, fnum, offset + bsent, write_mode, buf + bsent, size1, issued); + issued++; + } + + if (!cli_receive_smb (cli)) + { + return bwritten; + } + + received++; + + if (CVAL (cli->inbuf, smb_rcls) != 0) + { + break; + } + + bwritten += SVAL (cli->inbuf, smb_vwv2); + } + + while (received < issued && cli_receive_smb (cli)) + { + received++; + } + + return bwritten; +} + +#if 0 +/**************************************************************************** + write to a file using a SMBwrite and not bypassing 0 byte writes +****************************************************************************/ +ssize_t +cli_smbwrite (struct cli_state * cli, int fnum, const char *buf, off_t offset, size_t size) +{ + char *p; + + memset (cli->outbuf, '\0', smb_size); + memset (cli->inbuf, '\0', smb_size); + + set_message (cli->outbuf, 5, 3 + size, True); + + CVAL (cli->outbuf, smb_com) = SMBwrite; + SSVAL (cli->outbuf, smb_tid, cli->cnum); + cli_setup_packet (cli); + + SSVAL (cli->outbuf, smb_vwv0, fnum); + SSVAL (cli->outbuf, smb_vwv1, size); + SIVAL (cli->outbuf, smb_vwv2, offset); + SSVAL (cli->outbuf, smb_vwv4, 0); + + p = smb_buf (cli->outbuf); + *p++ = 1; + SSVAL (p, 0, size); + memcpy (p + 2, buf, size); + + cli_send_smb (cli); + if (!cli_receive_smb (cli)) + { + return False; + } + + if (CVAL (cli->inbuf, smb_rcls) != 0) + { + return -1; + } + + return SVAL (cli->inbuf, smb_vwv0); +} +#endif /*0 */ + +/**************************************************************************** +do a SMBgetattrE call +****************************************************************************/ +BOOL +cli_getattrE (struct cli_state * cli, int fd, + uint16 * attr, size_t * size, time_t * c_time, time_t * a_time, time_t * m_time) +{ + memset (cli->outbuf, '\0', smb_size); + memset (cli->inbuf, '\0', smb_size); + + set_message (cli->outbuf, 2, 0, True); + + CVAL (cli->outbuf, smb_com) = SMBgetattrE; + SSVAL (cli->outbuf, smb_tid, cli->cnum); + cli_setup_packet (cli); + + SSVAL (cli->outbuf, smb_vwv0, fd); + + cli_send_smb (cli); + if (!cli_receive_smb (cli)) + { + return False; + } + + if (CVAL (cli->inbuf, smb_rcls) != 0) + { + return False; + } + + if (size) + { + *size = IVAL (cli->inbuf, smb_vwv6); + } + + if (attr) + { + *attr = SVAL (cli->inbuf, smb_vwv10); + } + + if (c_time) + { + *c_time = make_unix_date3 (cli->inbuf + smb_vwv0); + } + + if (a_time) + { + *a_time = make_unix_date3 (cli->inbuf + smb_vwv2); + } + + if (m_time) + { + *m_time = make_unix_date3 (cli->inbuf + smb_vwv4); + } + + return True; +} + + +/**************************************************************************** +do a SMBgetatr call +****************************************************************************/ +BOOL +cli_getatr (struct cli_state * cli, char *fname, uint16 * attr, size_t * size, time_t * t) +{ + char *p; + + memset (cli->outbuf, '\0', smb_size); + memset (cli->inbuf, '\0', smb_size); + + set_message (cli->outbuf, 0, strlen (fname) + 2, True); + + CVAL (cli->outbuf, smb_com) = SMBgetatr; + SSVAL (cli->outbuf, smb_tid, cli->cnum); + cli_setup_packet (cli); + + p = smb_buf (cli->outbuf); + *p = 4; + pstrcpy (p + 1, fname); + + cli_send_smb (cli); + if (!cli_receive_smb (cli)) + { + return False; + } + + if (CVAL (cli->inbuf, smb_rcls) != 0) + { + return False; + } + + if (size) + { + *size = IVAL (cli->inbuf, smb_vwv3); + } + + if (t) + { + *t = make_unix_date3 (cli->inbuf + smb_vwv1); + } + + if (attr) + { + *attr = SVAL (cli->inbuf, smb_vwv0); + } + + + return True; +} + + +/**************************************************************************** +do a SMBsetatr call +****************************************************************************/ +BOOL +cli_setatr (struct cli_state * cli, char *fname, uint16 attr, time_t t) +{ + char *p; + + memset (cli->outbuf, '\0', smb_size); + memset (cli->inbuf, '\0', smb_size); + + set_message (cli->outbuf, 8, strlen (fname) + 4, True); + + CVAL (cli->outbuf, smb_com) = SMBsetatr; + SSVAL (cli->outbuf, smb_tid, cli->cnum); + cli_setup_packet (cli); + + SSVAL (cli->outbuf, smb_vwv0, attr); + put_dos_date3 (cli->outbuf, smb_vwv1, t); + + p = smb_buf (cli->outbuf); + *p = 4; + pstrcpy (p + 1, fname); + p = skip_string (p, 1); + *p = 4; + + cli_send_smb (cli); + if (!cli_receive_smb (cli)) + { + return False; + } + + if (CVAL (cli->inbuf, smb_rcls) != 0) + { + return False; + } + + return True; +} + +#if 0 +/**************************************************************************** +send a qpathinfo call +****************************************************************************/ +BOOL +cli_qpathinfo (struct cli_state * cli, const char *fname, + time_t * c_time, time_t * a_time, time_t * m_time, size_t * size, uint16 * mode) +{ + int data_len = 0; + int param_len = 0; + uint16 setup = TRANSACT2_QPATHINFO; + pstring param; + char *rparam = NULL, *rdata = NULL; + int count = 8; + BOOL ret; + time_t (*date_fn) (void *); + + param_len = strlen (fname) + 7; + + memset (param, 0, param_len); + SSVAL (param, 0, SMB_INFO_STANDARD); + pstrcpy (¶m[6], fname); + + do + { + ret = (cli_send_trans (cli, SMBtrans2, NULL, 0, /* Name, length */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 10, /* param, length, max */ + NULL, data_len, cli->max_xmit /* data, length, max */ + ) && cli_receive_trans (cli, SMBtrans2, &rparam, ¶m_len, &rdata, &data_len)); + if (!ret) + { + /* we need to work around a Win95 bug - sometimes + it gives ERRSRV/ERRerror temprarily */ + uint8 eclass; + uint32 ecode; + cli_error (cli, &eclass, &ecode, NULL); + if (eclass != ERRSRV || ecode != ERRerror) + break; + msleep (100); + } + } + while (count-- && ret == False); + + if (!ret || !rdata || data_len < 22) + { + return False; + } + + if (cli->win95) + { + date_fn = make_unix_date; + } + else + { + date_fn = make_unix_date2; + } + + if (c_time) + { + *c_time = date_fn (rdata + 0); + } + if (a_time) + { + *a_time = date_fn (rdata + 4); + } + if (m_time) + { + *m_time = date_fn (rdata + 8); + } + if (size) + { + *size = IVAL (rdata, 12); + } + if (mode) + { + *mode = SVAL (rdata, l1_attrFile); + } + + if (rdata) + free (rdata); + if (rparam) + free (rparam); + return True; +} + +/**************************************************************************** +send a qpathinfo call with the SMB_QUERY_FILE_ALL_INFO info level +****************************************************************************/ +BOOL +cli_qpathinfo2 (struct cli_state * cli, const char *fname, + time_t * c_time, time_t * a_time, time_t * m_time, + time_t * w_time, size_t * size, uint16 * mode, SMB_INO_T * ino) +{ + int data_len = 0; + int param_len = 0; + uint16 setup = TRANSACT2_QPATHINFO; + pstring param; + char *rparam = NULL, *rdata = NULL; + + param_len = strlen (fname) + 7; + + memset (param, 0, param_len); + SSVAL (param, 0, SMB_QUERY_FILE_ALL_INFO); + pstrcpy (¶m[6], fname); + + if (!cli_send_trans (cli, SMBtrans2, NULL, 0, /* name, length */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 10, /* param, length, max */ + NULL, data_len, cli->max_xmit /* data, length, max */ + )) + { + return False; + } + + if (!cli_receive_trans (cli, SMBtrans2, &rparam, ¶m_len, &rdata, &data_len)) + { + return False; + } + + if (!rdata || data_len < 22) + { + return False; + } + + if (c_time) + { + *c_time = interpret_long_date (rdata + 0) - cli->serverzone; + } + if (a_time) + { + *a_time = interpret_long_date (rdata + 8) - cli->serverzone; + } + if (m_time) + { + *m_time = interpret_long_date (rdata + 16) - cli->serverzone; + } + if (w_time) + { + *w_time = interpret_long_date (rdata + 24) - cli->serverzone; + } + if (mode) + { + *mode = SVAL (rdata, 32); + } + if (size) + { + *size = IVAL (rdata, 48); + } + if (ino) + { + *ino = IVAL (rdata, 64); + } + + if (rdata) + free (rdata); + if (rparam) + free (rparam); + return True; +} +#endif /* 0 */ + +/**************************************************************************** +send a qfileinfo call +****************************************************************************/ +BOOL +cli_qfileinfo (struct cli_state * cli, int fnum, + uint16 * mode, size_t * size, + time_t * c_time, time_t * a_time, time_t * m_time, time_t * w_time, SMB_INO_T * ino) +{ + int data_len = 0; + int param_len = 0; + uint16 setup = TRANSACT2_QFILEINFO; + pstring param; + char *rparam = NULL, *rdata = NULL; + + /* if its a win95 server then fail this - win95 totally screws it + up */ + if (cli->win95) + return False; + + param_len = 4; + + memset (param, 0, param_len); + SSVAL (param, 0, fnum); + SSVAL (param, 2, SMB_QUERY_FILE_ALL_INFO); + + if (!cli_send_trans (cli, SMBtrans2, NULL, 0, /* name, length */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 2, /* param, length, max */ + NULL, data_len, cli->max_xmit /* data, length, max */ + )) + { + return False; + } + + if (!cli_receive_trans (cli, SMBtrans2, &rparam, ¶m_len, &rdata, &data_len)) + { + return False; + } + + if (!rdata || data_len < 68) + { + return False; + } + + if (c_time) + { + *c_time = interpret_long_date (rdata + 0) - cli->serverzone; + } + if (a_time) + { + *a_time = interpret_long_date (rdata + 8) - cli->serverzone; + } + if (m_time) + { + *m_time = interpret_long_date (rdata + 16) - cli->serverzone; + } + if (w_time) + { + *w_time = interpret_long_date (rdata + 24) - cli->serverzone; + } + if (mode) + { + *mode = SVAL (rdata, 32); + } + if (size) + { + *size = IVAL (rdata, 48); + } + if (ino) + { + *ino = IVAL (rdata, 64); + } + + if (rdata) + free (rdata); + if (rparam) + free (rparam); + return True; +} + + +/**************************************************************************** +interpret a long filename structure - this is mostly guesses at the moment +The length of the structure is returned +The structure of a long filename depends on the info level. 260 is used +by NT and 2 is used by OS/2 +****************************************************************************/ +static int +interpret_long_filename (int level, char *p, file_info * finfo) +{ + extern file_info const def_finfo; + + if (finfo) + memcpy (finfo, &def_finfo, sizeof (*finfo)); + + switch (level) + { + case 1: /* OS/2 understands this */ + if (finfo) + { + /* these dates are converted to GMT by make_unix_date */ + finfo->ctime = make_unix_date2 (p + 4); + finfo->atime = make_unix_date2 (p + 8); + finfo->mtime = make_unix_date2 (p + 12); + finfo->size = IVAL (p, 16); + finfo->mode = CVAL (p, 24); + pstrcpy (finfo->name, p + 27); + } + return (28 + CVAL (p, 26)); + + case 2: /* this is what OS/2 uses mostly */ + if (finfo) + { + /* these dates are converted to GMT by make_unix_date */ + finfo->ctime = make_unix_date2 (p + 4); + finfo->atime = make_unix_date2 (p + 8); + finfo->mtime = make_unix_date2 (p + 12); + finfo->size = IVAL (p, 16); + finfo->mode = CVAL (p, 24); + pstrcpy (finfo->name, p + 31); + } + return (32 + CVAL (p, 30)); + + /* levels 3 and 4 are untested */ + case 3: + if (finfo) + { + /* these dates are probably like the other ones */ + finfo->ctime = make_unix_date2 (p + 8); + finfo->atime = make_unix_date2 (p + 12); + finfo->mtime = make_unix_date2 (p + 16); + finfo->size = IVAL (p, 20); + finfo->mode = CVAL (p, 28); + pstrcpy (finfo->name, p + 33); + } + return (SVAL (p, 4) + 4); + + case 4: + if (finfo) + { + /* these dates are probably like the other ones */ + finfo->ctime = make_unix_date2 (p + 8); + finfo->atime = make_unix_date2 (p + 12); + finfo->mtime = make_unix_date2 (p + 16); + finfo->size = IVAL (p, 20); + finfo->mode = CVAL (p, 28); + pstrcpy (finfo->name, p + 37); + } + return (SVAL (p, 4) + 4); + + case 260: /* NT uses this, but also accepts 2 */ + if (finfo) + { + int ret = SVAL (p, 0); + int namelen; + p += 4; /* next entry offset */ + p += 4; /* fileindex */ + + /* these dates appear to arrive in a + weird way. It seems to be localtime + plus the serverzone given in the + initial connect. This is GMT when + DST is not in effect and one hour + from GMT otherwise. Can this really + be right?? + + I suppose this could be called + kludge-GMT. Is is the GMT you get + by using the current DST setting on + a different localtime. It will be + cheap to calculate, I suppose, as + no DST tables will be needed */ + + finfo->ctime = interpret_long_date (p); + p += 8; + finfo->atime = interpret_long_date (p); + p += 8; + finfo->mtime = interpret_long_date (p); + p += 8; + p += 8; + finfo->size = IVAL (p, 0); + p += 8; + p += 8; /* alloc size */ + finfo->mode = CVAL (p, 0); + p += 4; + namelen = IVAL (p, 0); + p += 4; + p += 4; /* EA size */ + p += 2; /* short name len? */ + p += 24; /* short name? */ + StrnCpy (finfo->name, p, namelen); + return (ret); + } + return (SVAL (p, 0)); + } + + DEBUG (1, ("Unknown long filename format %d\n", level)); + return (SVAL (p, 0)); +} + + +/**************************************************************************** + do a directory listing, calling fn on each file found + ****************************************************************************/ +int +cli_list (struct cli_state *cli, const char *Mask, uint16 attribute, + void (*fn) (file_info *, const char *, void *), void *state) +{ + int max_matches = 512; + /* NT uses 260, OS/2 uses 2. Both accept 1. */ + int info_level = cli->protocol < PROTOCOL_NT1 ? 1 : 260; + char *p, *p2; + pstring mask; + file_info finfo; + int i; + char *dirlist = NULL; + int dirlist_len = 0; + int total_received = -1; + BOOL First = True; + int ff_resume_key = 0; + int ff_searchcount = 0; + int ff_eos = 0; + int ff_lastname = 0; + int ff_dir_handle = 0; + int loop_count = 0; + char *rparam = NULL, *rdata = NULL; + int param_len, data_len; + + uint16 setup; + pstring param; + + pstrcpy (mask, Mask); + + while (ff_eos == 0) + { + loop_count++; + if (loop_count > 200) + { + DEBUG (0, ("Error: Looping in FIND_NEXT??\n")); + break; + } + + param_len = 12 + strlen (mask) + 1; + + if (First) + { + setup = TRANSACT2_FINDFIRST; + SSVAL (param, 0, attribute); /* attribute */ + SSVAL (param, 2, max_matches); /* max count */ + SSVAL (param, 4, 8 + 4 + 2); /* resume required + close on end + continue */ + SSVAL (param, 6, info_level); + SIVAL (param, 8, 0); + pstrcpy (param + 12, mask); + } + else + { + setup = TRANSACT2_FINDNEXT; + SSVAL (param, 0, ff_dir_handle); + SSVAL (param, 2, max_matches); /* max count */ + SSVAL (param, 4, info_level); + SIVAL (param, 6, ff_resume_key); /* ff_resume_key */ + SSVAL (param, 10, 8 + 4 + 2); /* resume required + close on end + continue */ + pstrcpy (param + 12, mask); + + DEBUG (5, ("hand=0x%X resume=%d ff_lastname=%d mask=%s\n", + ff_dir_handle, ff_resume_key, ff_lastname, mask)); + } + + if (!cli_send_trans (cli, SMBtrans2, NULL, 0, /* Name, length */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 10, /* param, length, max */ + NULL, 0, cli->max_xmit /* data, length, max */ + )) + { + break; + } + + if (!cli_receive_trans (cli, SMBtrans2, &rparam, ¶m_len, &rdata, &data_len)) + { + /* we need to work around a Win95 bug - sometimes + it gives ERRSRV/ERRerror temprarily */ + uint8 eclass; + uint32 ecode; + cli_error (cli, &eclass, &ecode, NULL); + if (eclass != ERRSRV || ecode != ERRerror) + break; + msleep (100); + continue; + } + + if (total_received == -1) + total_received = 0; + + /* parse out some important return info */ + p = rparam; + if (First) + { + ff_dir_handle = SVAL (p, 0); + ff_searchcount = SVAL (p, 2); + ff_eos = SVAL (p, 4); + ff_lastname = SVAL (p, 8); + } + else + { + ff_searchcount = SVAL (p, 0); + ff_eos = SVAL (p, 2); + ff_lastname = SVAL (p, 6); + } + + if (ff_searchcount == 0) + break; + + /* point to the data bytes */ + p = rdata; + + /* we might need the lastname for continuations */ + if (ff_lastname > 0) + { + switch (info_level) + { + case 260: + ff_resume_key = 0; + StrnCpy (mask, p + ff_lastname, data_len - ff_lastname); + break; + case 1: + pstrcpy (mask, p + ff_lastname + 1); + ff_resume_key = 0; + break; + } + } + else + { + pstrcpy (mask, ""); + } + + /* and add them to the dirlist pool */ + dirlist = Realloc (dirlist, dirlist_len + data_len); + + if (!dirlist) + { + DEBUG (0, ("Failed to expand dirlist\n")); + break; + } + + /* put in a length for the last entry, to ensure we can chain entries + into the next packet */ + for (p2 = p, i = 0; i < (ff_searchcount - 1); i++) + p2 += interpret_long_filename (info_level, p2, NULL); + SSVAL (p2, 0, data_len - PTR_DIFF (p2, p)); + + /* grab the data for later use */ + memcpy (dirlist + dirlist_len, p, data_len); + dirlist_len += data_len; + + total_received += ff_searchcount; + + if (rdata) + free (rdata); + rdata = NULL; + if (rparam) + free (rparam); + rparam = NULL; + + DEBUG (3, ("received %d entries (eos=%d resume=%d)\n", + ff_searchcount, ff_eos, ff_resume_key)); + + First = False; + } + + for (p = dirlist, i = 0; i < total_received; i++) + { + p += interpret_long_filename (info_level, p, &finfo); + fn (&finfo, Mask, state); + } + + /* free up the dirlist buffer */ + if (dirlist) + free (dirlist); + return (total_received); +} + + +/**************************************************************************** +send a negprot command +****************************************************************************/ +BOOL +cli_negprot (struct cli_state * cli) +{ + char *p; + int numprots; + int plength; + + memset (cli->outbuf, '\0', smb_size); + + /* setup the protocol strings */ + for (plength = 0, numprots = 0; + prots[numprots].name && prots[numprots].prot <= cli->protocol; numprots++) + plength += strlen (prots[numprots].name) + 2; + + set_message (cli->outbuf, 0, plength, True); + + p = smb_buf (cli->outbuf); + for (numprots = 0; prots[numprots].name && prots[numprots].prot <= cli->protocol; numprots++) + { + *p++ = 2; + pstrcpy (p, prots[numprots].name); + p += strlen (p) + 1; + } + + CVAL (cli->outbuf, smb_com) = SMBnegprot; + cli_setup_packet (cli); + + CVAL (smb_buf (cli->outbuf), 0) = 2; + + cli_send_smb (cli); + if (!cli_receive_smb (cli)) + return False; + + show_msg (cli->inbuf); + + if (CVAL (cli->inbuf, smb_rcls) != 0 || ((int) SVAL (cli->inbuf, smb_vwv0) >= numprots)) + { + return (False); + } + + cli->protocol = prots[SVAL (cli->inbuf, smb_vwv0)].prot; + + + if (cli->protocol >= PROTOCOL_NT1) + { + /* NT protocol */ + cli->sec_mode = CVAL (cli->inbuf, smb_vwv1); + cli->max_mux = SVAL (cli->inbuf, smb_vwv1 + 1); + cli->max_xmit = IVAL (cli->inbuf, smb_vwv3 + 1); + cli->sesskey = IVAL (cli->inbuf, smb_vwv7 + 1); + cli->serverzone = SVALS (cli->inbuf, smb_vwv15 + 1) * 60; + /* this time arrives in real GMT */ + cli->servertime = interpret_long_date (cli->inbuf + smb_vwv11 + 1); + memcpy (cli->cryptkey, smb_buf (cli->inbuf), 8); + cli->capabilities = IVAL (cli->inbuf, smb_vwv9 + 1); + if (cli->capabilities & 1) + { + cli->readbraw_supported = True; + cli->writebraw_supported = True; + } + } + else if (cli->protocol >= PROTOCOL_LANMAN1) + { + cli->sec_mode = SVAL (cli->inbuf, smb_vwv1); + cli->max_xmit = SVAL (cli->inbuf, smb_vwv2); + cli->sesskey = IVAL (cli->inbuf, smb_vwv6); + cli->serverzone = SVALS (cli->inbuf, smb_vwv10) * 60; + /* this time is converted to GMT by make_unix_date */ + cli->servertime = make_unix_date (cli->inbuf + smb_vwv8); + cli->readbraw_supported = ((SVAL (cli->inbuf, smb_vwv5) & 0x1) != 0); + cli->writebraw_supported = ((SVAL (cli->inbuf, smb_vwv5) & 0x2) != 0); + memcpy (cli->cryptkey, smb_buf (cli->inbuf), 8); + } + else + { + /* the old core protocol */ + cli->sec_mode = 0; + cli->serverzone = TimeDiff (time (NULL)); + } + + cli->max_xmit = MIN (cli->max_xmit, CLI_BUFFER_SIZE); + + return True; +} + + +/**************************************************************************** + send a session request. see rfc1002.txt 4.3 and 4.3.2 +****************************************************************************/ +BOOL +cli_session_request (struct cli_state * cli, struct nmb_name * calling, struct nmb_name * called) +{ + char *p; + int len = 4; + /* send a session request (RFC 1002) */ + + memcpy (&(cli->calling), calling, sizeof (*calling)); + memcpy (&(cli->called), called, sizeof (*called)); + + /* put in the destination name */ + p = cli->outbuf + len; + name_mangle (cli->called.name, p, cli->called.name_type); + len += name_len (p); + + /* and my name */ + p = cli->outbuf + len; + name_mangle (cli->calling.name, p, cli->calling.name_type); + len += name_len (p); + + /* setup the packet length */ + _smb_setlen (cli->outbuf, len); + CVAL (cli->outbuf, 0) = 0x81; + +#ifdef WITH_SSL + retry: +#endif /* WITH_SSL */ + + cli_send_smb (cli); + DEBUG (5, ("Sent session request\n")); + + if (!cli_receive_smb (cli)) + return False; + + if (CVAL (cli->inbuf, 0) == 0x84) + { + /* C. Hoch 9/14/95 Start */ + /* For information, here is the response structure. + * We do the byte-twiddling to for portability. + struct RetargetResponse{ + unsigned char type; + unsigned char flags; + int16 length; + int32 ip_addr; + int16 port; + }; + */ + int port = (CVAL (cli->inbuf, 8) << 8) + CVAL (cli->inbuf, 9); + /* SESSION RETARGET */ + putip ((char *) &cli->dest_ip, cli->inbuf + 4); + + close_sockets (); + cli->fd = open_socket_out (SOCK_STREAM, &cli->dest_ip, port, LONG_CONNECT_TIMEOUT); + if (cli->fd == -1) + return False; + + DEBUG (3, ("Retargeted\n")); + + set_socket_options (cli->fd, user_socket_options); + + /* Try again */ + return cli_session_request (cli, calling, called); + } /* C. Hoch 9/14/95 End */ + +#ifdef WITH_SSL + if (CVAL (cli->inbuf, 0) == 0x83 && CVAL (cli->inbuf, 4) == 0x8e) + { /* use ssl */ + if (!sslutil_fd_is_ssl (cli->fd)) + { + if (sslutil_connect (cli->fd) == 0) + goto retry; + } + } +#endif /* WITH_SSL */ + + if (CVAL (cli->inbuf, 0) != 0x82) + { + /* This is the wrong place to put the error... JRA. */ + cli->rap_error = CVAL (cli->inbuf, 0); + return False; + } + return (True); +} + + +/**************************************************************************** +open the client sockets +****************************************************************************/ +BOOL +cli_connect (struct cli_state * cli, const char *host, struct in_addr * ip) +{ + extern struct in_addr ipzero; + + fstrcpy (cli->desthost, host); + + if (!ip || ip_equal (*ip, ipzero)) + { + if (!resolve_name (cli->desthost, &cli->dest_ip, 0x20)) + { + return False; + } + if (ip) + *ip = cli->dest_ip; + } + else + { + cli->dest_ip = *ip; + } + + if (cli->port == 0) + cli->port = 139; /* Set to default */ + + cli->fd = open_socket_out (SOCK_STREAM, &cli->dest_ip, cli->port, cli->timeout); + if (cli->fd == -1) + return False; + + return True; +} + + +/**************************************************************************** +initialise a client structure +****************************************************************************/ +struct cli_state * +cli_initialise (struct cli_state *cli) +{ + if (!cli) + { + cli = (struct cli_state *) malloc (sizeof (*cli)); + if (!cli) + return NULL; + ZERO_STRUCTP (cli); + } + + if (cli->initialised) + { + cli_shutdown (cli); + } + + ZERO_STRUCTP (cli); + + cli->port = 0; + cli->fd = -1; + cli->cnum = -1; + cli->pid = (uint16) getpid (); + cli->mid = 1; + cli->vuid = UID_FIELD_INVALID; + cli->protocol = PROTOCOL_NT1; + cli->timeout = 20000; /* Timeout is in milliseconds. */ + cli->bufsize = CLI_BUFFER_SIZE + 4; + cli->max_xmit = cli->bufsize; + cli->outbuf = (char *) malloc (cli->bufsize); + cli->inbuf = (char *) malloc (cli->bufsize); + if (!cli->outbuf || !cli->inbuf) + { + return False; + } + + cli->initialised = 1; + + return cli; +} + +/**************************************************************************** +shutdown a client structure +****************************************************************************/ +void +cli_shutdown (struct cli_state *cli) +{ + if (cli->outbuf) + { + free (cli->outbuf); + } + if (cli->inbuf) + { + free (cli->inbuf); + } +#ifdef WITH_SSL + if (cli->fd != -1) + sslutil_disconnect (cli->fd); +#endif /* WITH_SSL */ + if (cli->fd != -1) + close (cli->fd); + memset (cli, 0, sizeof (*cli)); +} + + +/**************************************************************************** + return error codes for the last packet + returns 0 if there was no error and the best approx of a unix errno + otherwise + + for 32 bit "warnings", a return code of 0 is expected. + +****************************************************************************/ +int +cli_error (struct cli_state *cli, uint8 * eclass, uint32 * num, uint32 * nt_rpc_error) +{ + int flgs2 = SVAL (cli->inbuf, smb_flg2); + char rcls; + int code; + + if (eclass) + *eclass = 0; + if (num) + *num = 0; + if (nt_rpc_error) + *nt_rpc_error = cli->nt_error; + + if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) + { + /* 32 bit error codes detected */ + uint32 nt_err = IVAL (cli->inbuf, smb_rcls); + if (num) + *num = nt_err; + DEBUG (10, ("cli_error: 32 bit codes: code=%08x\n", nt_err)); + if (!IS_BITS_SET_ALL (nt_err, 0xc0000000)) + return 0; + + switch (nt_err & 0xFFFFFF) + { + case NT_STATUS_ACCESS_VIOLATION: + return EACCES; + case NT_STATUS_NO_SUCH_FILE: + return ENOENT; + case NT_STATUS_NO_SUCH_DEVICE: + return ENODEV; + case NT_STATUS_INVALID_HANDLE: + return EBADF; + case NT_STATUS_NO_MEMORY: + return ENOMEM; + case NT_STATUS_ACCESS_DENIED: + return EACCES; + case NT_STATUS_OBJECT_NAME_NOT_FOUND: + return ENOENT; + case NT_STATUS_SHARING_VIOLATION: + return EBUSY; + case NT_STATUS_OBJECT_PATH_INVALID: + return ENOTDIR; + case NT_STATUS_OBJECT_NAME_COLLISION: + return EEXIST; + } + + /* for all other cases - a default code */ + return EINVAL; + } + + rcls = CVAL (cli->inbuf, smb_rcls); + code = SVAL (cli->inbuf, smb_err); + if (rcls == 0) + return 0; + + if (eclass) + *eclass = rcls; + if (num) + *num = code; + + if (rcls == ERRDOS) + { + switch (code) + { + case ERRbadfile: + return ENOENT; + case ERRbadpath: + return ENOTDIR; + case ERRnoaccess: + return EACCES; + case ERRfilexists: + return EEXIST; + case ERRrename: + return EEXIST; + case ERRbadshare: + return EBUSY; + case ERRlock: + return EBUSY; + } + } + if (rcls == ERRSRV) + { + switch (code) + { + case ERRbadpw: + return EPERM; + case ERRaccess: + return EACCES; + case ERRnoresource: + return ENOMEM; + case ERRinvdevice: + return ENODEV; + case ERRinvnetname: + return ENODEV; + } + } + /* for other cases */ + return EINVAL; +} + +/**************************************************************************** +set socket options on a open connection +****************************************************************************/ +void +cli_sockopt (struct cli_state *cli, char *options) +{ + set_socket_options (cli->fd, options); +} + +/**************************************************************************** +set the PID to use for smb messages. Return the old pid. +****************************************************************************/ +uint16 +cli_setpid (struct cli_state *cli, uint16 pid) +{ + uint16 ret = cli->pid; + cli->pid = pid; + return ret; +} + +/**************************************************************************** +re-establishes a connection +****************************************************************************/ +BOOL +cli_reestablish_connection (struct cli_state * cli) +{ + struct nmb_name calling; + struct nmb_name called; + fstring dest_host; + fstring share; + fstring dev; + BOOL do_tcon = False; + int oldfd = cli->fd; + + if (!cli->initialised || cli->fd == -1) + { + DEBUG (3, ("cli_reestablish_connection: not connected\n")); + return False; + } + + /* copy the parameters necessary to re-establish the connection */ + + if (cli->cnum != 0) + { + fstrcpy (share, cli->share); + fstrcpy (dev, cli->dev); + do_tcon = True; + } + + memcpy (&called, &(cli->called), sizeof (called)); + memcpy (&calling, &(cli->calling), sizeof (calling)); + fstrcpy (dest_host, cli->full_dest_host_name); + + DEBUG (5, ("cli_reestablish_connection: %s connecting to %s (ip %s) - %s [%s]\n", + nmb_namestr (&calling), nmb_namestr (&called), + inet_ntoa (cli->dest_ip), cli->user_name, cli->domain)); + + cli->fd = -1; + + if (cli_establish_connection (cli, + dest_host, &cli->dest_ip, + &calling, &called, share, dev, False, do_tcon)) + { + if (cli->fd != oldfd) + { + if (dup2 (cli->fd, oldfd) == oldfd) + { + close (cli->fd); + } + } + return True; + } + return False; +} + +/**************************************************************************** +establishes a connection right up to doing tconX, reading in a password. +****************************************************************************/ +BOOL +cli_establish_connection (struct cli_state * cli, + char *dest_host, struct in_addr * dest_ip, + struct nmb_name * calling, struct nmb_name * called, + char *service, char *service_type, BOOL do_shutdown, BOOL do_tcon) +{ + DEBUG (5, ("cli_establish_connection: %s connecting to %s (%s) - %s [%s]\n", + nmb_namestr (calling), nmb_namestr (called), inet_ntoa (*dest_ip), + cli->user_name, cli->domain)); + + /* establish connection */ + + if ((!cli->initialised)) + { + return False; + } + + if (cli->fd == -1) + { + if (!cli_connect (cli, dest_host, dest_ip)) + { + DEBUG (1, ("cli_establish_connection: failed to connect to %s (%s)\n", + nmb_namestr (calling), inet_ntoa (*dest_ip))); + return False; + } + } + + if (!cli_session_request (cli, calling, called)) + { + DEBUG (1, ("failed session request\n")); + if (do_shutdown) + cli_shutdown (cli); + return False; + } + + if (!cli_negprot (cli)) + { + DEBUG (1, ("failed negprot\n")); + if (do_shutdown) + cli_shutdown (cli); + return False; + } + + if (cli->pwd.cleartext || cli->pwd.null_pwd) + { + fstring passwd; + int pass_len; + + if (cli->pwd.null_pwd) + { + /* attempt null session */ + passwd[0] = 0; + pass_len = 1; + } + else + { + /* attempt clear-text session */ + pwd_get_cleartext (&(cli->pwd), passwd); + pass_len = strlen (passwd); + } + + /* attempt clear-text session */ + if (!cli_session_setup (cli, cli->user_name, passwd, pass_len, NULL, 0, cli->domain)) + { + DEBUG (1, ("failed session setup\n")); + if (do_shutdown) + { + cli_shutdown (cli); + } + return False; + } + if (do_tcon) + { + if (!cli_send_tconX (cli, service, service_type, (char *) passwd, strlen (passwd))) + { + DEBUG (1, ("failed tcon_X\n")); + if (do_shutdown) + { + cli_shutdown (cli); + } + return False; + } + } + } + else + { + /* attempt encrypted session */ + unsigned char nt_sess_pwd[24]; + unsigned char lm_sess_pwd[24]; + + /* creates (storing a copy of) and then obtains a 24 byte password OWF */ + pwd_make_lm_nt_owf (&(cli->pwd), cli->cryptkey); + pwd_get_lm_nt_owf (&(cli->pwd), lm_sess_pwd, nt_sess_pwd); + + /* attempt encrypted session */ + if (!cli_session_setup (cli, cli->user_name, + (char *) lm_sess_pwd, sizeof (lm_sess_pwd), + (char *) nt_sess_pwd, sizeof (nt_sess_pwd), cli->domain)) + { + DEBUG (1, ("failed session setup\n")); + if (do_shutdown) + cli_shutdown (cli); + return False; + } + + if (do_tcon) + { + if (!cli_send_tconX (cli, service, service_type, + (char *) nt_sess_pwd, sizeof (nt_sess_pwd))) + { + DEBUG (1, ("failed tcon_X\n")); + if (do_shutdown) + cli_shutdown (cli); + return False; + } + } + } + + if (do_shutdown) + cli_shutdown (cli); + + return True; +} + + +/**************************************************************************** +check for existance of a dir +****************************************************************************/ +BOOL +cli_chkpath (struct cli_state * cli, char *path) +{ + pstring path2; + char *p; + + safe_strcpy (path2, path, sizeof (pstring) - 1); + trim_string (path2, NULL, "\\"); + if (!*path2) + *path2 = '\\'; + + memset (cli->outbuf, '\0', smb_size); + set_message (cli->outbuf, 0, 4 + strlen (path2), True); + SCVAL (cli->outbuf, smb_com, SMBchkpth); + SSVAL (cli->outbuf, smb_tid, cli->cnum); + cli_setup_packet (cli); + p = smb_buf (cli->outbuf); + *p++ = 4; + safe_strcpy (p, path2, strlen (path2)); + + cli_send_smb (cli); + if (!cli_receive_smb (cli)) + { + return False; + } + + if (cli_error (cli, NULL, NULL, NULL)) + return False; + + return True; +} + +#if 0 +/**************************************************************************** +start a message sequence +****************************************************************************/ +BOOL +cli_message_start (struct cli_state * cli, char *host, char *username, int *grp) +{ + char *p; + + /* send a SMBsendstrt command */ + memset (cli->outbuf, '\0', smb_size); + set_message (cli->outbuf, 0, 0, True); + CVAL (cli->outbuf, smb_com) = SMBsendstrt; + SSVAL (cli->outbuf, smb_tid, cli->cnum); + cli_setup_packet (cli); + + p = smb_buf (cli->outbuf); + *p++ = 4; + pstrcpy (p, username); + p = skip_string (p, 1); + *p++ = 4; + pstrcpy (p, host); + p = skip_string (p, 1); + + set_message (cli->outbuf, 0, PTR_DIFF (p, smb_buf (cli->outbuf)), False); + + cli_send_smb (cli); + + if (!cli_receive_smb (cli)) + { + return False; + } + + if (cli_error (cli, NULL, NULL, NULL)) + return False; + + *grp = SVAL (cli->inbuf, smb_vwv0); + + return True; +} + + +/**************************************************************************** +send a message +****************************************************************************/ +BOOL +cli_message_text (struct cli_state * cli, char *msg, int len, int grp) +{ + char *p; + + memset (cli->outbuf, '\0', smb_size); + set_message (cli->outbuf, 1, len + 3, True); + CVAL (cli->outbuf, smb_com) = SMBsendtxt; + SSVAL (cli->outbuf, smb_tid, cli->cnum); + cli_setup_packet (cli); + + SSVAL (cli->outbuf, smb_vwv0, grp); + + p = smb_buf (cli->outbuf); + *p = 1; + SSVAL (p, 1, len); + memcpy (p + 3, msg, len); + cli_send_smb (cli); + + if (!cli_receive_smb (cli)) + { + return False; + } + + if (cli_error (cli, NULL, NULL, NULL)) + return False; + + return True; +} + +/**************************************************************************** +end a message +****************************************************************************/ +BOOL +cli_message_end (struct cli_state * cli, int grp) +{ + memset (cli->outbuf, '\0', smb_size); + set_message (cli->outbuf, 1, 0, True); + CVAL (cli->outbuf, smb_com) = SMBsendend; + SSVAL (cli->outbuf, smb_tid, cli->cnum); + + SSVAL (cli->outbuf, smb_vwv0, grp); + + cli_setup_packet (cli); + + cli_send_smb (cli); + + if (!cli_receive_smb (cli)) + { + return False; + } + + if (cli_error (cli, NULL, NULL, NULL)) + return False; + + return True; +} +#endif /*0 */ + +#if 0 /* May be useful one day */ +/**************************************************************************** +query disk space +****************************************************************************/ +BOOL +cli_dskattr (struct cli_state * cli, int *bsize, int *total, int *avail) +{ + memset (cli->outbuf, '\0', smb_size); + set_message (cli->outbuf, 0, 0, True); + CVAL (cli->outbuf, smb_com) = SMBdskattr; + SSVAL (cli->outbuf, smb_tid, cli->cnum); + cli_setup_packet (cli); + + cli_send_smb (cli); + if (!cli_receive_smb (cli)) + { + return False; + } + + *bsize = SVAL (cli->inbuf, smb_vwv1) * SVAL (cli->inbuf, smb_vwv2); + *total = SVAL (cli->inbuf, smb_vwv0); + *avail = SVAL (cli->inbuf, smb_vwv3); + + return True; +} +#endif /* 0 */ diff --git a/src/vfs/smbfs/helpers/libsmb/namequery.c b/src/vfs/smbfs/helpers/libsmb/namequery.c dissimilarity index 76% index 11d228327..79bcbccb9 100644 --- a/src/vfs/smbfs/helpers/libsmb/namequery.c +++ b/src/vfs/smbfs/helpers/libsmb/namequery.c @@ -1,559 +1,605 @@ -/* - Unix SMB/Netbios implementation. - Version 1.9. - name query routines - - Copyright (C) Andrew Tridgell 1994-1998 - - Copyright (C) 2011 - The Free Software Foundation, Inc. - - This file is part of the Midnight Commander. - - The Midnight Commander is free software: you can redistribute it - and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of the License, - or (at your option) any later version. - - The Midnight Commander is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "includes.h" - -const char *unix_error_string (int error_num); -extern pstring scope; -extern int DEBUGLEVEL; - -/* nmbd.c sets this to True. */ -const BOOL global_in_nmbd = False; -#if 0 -/**************************************************************************** -interpret a node status response -****************************************************************************/ -static void _interpret_node_status(char *p, char *master,char *rname) -{ - int numnames = CVAL(p,0); - DEBUG(1,("received %d names\n",numnames)); - - if (rname) *rname = 0; - if (master) *master = 0; - - p += 1; - while (numnames--) - { - char qname[17]; - int type; - fstring flags; - int i; - *flags = 0; - StrnCpy(qname,p,15); - type = CVAL(p,15); - p += 16; - - fstrcat(flags, (p[0] & 0x80) ? " " : " "); - if ((p[0] & 0x60) == 0x00) fstrcat(flags,"B "); - if ((p[0] & 0x60) == 0x20) fstrcat(flags,"P "); - if ((p[0] & 0x60) == 0x40) fstrcat(flags,"M "); - if ((p[0] & 0x60) == 0x60) fstrcat(flags,"H "); - if (p[0] & 0x10) fstrcat(flags," "); - if (p[0] & 0x08) fstrcat(flags," "); - if (p[0] & 0x04) fstrcat(flags," "); - if (p[0] & 0x02) fstrcat(flags," "); - - if (master && !*master && type == 0x1d) { - StrnCpy(master,qname,15); - trim_string(master,NULL," "); - } - - if (rname && !*rname && type == 0x20 && !(p[0]&0x80)) { - StrnCpy(rname,qname,15); - trim_string(rname,NULL," "); - } - - for (i = strlen( qname) ; --i >= 0 ; ) { - if (!isprint((int)qname[i])) qname[i] = '.'; - } - DEBUG(1,("\t%-15s <%02x> - %s\n",qname,type,flags)); - p+=2; - } - DEBUG(1,("num_good_sends=%d num_good_receives=%d\n", - IVAL(p,20),IVAL(p,24))); -} -#endif /* 0 */ - -/**************************************************************************** - do a netbios name query to find someones IP - returns an array of IP addresses or NULL if none - *count will be set to the number of addresses returned - ****************************************************************************/ -struct in_addr *name_query(int fd,const char *name,int name_type, BOOL bcast,BOOL recurse, - struct in_addr to_ip, int *count, void (*fn)(struct packet_struct *)) -{ - BOOL found=False; - int i, retries = 3; - int retry_time = bcast?250:2000; - struct timeval tval; - struct packet_struct p; - struct packet_struct *p2; - struct nmb_packet *nmb = &p.packet.nmb; - static int name_trn_id = 0; - struct in_addr *ip_list = NULL; - - memset((char *)&p,'\0',sizeof(p)); - (*count) = 0; - - if (!name_trn_id) name_trn_id = ((unsigned)time(NULL)%(unsigned)0x7FFF) + - ((unsigned)getpid()%(unsigned)100); - name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF; - - nmb->header.name_trn_id = name_trn_id; - nmb->header.opcode = 0; - nmb->header.response = False; - nmb->header.nm_flags.bcast = bcast; - nmb->header.nm_flags.recursion_available = False; - nmb->header.nm_flags.recursion_desired = recurse; - nmb->header.nm_flags.trunc = False; - nmb->header.nm_flags.authoritative = False; - nmb->header.rcode = 0; - nmb->header.qdcount = 1; - nmb->header.ancount = 0; - nmb->header.nscount = 0; - nmb->header.arcount = 0; - - make_nmb_name(&nmb->question.question_name,name,name_type); - - nmb->question.question_type = 0x20; - nmb->question.question_class = 0x1; - - p.ip = to_ip; - p.port = NMB_PORT; - p.fd = fd; - p.timestamp = time(NULL); - p.packet_type = NMB_PACKET; - - GetTimeOfDay(&tval); - - if (!send_packet(&p)) - return NULL; - - retries--; - - while (1) - { - struct timeval tval2; - GetTimeOfDay(&tval2); - if (TvalDiff(&tval,&tval2) > retry_time) - { - if (!retries) - break; - if (!found && !send_packet(&p)) - return NULL; - GetTimeOfDay(&tval); - retries--; - } - - if ((p2=receive_packet(fd,NMB_PACKET,90))) - { - struct nmb_packet *nmb2 = &p2->packet.nmb; - debug_nmb_packet(p2); - - if (nmb->header.name_trn_id != nmb2->header.name_trn_id || - !nmb2->header.response) - { - /* - * Its not for us - maybe deal with it later - * (put it on the queue?). - */ - if (fn) - fn(p2); - else - free_packet(p2); - continue; - } - - if (nmb2->header.opcode != 0 || - nmb2->header.nm_flags.bcast || - nmb2->header.rcode || - !nmb2->header.ancount) - { - /* - * XXXX what do we do with this? Could be a redirect, but - * we'll discard it for the moment. - */ - free_packet(p2); - continue; - } - - ip_list = (struct in_addr *)Realloc(ip_list, sizeof(ip_list[0]) * - ((*count)+nmb2->answers->rdlength/6)); - if (ip_list) - { - DEBUG(fn?3:2,("Got a positive name query response from %s ( ", - inet_ntoa(p2->ip))); - for (i=0;ianswers->rdlength/6;i++) - { - putip((char *)&ip_list[(*count)],&nmb2->answers->rdata[2+i*6]); - DEBUG(fn?3:2,("%s ",inet_ntoa(ip_list[(*count)]))); - (*count)++; - } - DEBUG(fn?3:2,(")\n")); - } - - found=True; - retries=0; - free_packet(p2); - if (fn) - break; - - /* - * If we're doing a unicast lookup we only - * expect one reply. Don't wait the full 2 - * seconds if we got one. JRA. - */ - if(!bcast && found) - break; - } - } - - return ip_list; -} - -/******************************************************** - Start parsing the lmhosts file. -*********************************************************/ - -FILE *startlmhosts(const char *fname) -{ - FILE *fp = sys_fopen(fname,"r"); - if (!fp) { - DEBUG(4,("startlmhosts: Cannot open lmhosts file %s. Error was %s\n", - fname, unix_error_string (errno))); - return NULL; - } - return fp; -} - -/******************************************************** - Parse the next line in the lmhosts file. -*********************************************************/ -BOOL getlmhostsent( FILE *fp, pstring name, int *name_type, struct in_addr *ipaddr) -{ - pstring line; - - while(!feof(fp) && !ferror(fp)) { - pstring ip,flags,extra; - char *ptr; - int count = 0; - - *name_type = -1; - - if (!fgets_slash(line,sizeof(pstring),fp)) - continue; - - if (*line == '#') - continue; - - pstrcpy(ip,""); - pstrcpy(name,""); - pstrcpy(flags,""); - - ptr = line; - - if (next_token(&ptr,ip ,NULL,sizeof(ip))) - ++count; - if (next_token(&ptr,name ,NULL, sizeof(pstring))) - ++count; - if (next_token(&ptr,flags,NULL, sizeof(flags))) - ++count; - if (next_token(&ptr,extra,NULL, sizeof(extra))) - ++count; - - if (count <= 0) - continue; - - if (count > 0 && count < 2) - { - DEBUG(0,("getlmhostsent: Ill formed hosts line [%s]\n",line)); - continue; - } - - if (count >= 4) - { - DEBUG(0,("getlmhostsent: too many columns in lmhosts file (obsolete syntax)\n")); - continue; - } - - DEBUG(4, ("getlmhostsent: lmhost entry: %s %s %s\n", ip, name, flags)); - - if (strchr(flags,'G') || strchr(flags,'S')) - { - DEBUG(0,("getlmhostsent: group flag in lmhosts ignored (obsolete)\n")); - continue; - } - - *ipaddr = *interpret_addr2(ip); - - /* Extra feature. If the name ends in '#XX', where XX is a hex number, - then only add that name type. */ - if((ptr = strchr(name, '#')) != NULL) - { - char *endptr; - - ptr++; - *name_type = (int)strtol(ptr, &endptr, 16); - - if(!*ptr || (endptr == ptr)) - { - DEBUG(0,("getlmhostsent: invalid name %s containing '#'.\n", name)); - continue; - } - - *(--ptr) = '\0'; /* Truncate at the '#' */ - } - - return True; - } - - return False; -} - -/******************************************************** - Finish parsing the lmhosts file. -*********************************************************/ - -void endlmhosts(FILE *fp) -{ - fclose(fp); -} - -/******************************************************** -resolve via "bcast" method -*********************************************************/ -static BOOL resolve_bcast(const char *name, struct in_addr *return_ip, int name_type) -{ - int sock, i; - - /* - * "bcast" means do a broadcast lookup on all the local interfaces. - */ - - DEBUG(3,("resolve_name: Attempting broadcast lookup for name %s<0x%x>\n", name, name_type)); - - sock = open_socket_in( SOCK_DGRAM, 0, 3, - interpret_addr(lp_socket_address()), True ); - - if (sock != -1) { - struct in_addr *iplist = NULL; - int count; - int num_interfaces = iface_count(); - static char so_broadcast[] = "SO_BROADCAST"; - set_socket_options(sock, so_broadcast); - /* - * Lookup the name on all the interfaces, return on - * the first successful match. - */ - for( i = 0; i < num_interfaces; i++) { - struct in_addr sendto_ip; - /* Done this way to fix compiler error on IRIX 5.x */ - sendto_ip = *iface_bcast(*iface_n_ip(i)); - iplist = name_query(sock, name, name_type, True, - True, sendto_ip, &count, NULL); - if(iplist != NULL) { - *return_ip = iplist[0]; - free((char *)iplist); - close(sock); - return True; - } - } - close(sock); - } - - return False; -} - - - -/******************************************************** -resolve via "wins" method -*********************************************************/ -static BOOL resolve_wins(const char *name, struct in_addr *return_ip, int name_type) -{ - int sock; - struct in_addr wins_ip; - BOOL wins_ismyip; - - /* - * "wins" means do a unicast lookup to the WINS server. - * Ignore if there is no WINS server specified or if the - * WINS server is one of our interfaces (if we're being - * called from within nmbd - we can't do this call as we - * would then block). - */ - - DEBUG(3,("resolve_name: Attempting wins lookup for name %s<0x%x>\n", name, name_type)); - - if(!*lp_wins_server()) { - DEBUG(3,("resolve_name: WINS server resolution selected and no WINS server present.\n")); - return False; - } - - wins_ip = *interpret_addr2(lp_wins_server()); - wins_ismyip = ismyip(wins_ip); - - if((wins_ismyip && !global_in_nmbd) || !wins_ismyip) { - sock = open_socket_in( SOCK_DGRAM, 0, 3, - interpret_addr(lp_socket_address()), True ); - - if (sock != -1) { - struct in_addr *iplist = NULL; - int count; - iplist = name_query(sock, name, name_type, False, - True, wins_ip, &count, NULL); - if(iplist != NULL) { - *return_ip = iplist[0]; - free((char *)iplist); - close(sock); - return True; - } - close(sock); - } - } - - return False; -} - - -/******************************************************** -resolve via "lmhosts" method -*********************************************************/ -static BOOL resolve_lmhosts(const char *name, struct in_addr *return_ip, int name_type) -{ - /* - * "lmhosts" means parse the local lmhosts file. - */ - - FILE *fp; - pstring lmhost_name; - int name_type2; - - DEBUG(3,("resolve_name: Attempting lmhosts lookup for name %s<0x%x>\n", name, name_type)); - - fp = startlmhosts( LMHOSTSFILE ); - if(fp) { - while (getlmhostsent(fp, lmhost_name, &name_type2, return_ip)) { - if (strequal(name, lmhost_name) && - ((name_type2 == -1) || (name_type == name_type2)) - ) { - endlmhosts(fp); - return True; - } - } - endlmhosts(fp); - } - return False; -} - - -/******************************************************** -resolve via "hosts" method -*********************************************************/ -static BOOL resolve_hosts(const char *name, struct in_addr *return_ip) -{ - /* - * "host" means do a localhost, or dns lookup. - */ - struct hostent *hp; - - DEBUG(3,("resolve_name: Attempting host lookup for name %s<0x20>\n", name)); - - if (((hp = Get_Hostbyname(name)) != NULL) && (hp->h_addr != NULL)) { - putip((char *)return_ip,(char *)hp->h_addr); - return True; - } - return False; -} - - -/******************************************************** - Resolve a name into an IP address. Use this function if - the string is either an IP address, DNS or host name - or NetBIOS name. This uses the name switch in the - smb.conf to determine the order of name resolution. -*********************************************************/ -BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type) -{ - int i; - BOOL pure_address = True; - pstring name_resolve_list; - fstring tok; - char *ptr; - - if (strcmp(name,"0.0.0.0") == 0) { - return_ip->s_addr = 0; - return True; - } - if (strcmp(name,"255.255.255.255") == 0) { - return_ip->s_addr = 0xFFFFFFFF; - return True; - } - - for (i=0; pure_address && name[i]; i++) - if (!(isdigit((int)name[i]) || name[i] == '.')) - pure_address = False; - - /* if it's in the form of an IP address then get the lib to interpret it */ - if (pure_address) { - return_ip->s_addr = inet_addr(name); - return True; - } - - pstrcpy(name_resolve_list, lp_name_resolve_order()); - if (name_resolve_list == NULL || *name_resolve_list == '\0') - pstrcpy(name_resolve_list, "host"); - ptr = name_resolve_list; - - while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) { - if((strequal(tok, "host") || strequal(tok, "hosts"))) { - if (name_type == 0x20 && resolve_hosts(name, return_ip)) { - return True; - } - } else if(strequal( tok, "lmhosts")) { - if (resolve_lmhosts(name, return_ip, name_type)) { - return True; - } - } else if(strequal( tok, "wins")) { - /* don't resolve 1D via WINS */ - if (name_type != 0x1D && - resolve_wins(name, return_ip, name_type)) { - return True; - } - } else if(strequal( tok, "bcast")) { - if (resolve_bcast(name, return_ip, name_type)) { - return True; - } - } else { - DEBUG(0,("resolve_name: unknown name switch type %s\n", tok)); - } - } - - return False; -} - - -#if 0 -/******************************************************** -find the IP address of the master browser or DMB for a workgroup -*********************************************************/ -BOOL find_master_ip(char *group, struct in_addr *master_ip) -{ - if (resolve_name(group, master_ip, 0x1D)) return True; - - return resolve_name(group, master_ip, 0x1B); -} -#endif /* 0 */ +/* + Unix SMB/Netbios implementation. + Version 1.9. + name query routines + + Copyright (C) Andrew Tridgell 1994-1998 + + Copyright (C) 2011 + The Free Software Foundation, Inc. + + This file is part of the Midnight Commander. + + The Midnight Commander is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + The Midnight Commander is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + */ + +#include "includes.h" + +const char *unix_error_string (int error_num); +extern pstring scope; +extern int DEBUGLEVEL; + +/* nmbd.c sets this to True. */ +const BOOL global_in_nmbd = False; +#if 0 +/**************************************************************************** +interpret a node status response +****************************************************************************/ +static void +_interpret_node_status (char *p, char *master, char *rname) +{ + int numnames = CVAL (p, 0); + DEBUG (1, ("received %d names\n", numnames)); + + if (rname) + *rname = 0; + if (master) + *master = 0; + + p += 1; + while (numnames--) + { + char qname[17]; + int type; + fstring flags; + int i; + *flags = 0; + StrnCpy (qname, p, 15); + type = CVAL (p, 15); + p += 16; + + fstrcat (flags, (p[0] & 0x80) ? " " : " "); + if ((p[0] & 0x60) == 0x00) + fstrcat (flags, "B "); + if ((p[0] & 0x60) == 0x20) + fstrcat (flags, "P "); + if ((p[0] & 0x60) == 0x40) + fstrcat (flags, "M "); + if ((p[0] & 0x60) == 0x60) + fstrcat (flags, "H "); + if (p[0] & 0x10) + fstrcat (flags, " "); + if (p[0] & 0x08) + fstrcat (flags, " "); + if (p[0] & 0x04) + fstrcat (flags, " "); + if (p[0] & 0x02) + fstrcat (flags, " "); + + if (master && !*master && type == 0x1d) + { + StrnCpy (master, qname, 15); + trim_string (master, NULL, " "); + } + + if (rname && !*rname && type == 0x20 && !(p[0] & 0x80)) + { + StrnCpy (rname, qname, 15); + trim_string (rname, NULL, " "); + } + + for (i = strlen (qname); --i >= 0;) + { + if (!isprint ((int) qname[i])) + qname[i] = '.'; + } + DEBUG (1, ("\t%-15s <%02x> - %s\n", qname, type, flags)); + p += 2; + } + DEBUG (1, ("num_good_sends=%d num_good_receives=%d\n", IVAL (p, 20), IVAL (p, 24))); +} +#endif /* 0 */ + +/**************************************************************************** + do a netbios name query to find someones IP + returns an array of IP addresses or NULL if none + *count will be set to the number of addresses returned + ****************************************************************************/ +struct in_addr * +name_query (int fd, const char *name, int name_type, BOOL bcast, BOOL recurse, + struct in_addr to_ip, int *count, void (*fn) (struct packet_struct *)) +{ + BOOL found = False; + int i, retries = 3; + int retry_time = bcast ? 250 : 2000; + struct timeval tval; + struct packet_struct p; + struct packet_struct *p2; + struct nmb_packet *nmb = &p.packet.nmb; + static int name_trn_id = 0; + struct in_addr *ip_list = NULL; + + memset ((char *) &p, '\0', sizeof (p)); + (*count) = 0; + + if (!name_trn_id) + name_trn_id = ((unsigned) time (NULL) % (unsigned) 0x7FFF) + + ((unsigned) getpid () % (unsigned) 100); + name_trn_id = (name_trn_id + 1) % (unsigned) 0x7FFF; + + nmb->header.name_trn_id = name_trn_id; + nmb->header.opcode = 0; + nmb->header.response = False; + nmb->header.nm_flags.bcast = bcast; + nmb->header.nm_flags.recursion_available = False; + nmb->header.nm_flags.recursion_desired = recurse; + nmb->header.nm_flags.trunc = False; + nmb->header.nm_flags.authoritative = False; + nmb->header.rcode = 0; + nmb->header.qdcount = 1; + nmb->header.ancount = 0; + nmb->header.nscount = 0; + nmb->header.arcount = 0; + + make_nmb_name (&nmb->question.question_name, name, name_type); + + nmb->question.question_type = 0x20; + nmb->question.question_class = 0x1; + + p.ip = to_ip; + p.port = NMB_PORT; + p.fd = fd; + p.timestamp = time (NULL); + p.packet_type = NMB_PACKET; + + GetTimeOfDay (&tval); + + if (!send_packet (&p)) + return NULL; + + retries--; + + while (1) + { + struct timeval tval2; + GetTimeOfDay (&tval2); + if (TvalDiff (&tval, &tval2) > retry_time) + { + if (!retries) + break; + if (!found && !send_packet (&p)) + return NULL; + GetTimeOfDay (&tval); + retries--; + } + + if ((p2 = receive_packet (fd, NMB_PACKET, 90))) + { + struct nmb_packet *nmb2 = &p2->packet.nmb; + debug_nmb_packet (p2); + + if (nmb->header.name_trn_id != nmb2->header.name_trn_id || !nmb2->header.response) + { + /* + * Its not for us - maybe deal with it later + * (put it on the queue?). + */ + if (fn) + fn (p2); + else + free_packet (p2); + continue; + } + + if (nmb2->header.opcode != 0 || + nmb2->header.nm_flags.bcast || nmb2->header.rcode || !nmb2->header.ancount) + { + /* + * XXXX what do we do with this? Could be a redirect, but + * we'll discard it for the moment. + */ + free_packet (p2); + continue; + } + + ip_list = (struct in_addr *) Realloc (ip_list, sizeof (ip_list[0]) * + ((*count) + nmb2->answers->rdlength / 6)); + if (ip_list) + { + DEBUG (fn ? 3 : 2, ("Got a positive name query response from %s ( ", + inet_ntoa (p2->ip))); + for (i = 0; i < nmb2->answers->rdlength / 6; i++) + { + putip ((char *) &ip_list[(*count)], &nmb2->answers->rdata[2 + i * 6]); + DEBUG (fn ? 3 : 2, ("%s ", inet_ntoa (ip_list[(*count)]))); + (*count)++; + } + DEBUG (fn ? 3 : 2, (")\n")); + } + + found = True; + retries = 0; + free_packet (p2); + if (fn) + break; + + /* + * If we're doing a unicast lookup we only + * expect one reply. Don't wait the full 2 + * seconds if we got one. JRA. + */ + if (!bcast && found) + break; + } + } + + return ip_list; +} + +/******************************************************** + Start parsing the lmhosts file. +*********************************************************/ + +FILE * +startlmhosts (const char *fname) +{ + FILE *fp = sys_fopen (fname, "r"); + if (!fp) + { + DEBUG (4, ("startlmhosts: Cannot open lmhosts file %s. Error was %s\n", + fname, unix_error_string (errno))); + return NULL; + } + return fp; +} + +/******************************************************** + Parse the next line in the lmhosts file. +*********************************************************/ +BOOL +getlmhostsent (FILE * fp, pstring name, int *name_type, struct in_addr * ipaddr) +{ + pstring line; + + while (!feof (fp) && !ferror (fp)) + { + pstring ip, flags, extra; + char *ptr; + int count = 0; + + *name_type = -1; + + if (!fgets_slash (line, sizeof (pstring), fp)) + continue; + + if (*line == '#') + continue; + + pstrcpy (ip, ""); + pstrcpy (name, ""); + pstrcpy (flags, ""); + + ptr = line; + + if (next_token (&ptr, ip, NULL, sizeof (ip))) + ++count; + if (next_token (&ptr, name, NULL, sizeof (pstring))) + ++count; + if (next_token (&ptr, flags, NULL, sizeof (flags))) + ++count; + if (next_token (&ptr, extra, NULL, sizeof (extra))) + ++count; + + if (count <= 0) + continue; + + if (count > 0 && count < 2) + { + DEBUG (0, ("getlmhostsent: Ill formed hosts line [%s]\n", line)); + continue; + } + + if (count >= 4) + { + DEBUG (0, ("getlmhostsent: too many columns in lmhosts file (obsolete syntax)\n")); + continue; + } + + DEBUG (4, ("getlmhostsent: lmhost entry: %s %s %s\n", ip, name, flags)); + + if (strchr (flags, 'G') || strchr (flags, 'S')) + { + DEBUG (0, ("getlmhostsent: group flag in lmhosts ignored (obsolete)\n")); + continue; + } + + *ipaddr = *interpret_addr2 (ip); + + /* Extra feature. If the name ends in '#XX', where XX is a hex number, + then only add that name type. */ + if ((ptr = strchr (name, '#')) != NULL) + { + char *endptr; + + ptr++; + *name_type = (int) strtol (ptr, &endptr, 16); + + if (!*ptr || (endptr == ptr)) + { + DEBUG (0, ("getlmhostsent: invalid name %s containing '#'.\n", name)); + continue; + } + + *(--ptr) = '\0'; /* Truncate at the '#' */ + } + + return True; + } + + return False; +} + +/******************************************************** + Finish parsing the lmhosts file. +*********************************************************/ + +void +endlmhosts (FILE * fp) +{ + fclose (fp); +} + +/******************************************************** +resolve via "bcast" method +*********************************************************/ +static BOOL +resolve_bcast (const char *name, struct in_addr *return_ip, int name_type) +{ + int sock, i; + + /* + * "bcast" means do a broadcast lookup on all the local interfaces. + */ + + DEBUG (3, ("resolve_name: Attempting broadcast lookup for name %s<0x%x>\n", name, name_type)); + + sock = open_socket_in (SOCK_DGRAM, 0, 3, interpret_addr (lp_socket_address ()), True); + + if (sock != -1) + { + struct in_addr *iplist = NULL; + int count; + int num_interfaces = iface_count (); + static char so_broadcast[] = "SO_BROADCAST"; + set_socket_options (sock, so_broadcast); + /* + * Lookup the name on all the interfaces, return on + * the first successful match. + */ + for (i = 0; i < num_interfaces; i++) + { + struct in_addr sendto_ip; + /* Done this way to fix compiler error on IRIX 5.x */ + sendto_ip = *iface_bcast (*iface_n_ip (i)); + iplist = name_query (sock, name, name_type, True, True, sendto_ip, &count, NULL); + if (iplist != NULL) + { + *return_ip = iplist[0]; + free ((char *) iplist); + close (sock); + return True; + } + } + close (sock); + } + + return False; +} + + + +/******************************************************** +resolve via "wins" method +*********************************************************/ +static BOOL +resolve_wins (const char *name, struct in_addr *return_ip, int name_type) +{ + int sock; + struct in_addr wins_ip; + BOOL wins_ismyip; + + /* + * "wins" means do a unicast lookup to the WINS server. + * Ignore if there is no WINS server specified or if the + * WINS server is one of our interfaces (if we're being + * called from within nmbd - we can't do this call as we + * would then block). + */ + + DEBUG (3, ("resolve_name: Attempting wins lookup for name %s<0x%x>\n", name, name_type)); + + if (!*lp_wins_server ()) + { + DEBUG (3, ("resolve_name: WINS server resolution selected and no WINS server present.\n")); + return False; + } + + wins_ip = *interpret_addr2 (lp_wins_server ()); + wins_ismyip = ismyip (wins_ip); + + if ((wins_ismyip && !global_in_nmbd) || !wins_ismyip) + { + sock = open_socket_in (SOCK_DGRAM, 0, 3, interpret_addr (lp_socket_address ()), True); + + if (sock != -1) + { + struct in_addr *iplist = NULL; + int count; + iplist = name_query (sock, name, name_type, False, True, wins_ip, &count, NULL); + if (iplist != NULL) + { + *return_ip = iplist[0]; + free ((char *) iplist); + close (sock); + return True; + } + close (sock); + } + } + + return False; +} + + +/******************************************************** +resolve via "lmhosts" method +*********************************************************/ +static BOOL +resolve_lmhosts (const char *name, struct in_addr *return_ip, int name_type) +{ + /* + * "lmhosts" means parse the local lmhosts file. + */ + + FILE *fp; + pstring lmhost_name; + int name_type2; + + DEBUG (3, ("resolve_name: Attempting lmhosts lookup for name %s<0x%x>\n", name, name_type)); + + fp = startlmhosts (LMHOSTSFILE); + if (fp) + { + while (getlmhostsent (fp, lmhost_name, &name_type2, return_ip)) + { + if (strequal (name, lmhost_name) && ((name_type2 == -1) || (name_type == name_type2))) + { + endlmhosts (fp); + return True; + } + } + endlmhosts (fp); + } + return False; +} + + +/******************************************************** +resolve via "hosts" method +*********************************************************/ +static BOOL +resolve_hosts (const char *name, struct in_addr *return_ip) +{ + /* + * "host" means do a localhost, or dns lookup. + */ + struct hostent *hp; + + DEBUG (3, ("resolve_name: Attempting host lookup for name %s<0x20>\n", name)); + + if (((hp = Get_Hostbyname (name)) != NULL) && (hp->h_addr != NULL)) + { + putip ((char *) return_ip, (char *) hp->h_addr); + return True; + } + return False; +} + + +/******************************************************** + Resolve a name into an IP address. Use this function if + the string is either an IP address, DNS or host name + or NetBIOS name. This uses the name switch in the + smb.conf to determine the order of name resolution. +*********************************************************/ +BOOL +resolve_name (const char *name, struct in_addr * return_ip, int name_type) +{ + int i; + BOOL pure_address = True; + pstring name_resolve_list; + fstring tok; + char *ptr; + + if (strcmp (name, "0.0.0.0") == 0) + { + return_ip->s_addr = 0; + return True; + } + if (strcmp (name, "255.255.255.255") == 0) + { + return_ip->s_addr = 0xFFFFFFFF; + return True; + } + + for (i = 0; pure_address && name[i]; i++) + if (!(isdigit ((int) name[i]) || name[i] == '.')) + pure_address = False; + + /* if it's in the form of an IP address then get the lib to interpret it */ + if (pure_address) + { + return_ip->s_addr = inet_addr (name); + return True; + } + + pstrcpy (name_resolve_list, lp_name_resolve_order ()); + if (name_resolve_list == NULL || *name_resolve_list == '\0') + pstrcpy (name_resolve_list, "host"); + ptr = name_resolve_list; + + while (next_token (&ptr, tok, LIST_SEP, sizeof (tok))) + { + if ((strequal (tok, "host") || strequal (tok, "hosts"))) + { + if (name_type == 0x20 && resolve_hosts (name, return_ip)) + { + return True; + } + } + else if (strequal (tok, "lmhosts")) + { + if (resolve_lmhosts (name, return_ip, name_type)) + { + return True; + } + } + else if (strequal (tok, "wins")) + { + /* don't resolve 1D via WINS */ + if (name_type != 0x1D && resolve_wins (name, return_ip, name_type)) + { + return True; + } + } + else if (strequal (tok, "bcast")) + { + if (resolve_bcast (name, return_ip, name_type)) + { + return True; + } + } + else + { + DEBUG (0, ("resolve_name: unknown name switch type %s\n", tok)); + } + } + + return False; +} + + +#if 0 +/******************************************************** +find the IP address of the master browser or DMB for a workgroup +*********************************************************/ +BOOL +find_master_ip (char *group, struct in_addr * master_ip) +{ + if (resolve_name (group, master_ip, 0x1D)) + return True; + + return resolve_name (group, master_ip, 0x1B); +} +#endif /* 0 */ diff --git a/src/vfs/smbfs/helpers/libsmb/nmblib.c b/src/vfs/smbfs/helpers/libsmb/nmblib.c dissimilarity index 71% index c5b906956..158c7e8ea 100644 --- a/src/vfs/smbfs/helpers/libsmb/nmblib.c +++ b/src/vfs/smbfs/helpers/libsmb/nmblib.c @@ -1,972 +1,1036 @@ -/* - Unix SMB/Netbios implementation. - Version 1.9. - NBT netbios library routines - - Copyright (C) Andrew Tridgell 1994-1998 - - Copyright (C) 2011 - The Free Software Foundation, Inc. - - This file is part of the Midnight Commander. - - The Midnight Commander is free software: you can redistribute it - and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of the License, - or (at your option) any later version. - - The Midnight Commander is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "includes.h" - -const char *unix_error_string (int error_num); -extern int DEBUGLEVEL; - -int num_good_sends = 0; -int num_good_receives = 0; - -static struct opcode_names { - const char *nmb_opcode_name; - int opcode; -} const nmb_header_opcode_names[] = { - {"Query", 0 }, - {"Registration", 5 }, - {"Release", 6 }, - {"WACK", 7 }, - {"Refresh", 8 }, - {"Refresh(altcode)", 9 }, - {"Multi-homed Registration", 15 }, - {0, -1 } -}; - -/**************************************************************************** - * Lookup a nmb opcode name. - ****************************************************************************/ -static const char *lookup_opcode_name( int opcode ) -{ - const struct opcode_names *op_namep = nmb_header_opcode_names; - - while(op_namep->nmb_opcode_name) { - if(opcode == op_namep->opcode) - return op_namep->nmb_opcode_name; - op_namep++; - } - return ""; -} - -/**************************************************************************** - print out a res_rec structure - ****************************************************************************/ -static void debug_nmb_res_rec(struct res_rec *res, const char *hdr) -{ - int i, j; - - DEBUGADD( 4, ( " %s: nmb_name=%s rr_type=%d rr_class=%d ttl=%d\n", - hdr, - nmb_namestr(&res->rr_name), - res->rr_type, - res->rr_class, - res->ttl ) ); - - if( res->rdlength == 0 || res->rdata == NULL ) - return; - - for (i = 0; i < res->rdlength; i+= 16) - { - DEBUGADD(4, (" %s %3x char ", hdr, i)); - - for (j = 0; j < 16; j++) - { - unsigned char x = res->rdata[i+j]; - if (x < 32 || x > 127) x = '.'; - - if (i+j >= res->rdlength) break; - DEBUGADD(4, ("%c", x)); - } - - DEBUGADD(4, (" hex ")); - - for (j = 0; j < 16; j++) - { - if (i+j >= res->rdlength) break; - DEBUGADD(4, ("%02X", (unsigned char)res->rdata[i+j])); - } - - DEBUGADD(4, ("\n")); - } -} - -/**************************************************************************** - process a nmb packet - ****************************************************************************/ -void debug_nmb_packet(struct packet_struct *p) -{ - struct nmb_packet *nmb = &p->packet.nmb; - - if( DEBUGLVL( 4 ) ) - { - dbgtext( "nmb packet from %s(%d) header: id=%d opcode=%s(%d) response=%s\n", - inet_ntoa(p->ip), p->port, - nmb->header.name_trn_id, - lookup_opcode_name(nmb->header.opcode), - nmb->header.opcode, - BOOLSTR(nmb->header.response) ); - dbgtext( " header: flags: bcast=%s rec_avail=%s rec_des=%s trunc=%s auth=%s\n", - BOOLSTR(nmb->header.nm_flags.bcast), - BOOLSTR(nmb->header.nm_flags.recursion_available), - BOOLSTR(nmb->header.nm_flags.recursion_desired), - BOOLSTR(nmb->header.nm_flags.trunc), - BOOLSTR(nmb->header.nm_flags.authoritative) ); - dbgtext( " header: rcode=%d qdcount=%d ancount=%d nscount=%d arcount=%d\n", - nmb->header.rcode, - nmb->header.qdcount, - nmb->header.ancount, - nmb->header.nscount, - nmb->header.arcount ); - } - - if (nmb->header.qdcount) - { - DEBUGADD( 4, ( " question: q_name=%s q_type=%d q_class=%d\n", - nmb_namestr(&nmb->question.question_name), - nmb->question.question_type, - nmb->question.question_class) ); - } - - if (nmb->answers && nmb->header.ancount) - { - debug_nmb_res_rec(nmb->answers,"answers"); - } - if (nmb->nsrecs && nmb->header.nscount) - { - debug_nmb_res_rec(nmb->nsrecs,"nsrecs"); - } - if (nmb->additional && nmb->header.arcount) - { - debug_nmb_res_rec(nmb->additional,"additional"); - } -} - -/******************************************************************* - handle "compressed" name pointers - ******************************************************************/ -static BOOL handle_name_ptrs(unsigned char *ubuf,int *offset,int length, - BOOL *got_pointer,int *ret) -{ - int loop_count=0; - - while ((ubuf[*offset] & 0xC0) == 0xC0) { - if (!*got_pointer) (*ret) += 2; - (*got_pointer)=True; - (*offset) = ((ubuf[*offset] & ~0xC0)<<8) | ubuf[(*offset)+1]; - if (loop_count++ == 10 || (*offset) < 0 || (*offset)>(length-2)) { - return(False); - } - } - return(True); -} - -/******************************************************************* - parse a nmb name from "compressed" format to something readable - return the space taken by the name, or 0 if the name is invalid - ******************************************************************/ -static int parse_nmb_name(char *inbuf,int offset,int length, struct nmb_name *name) -{ - int m,n=0; - unsigned char *ubuf = (unsigned char *)inbuf; - int ret = 0; - BOOL got_pointer=False; - - if (length - offset < 2) - return(0); - - /* handle initial name pointers */ - if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) - return(0); - - m = ubuf[offset]; - - if (!m) - return(0); - if ((m & 0xC0) || offset+m+2 > length) - return(0); - - memset((char *)name,'\0',sizeof(*name)); - - /* the "compressed" part */ - if (!got_pointer) - ret += m + 2; - offset++; - while (m > 0) { - unsigned char c1,c2; - c1 = ubuf[offset++]-'A'; - c2 = ubuf[offset++]-'A'; - if ((c1 & 0xF0) || (c2 & 0xF0) || ((size_t) n > sizeof(name->name)-1)) - return(0); - name->name[n++] = (c1<<4) | c2; - m -= 2; - } - name->name[n] = 0; - - if (n==16) { - /* parse out the name type, - its always in the 16th byte of the name */ - name->name_type = ((unsigned char)name->name[15]) & 0xff; - - /* remove trailing spaces */ - name->name[15] = 0; - n = 14; - while (n && name->name[n]==' ') - name->name[n--] = 0; - } - - /* now the domain parts (if any) */ - n = 0; - while (ubuf[offset]) { - /* we can have pointers within the domain part as well */ - if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) - return(0); - - m = ubuf[offset]; - if (!got_pointer) - ret += m+1; - if (n) - name->scope[n++] = '.'; - if (m+2+offset>length || (size_t) n+m+1 >sizeof(name->scope)) - return(0); - offset++; - while (m--) - name->scope[n++] = (char)ubuf[offset++]; - } - name->scope[n++] = 0; - - return(ret); -} - - -/******************************************************************* - put a compressed nmb name into a buffer. return the length of the - compressed name - - compressed names are really weird. The "compression" doubles the - size. The idea is that it also means that compressed names conform - to the doman name system. See RFC1002. - ******************************************************************/ -static int put_nmb_name(char *buf,int offset,struct nmb_name *name) -{ - int ret,m; - fstring buf1; - char *p; - - if (strcmp(name->name,"*") == 0) { - /* special case for wildcard name */ - memset(buf1,'\0',20); - buf1[0] = '*'; - buf1[15] = name->name_type; - } else { - slprintf(buf1, sizeof(buf1) - 1,"%-15.15s%c",name->name,name->name_type); - } - - buf[offset] = 0x20; - - ret = 34; - - for (m=0;m<16;m++) { - buf[offset+1+2*m] = 'A' + ((buf1[m]>>4)&0xF); - buf[offset+2+2*m] = 'A' + (buf1[m]&0xF); - } - offset += 33; - - buf[offset] = 0; - - if (name->scope[0]) { - /* XXXX this scope handling needs testing */ - ret += strlen(name->scope) + 1; - pstrcpy(&buf[offset+1],name->scope); - - p = &buf[offset+1]; - while ((p = strchr(p,'.'))) { - buf[offset] = PTR_DIFF(p,&buf[offset+1]); - offset += (buf[offset] + 1); - p = &buf[offset+1]; - } - buf[offset] = strlen(&buf[offset+1]); - } - - return(ret); -} - -/******************************************************************* - useful for debugging messages - ******************************************************************/ -char *nmb_namestr(struct nmb_name *n) -{ - static int i=0; - static fstring ret[4]; - char *p = ret[i]; - - if (!n->scope[0]) - slprintf(p,sizeof(fstring)-1, "%s<%02x>",n->name,n->name_type); - else - slprintf(p,sizeof(fstring)-1, "%s<%02x>.%s",n->name,n->name_type,n->scope); - - i = (i+1)%4; - return(p); -} - -/******************************************************************* - allocate and parse some resource records - ******************************************************************/ -static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length, - struct res_rec **recs, int count) -{ - int i; - *recs = (struct res_rec *)malloc(sizeof(**recs)*count); - if (!*recs) return(False); - - memset((char *)*recs,'\0',sizeof(**recs)*count); - - for (i=0;i length) { - free(*recs); - return(False); - } - (*recs)[i].rr_type = RSVAL(inbuf,(*offset)); - (*recs)[i].rr_class = RSVAL(inbuf,(*offset)+2); - (*recs)[i].ttl = RIVAL(inbuf,(*offset)+4); - (*recs)[i].rdlength = RSVAL(inbuf,(*offset)+8); - (*offset) += 10; - if ((size_t)(*recs)[i].rdlength>sizeof((*recs)[i].rdata) || - (*offset)+(*recs)[i].rdlength > length) { - free(*recs); - return(False); - } - memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength); - (*offset) += (*recs)[i].rdlength; - } - return(True); -} - -/******************************************************************* - put a resource record into a packet - ******************************************************************/ -static int put_res_rec(char *buf,int offset,struct res_rec *recs,int count) -{ - int ret=0; - int i; - - for (i=0;i> 8) & 0xFF)); - buf[offset+1] = (ptr_offset & 0xFF); - offset += 2; - ret += 2; - RSSVAL(buf,offset,rec->rr_type); - RSSVAL(buf,offset+2,rec->rr_class); - RSIVAL(buf,offset+4,rec->ttl); - RSSVAL(buf,offset+8,rec->rdlength); - memcpy(buf+offset+10,rec->rdata,rec->rdlength); - offset += 10+rec->rdlength; - ret += 10+rec->rdlength; - - return(ret); -} - -/******************************************************************* - parse a dgram packet. Return False if the packet can't be parsed - or is invalid for some reason, True otherwise - - this is documented in section 4.4.1 of RFC1002 - ******************************************************************/ -static BOOL parse_dgram(char *inbuf,int length,struct dgram_packet *dgram) -{ - int offset; - int flags; - - memset((char *)dgram,'\0',sizeof(*dgram)); - - if (length < 14) return(False); - - dgram->header.msg_type = CVAL(inbuf,0); - flags = CVAL(inbuf,1); - dgram->header.flags.node_type = (enum node_type)((flags>>2)&3); - if (flags & 1) dgram->header.flags.more = True; - if (flags & 2) dgram->header.flags.first = True; - dgram->header.dgm_id = RSVAL(inbuf,2); - putip((char *)&dgram->header.source_ip,inbuf+4); - dgram->header.source_port = RSVAL(inbuf,8); - dgram->header.dgm_length = RSVAL(inbuf,10); - dgram->header.packet_offset = RSVAL(inbuf,12); - - offset = 14; - - if (dgram->header.msg_type == 0x10 || - dgram->header.msg_type == 0x11 || - dgram->header.msg_type == 0x12) { - offset += parse_nmb_name(inbuf,offset,length,&dgram->source_name); - offset += parse_nmb_name(inbuf,offset,length,&dgram->dest_name); - } - - if (offset >= length || ((size_t)length-offset > sizeof(dgram->data))) - return(False); - - dgram->datasize = length-offset; - memcpy(dgram->data,inbuf+offset,dgram->datasize); - - return(True); -} - - -/******************************************************************* - parse a nmb packet. Return False if the packet can't be parsed - or is invalid for some reason, True otherwise - ******************************************************************/ -static BOOL parse_nmb(char *inbuf,int length,struct nmb_packet *nmb) -{ - int nm_flags,offset; - - memset((char *)nmb,'\0',sizeof(*nmb)); - - if (length < 12) return(False); - - /* parse the header */ - nmb->header.name_trn_id = RSVAL(inbuf,0); - - DEBUG(10,("parse_nmb: packet id = %d\n", nmb->header.name_trn_id)); - - nmb->header.opcode = (CVAL(inbuf,2) >> 3) & 0xF; - nmb->header.response = ((CVAL(inbuf,2)>>7)&1)?True:False; - nm_flags = ((CVAL(inbuf,2) & 0x7) << 4) + (CVAL(inbuf,3)>>4); - nmb->header.nm_flags.bcast = (nm_flags&1)?True:False; - nmb->header.nm_flags.recursion_available = (nm_flags&8)?True:False; - nmb->header.nm_flags.recursion_desired = (nm_flags&0x10)?True:False; - nmb->header.nm_flags.trunc = (nm_flags&0x20)?True:False; - nmb->header.nm_flags.authoritative = (nm_flags&0x40)?True:False; - nmb->header.rcode = CVAL(inbuf,3) & 0xF; - nmb->header.qdcount = RSVAL(inbuf,4); - nmb->header.ancount = RSVAL(inbuf,6); - nmb->header.nscount = RSVAL(inbuf,8); - nmb->header.arcount = RSVAL(inbuf,10); - - if (nmb->header.qdcount) { - offset = parse_nmb_name(inbuf,12,length,&nmb->question.question_name); - if (!offset) return(False); - - if (length - (12+offset) < 4) return(False); - nmb->question.question_type = RSVAL(inbuf,12+offset); - nmb->question.question_class = RSVAL(inbuf,12+offset+2); - - offset += 12+4; - } else { - offset = 12; - } - - /* and any resource records */ - if (nmb->header.ancount && - !parse_alloc_res_rec(inbuf,&offset,length,&nmb->answers, - nmb->header.ancount)) - return(False); - - if (nmb->header.nscount && - !parse_alloc_res_rec(inbuf,&offset,length,&nmb->nsrecs, - nmb->header.nscount)) - return(False); - - if (nmb->header.arcount && - !parse_alloc_res_rec(inbuf,&offset,length,&nmb->additional, - nmb->header.arcount)) - return(False); - - return(True); -} -#if 0 -/******************************************************************* - 'Copy constructor' for an nmb packet - ******************************************************************/ -static struct packet_struct *copy_nmb_packet(struct packet_struct *packet) -{ - struct nmb_packet *nmb; - struct nmb_packet *copy_nmb; - struct packet_struct *pkt_copy; - - if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL) - { - DEBUG(0,("copy_nmb_packet: malloc fail.\n")); - return NULL; - } - - /* Structure copy of entire thing. */ - - *pkt_copy = *packet; - - /* Ensure this copy is not locked. */ - pkt_copy->locked = False; - - /* Ensure this copy has no resource records. */ - nmb = &packet->packet.nmb; - copy_nmb = &pkt_copy->packet.nmb; - - copy_nmb->answers = NULL; - copy_nmb->nsrecs = NULL; - copy_nmb->additional = NULL; - - /* Now copy any resource records. */ - - if (nmb->answers) - { - if((copy_nmb->answers = (struct res_rec *) - malloc(nmb->header.ancount * sizeof(struct res_rec))) == NULL) - goto free_and_exit; - memcpy((char *)copy_nmb->answers, (char *)nmb->answers, - nmb->header.ancount * sizeof(struct res_rec)); - } - if (nmb->nsrecs) - { - if((copy_nmb->nsrecs = (struct res_rec *) - malloc(nmb->header.nscount * sizeof(struct res_rec))) == NULL) - goto free_and_exit; - memcpy((char *)copy_nmb->nsrecs, (char *)nmb->nsrecs, - nmb->header.nscount * sizeof(struct res_rec)); - } - if (nmb->additional) - { - if((copy_nmb->additional = (struct res_rec *) - malloc(nmb->header.arcount * sizeof(struct res_rec))) == NULL) - goto free_and_exit; - memcpy((char *)copy_nmb->additional, (char *)nmb->additional, - nmb->header.arcount * sizeof(struct res_rec)); - } - - return pkt_copy; - -free_and_exit: - - if(copy_nmb->answers) - free((char *)copy_nmb->answers); - if(copy_nmb->nsrecs) - free((char *)copy_nmb->nsrecs); - if(copy_nmb->additional) - free((char *)copy_nmb->additional); - free((char *)pkt_copy); - - DEBUG(0,("copy_nmb_packet: malloc fail in resource records.\n")); - return NULL; -} - -/******************************************************************* - 'Copy constructor' for a dgram packet - ******************************************************************/ -static struct packet_struct *copy_dgram_packet(struct packet_struct *packet) -{ - struct packet_struct *pkt_copy; - - if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL) - { - DEBUG(0,("copy_dgram_packet: malloc fail.\n")); - return NULL; - } - - /* Structure copy of entire thing. */ - - *pkt_copy = *packet; - - /* Ensure this copy is not locked. */ - pkt_copy->locked = False; - - /* There are no additional pointers in a dgram packet, - we are finished. */ - return pkt_copy; -} - -/******************************************************************* - 'Copy constructor' for a generic packet - ******************************************************************/ -struct packet_struct *copy_packet(struct packet_struct *packet) -{ - if(packet->packet_type == NMB_PACKET) - return copy_nmb_packet(packet); - else if (packet->packet_type == DGRAM_PACKET) - return copy_dgram_packet(packet); - return NULL; -} -#endif /* 0 */ -/******************************************************************* - free up any resources associated with an nmb packet - ******************************************************************/ -static void free_nmb_packet(struct nmb_packet *nmb) -{ - if (nmb->answers) free(nmb->answers); - if (nmb->nsrecs) free(nmb->nsrecs); - if (nmb->additional) free(nmb->additional); -} - -/******************************************************************* - free up any resources associated with a dgram packet - ******************************************************************/ -static void free_dgram_packet(struct dgram_packet *nmb) -{ - /* We have nothing to do for a dgram packet. */ - (void) nmb; -} - -/******************************************************************* - free up any resources associated with a packet - ******************************************************************/ -void free_packet(struct packet_struct *packet) -{ - if (packet->locked) - return; - if (packet->packet_type == NMB_PACKET) - free_nmb_packet(&packet->packet.nmb); - else if (packet->packet_type == DGRAM_PACKET) - free_dgram_packet(&packet->packet.dgram); - free(packet); -} - -/******************************************************************* - read a packet from a socket and parse it, returning a packet ready - to be used or put on the queue. This assumes a UDP socket - ******************************************************************/ -struct packet_struct *read_packet(int fd,enum packet_type packet_type) -{ - extern struct in_addr lastip; - extern int lastport; - struct packet_struct *packet; - char buf[MAX_DGRAM_SIZE]; - int length; - BOOL ok=False; - - length = read_udp_socket(fd,buf,sizeof(buf)); - if (length < MIN_DGRAM_SIZE) return(NULL); - - packet = (struct packet_struct *)malloc(sizeof(*packet)); - if (!packet) return(NULL); - - packet->next = NULL; - packet->prev = NULL; - packet->ip = lastip; - packet->port = lastport; - packet->fd = fd; - packet->locked = False; - packet->timestamp = time(NULL); - packet->packet_type = packet_type; - switch (packet_type) - { - case NMB_PACKET: - ok = parse_nmb(buf,length,&packet->packet.nmb); - break; - - case DGRAM_PACKET: - ok = parse_dgram(buf,length,&packet->packet.dgram); - break; - } - if (!ok) { - DEBUG(10,("read_packet: discarding packet id = %d\n", - packet->packet.nmb.header.name_trn_id)); - free_packet(packet); - return(NULL); - } - - num_good_receives++; - - DEBUG(5,("Received a packet of len %d from (%s) port %d\n", - length, inet_ntoa(packet->ip), packet->port ) ); - - return(packet); -} - - -/******************************************************************* - send a udp packet on a already open socket - ******************************************************************/ -static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port) -{ - BOOL ret; - struct sockaddr_in sock_out; - - /* set the address and port */ - memset((char *)&sock_out,'\0',sizeof(sock_out)); - putip((char *)&sock_out.sin_addr,(char *)&ip); - sock_out.sin_port = htons( port ); - sock_out.sin_family = AF_INET; - - DEBUG( 5, ( "Sending a packet of len %d to (%s) on port %d\n", - len, inet_ntoa(ip), port ) ); - - ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out, - sizeof(sock_out)) >= 0); - - if (!ret) - DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n", - inet_ntoa(ip),port, unix_error_string (errno))); - - if (ret) - num_good_sends++; - - return(ret); -} - -/******************************************************************* - build a dgram packet ready for sending - - XXXX This currently doesn't handle packets too big for one - datagram. It should split them and use the packet_offset, more and - first flags to handle the fragmentation. Yuck. - ******************************************************************/ -static int build_dgram(char *buf,struct packet_struct *p) -{ - struct dgram_packet *dgram = &p->packet.dgram; - unsigned char *ubuf = (unsigned char *)buf; - int offset=0; - - /* put in the header */ - ubuf[0] = dgram->header.msg_type; - ubuf[1] = (((int)dgram->header.flags.node_type)<<2); - if (dgram->header.flags.more) ubuf[1] |= 1; - if (dgram->header.flags.first) ubuf[1] |= 2; - RSSVAL(ubuf,2,dgram->header.dgm_id); - putip(ubuf+4,(char *)&dgram->header.source_ip); - RSSVAL(ubuf,8,dgram->header.source_port); - RSSVAL(ubuf,12,dgram->header.packet_offset); - - offset = 14; - - if (dgram->header.msg_type == 0x10 || - dgram->header.msg_type == 0x11 || - dgram->header.msg_type == 0x12) { - offset += put_nmb_name((char *)ubuf,offset,&dgram->source_name); - offset += put_nmb_name((char *)ubuf,offset,&dgram->dest_name); - } - - memcpy(ubuf+offset,dgram->data,dgram->datasize); - offset += dgram->datasize; - - /* automatically set the dgm_length */ - dgram->header.dgm_length = offset; - RSSVAL(ubuf,10,dgram->header.dgm_length); - - return(offset); -} - -/******************************************************************* - build a nmb name - *******************************************************************/ -void make_nmb_name( struct nmb_name *n, const char *name, int type ) -{ - extern pstring global_scope; - memset( (char *)n, '\0', sizeof(struct nmb_name) ); - StrnCpy( n->name, name, 15 ); - strupper( n->name ); - n->name_type = (unsigned int)type & 0xFF; - StrnCpy( n->scope, global_scope, 63 ); - strupper( n->scope ); -} - -/******************************************************************* - Compare two nmb names - ******************************************************************/ -#if 0 -BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2) -{ - return ((n1->name_type == n2->name_type) && - strequal(n1->name ,n2->name ) && - strequal(n1->scope,n2->scope)); -} -#endif /* 0 */ -/******************************************************************* - build a nmb packet ready for sending - - XXXX this currently relies on not being passed something that expands - to a packet too big for the buffer. Eventually this should be - changed to set the trunc bit so the receiver can request the rest - via tcp (when that becomes supported) - ******************************************************************/ -static int build_nmb(char *buf,struct packet_struct *p) -{ - struct nmb_packet *nmb = &p->packet.nmb; - unsigned char *ubuf = (unsigned char *)buf; - int offset=0; - - /* put in the header */ - RSSVAL(ubuf,offset,nmb->header.name_trn_id); - ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3; - if (nmb->header.response) ubuf[offset+2] |= (1<<7); - if (nmb->header.nm_flags.authoritative && - nmb->header.response) ubuf[offset+2] |= 0x4; - if (nmb->header.nm_flags.trunc) ubuf[offset+2] |= 0x2; - if (nmb->header.nm_flags.recursion_desired) ubuf[offset+2] |= 0x1; - if (nmb->header.nm_flags.recursion_available && - nmb->header.response) ubuf[offset+3] |= 0x80; - if (nmb->header.nm_flags.bcast) ubuf[offset+3] |= 0x10; - ubuf[offset+3] |= (nmb->header.rcode & 0xF); - - RSSVAL(ubuf,offset+4,nmb->header.qdcount); - RSSVAL(ubuf,offset+6,nmb->header.ancount); - RSSVAL(ubuf,offset+8,nmb->header.nscount); - RSSVAL(ubuf,offset+10,nmb->header.arcount); - - offset += 12; - if (nmb->header.qdcount) { - /* XXXX this doesn't handle a qdcount of > 1 */ - offset += put_nmb_name((char *)ubuf,offset,&nmb->question.question_name); - RSSVAL(ubuf,offset,nmb->question.question_type); - RSSVAL(ubuf,offset+2,nmb->question.question_class); - offset += 4; - } - - if (nmb->header.ancount) - offset += put_res_rec((char *)ubuf,offset,nmb->answers, - nmb->header.ancount); - - if (nmb->header.nscount) - offset += put_res_rec((char *)ubuf,offset,nmb->nsrecs, - nmb->header.nscount); - - /* - * The spec says we must put compressed name pointers - * in the following outgoing packets : - * NAME_REGISTRATION_REQUEST, NAME_REFRESH_REQUEST, - * NAME_RELEASE_REQUEST. - */ - - if((nmb->header.response == False) && - ((nmb->header.opcode == NMB_NAME_REG_OPCODE) || - (nmb->header.opcode == NMB_NAME_RELEASE_OPCODE) || - (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_8) || - (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_9) || - (nmb->header.opcode == NMB_NAME_MULTIHOMED_REG_OPCODE)) && - (nmb->header.arcount == 1)) { - - offset += put_compressed_name_ptr(ubuf,offset,nmb->additional,12); - - } else if (nmb->header.arcount) { - offset += put_res_rec((char *)ubuf,offset,nmb->additional, - nmb->header.arcount); - } - return(offset); -} - - -/******************************************************************* - send a packet_struct - ******************************************************************/ -BOOL send_packet(struct packet_struct *p) -{ - char buf[1024]; - int len=0; - - memset(buf,'\0',sizeof(buf)); - - switch (p->packet_type) - { - case NMB_PACKET: - len = build_nmb(buf,p); - debug_nmb_packet(p); - break; - - case DGRAM_PACKET: - len = build_dgram(buf,p); - break; - } - - if (!len) return(False); - - return(send_udp(p->fd,buf,len,p->ip,p->port)); -} - -/**************************************************************************** - receive a packet with timeout on a open UDP filedescriptor - The timeout is in milliseconds - ***************************************************************************/ -struct packet_struct *receive_packet(int fd,enum packet_type type,int t) -{ - fd_set fds; - struct timeval timeout; - - FD_ZERO(&fds); - FD_SET(fd,&fds); - timeout.tv_sec = t/1000; - timeout.tv_usec = 1000*(t%1000); - - sys_select(fd+1,&fds,&timeout); - - if (FD_ISSET(fd,&fds)) - return(read_packet(fd,type)); - - return(NULL); -} - -#if 0 -/**************************************************************************** -return the number of bits that match between two 4 character buffers - ***************************************************************************/ -static int matching_bits(uchar *p1, uchar *p2) -{ - int i, j, ret = 0; - for (i=0; i<4; i++) { - if (p1[i] != p2[i]) break; - ret += 8; - } - - if (i==4) return ret; - - for (j=0; j<8; j++) { - if ((p1[i] & (1<<(7-j))) != (p2[i] & (1<<(7-j)))) break; - ret++; - } - - return ret; -} - -static uchar sort_ip[4]; - -/**************************************************************************** -compare two query reply records - ***************************************************************************/ -static int name_query_comp(uchar *p1, uchar *p2) -{ - return matching_bits(p2+2, sort_ip) - matching_bits(p1+2, sort_ip); -} - -/**************************************************************************** -sort a set of 6 byte name query response records so that the IPs that -have the most leading bits in common with the specified address come first - ***************************************************************************/ -void sort_query_replies(char *data, int n, struct in_addr ip) -{ - if (n <= 1) return; - - putip(sort_ip, (char *)&ip); - - qsort(data, n, 6, QSORT_CAST name_query_comp); -} -#endif /*0 */ +/* + Unix SMB/Netbios implementation. + Version 1.9. + NBT netbios library routines + + Copyright (C) Andrew Tridgell 1994-1998 + + Copyright (C) 2011 + The Free Software Foundation, Inc. + + This file is part of the Midnight Commander. + + The Midnight Commander is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + The Midnight Commander is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + */ + +#include "includes.h" + +const char *unix_error_string (int error_num); +extern int DEBUGLEVEL; + +int num_good_sends = 0; +int num_good_receives = 0; + +static struct opcode_names +{ + const char *nmb_opcode_name; + int opcode; +} const nmb_header_opcode_names[] = { + {"Query", 0}, + {"Registration", 5}, + {"Release", 6}, + {"WACK", 7}, + {"Refresh", 8}, + {"Refresh(altcode)", 9}, + {"Multi-homed Registration", 15}, + {0, -1} +}; + +/**************************************************************************** + * Lookup a nmb opcode name. + ****************************************************************************/ +static const char * +lookup_opcode_name (int opcode) +{ + const struct opcode_names *op_namep = nmb_header_opcode_names; + + while (op_namep->nmb_opcode_name) + { + if (opcode == op_namep->opcode) + return op_namep->nmb_opcode_name; + op_namep++; + } + return ""; +} + +/**************************************************************************** + print out a res_rec structure + ****************************************************************************/ +static void +debug_nmb_res_rec (struct res_rec *res, const char *hdr) +{ + int i, j; + + DEBUGADD (4, (" %s: nmb_name=%s rr_type=%d rr_class=%d ttl=%d\n", + hdr, nmb_namestr (&res->rr_name), res->rr_type, res->rr_class, res->ttl)); + + if (res->rdlength == 0 || res->rdata == NULL) + return; + + for (i = 0; i < res->rdlength; i += 16) + { + DEBUGADD (4, (" %s %3x char ", hdr, i)); + + for (j = 0; j < 16; j++) + { + unsigned char x = res->rdata[i + j]; + if (x < 32 || x > 127) + x = '.'; + + if (i + j >= res->rdlength) + break; + DEBUGADD (4, ("%c", x)); + } + + DEBUGADD (4, (" hex ")); + + for (j = 0; j < 16; j++) + { + if (i + j >= res->rdlength) + break; + DEBUGADD (4, ("%02X", (unsigned char) res->rdata[i + j])); + } + + DEBUGADD (4, ("\n")); + } +} + +/**************************************************************************** + process a nmb packet + ****************************************************************************/ +void +debug_nmb_packet (struct packet_struct *p) +{ + struct nmb_packet *nmb = &p->packet.nmb; + + if (DEBUGLVL (4)) + { + dbgtext ("nmb packet from %s(%d) header: id=%d opcode=%s(%d) response=%s\n", + inet_ntoa (p->ip), p->port, + nmb->header.name_trn_id, + lookup_opcode_name (nmb->header.opcode), + nmb->header.opcode, BOOLSTR (nmb->header.response)); + dbgtext (" header: flags: bcast=%s rec_avail=%s rec_des=%s trunc=%s auth=%s\n", + BOOLSTR (nmb->header.nm_flags.bcast), + BOOLSTR (nmb->header.nm_flags.recursion_available), + BOOLSTR (nmb->header.nm_flags.recursion_desired), + BOOLSTR (nmb->header.nm_flags.trunc), + BOOLSTR (nmb->header.nm_flags.authoritative)); + dbgtext (" header: rcode=%d qdcount=%d ancount=%d nscount=%d arcount=%d\n", + nmb->header.rcode, + nmb->header.qdcount, + nmb->header.ancount, nmb->header.nscount, nmb->header.arcount); + } + + if (nmb->header.qdcount) + { + DEBUGADD (4, (" question: q_name=%s q_type=%d q_class=%d\n", + nmb_namestr (&nmb->question.question_name), + nmb->question.question_type, nmb->question.question_class)); + } + + if (nmb->answers && nmb->header.ancount) + { + debug_nmb_res_rec (nmb->answers, "answers"); + } + if (nmb->nsrecs && nmb->header.nscount) + { + debug_nmb_res_rec (nmb->nsrecs, "nsrecs"); + } + if (nmb->additional && nmb->header.arcount) + { + debug_nmb_res_rec (nmb->additional, "additional"); + } +} + +/******************************************************************* + handle "compressed" name pointers + ******************************************************************/ +static BOOL +handle_name_ptrs (unsigned char *ubuf, int *offset, int length, BOOL * got_pointer, int *ret) +{ + int loop_count = 0; + + while ((ubuf[*offset] & 0xC0) == 0xC0) + { + if (!*got_pointer) + (*ret) += 2; + (*got_pointer) = True; + (*offset) = ((ubuf[*offset] & ~0xC0) << 8) | ubuf[(*offset) + 1]; + if (loop_count++ == 10 || (*offset) < 0 || (*offset) > (length - 2)) + { + return (False); + } + } + return (True); +} + +/******************************************************************* + parse a nmb name from "compressed" format to something readable + return the space taken by the name, or 0 if the name is invalid + ******************************************************************/ +static int +parse_nmb_name (char *inbuf, int offset, int length, struct nmb_name *name) +{ + int m, n = 0; + unsigned char *ubuf = (unsigned char *) inbuf; + int ret = 0; + BOOL got_pointer = False; + + if (length - offset < 2) + return (0); + + /* handle initial name pointers */ + if (!handle_name_ptrs (ubuf, &offset, length, &got_pointer, &ret)) + return (0); + + m = ubuf[offset]; + + if (!m) + return (0); + if ((m & 0xC0) || offset + m + 2 > length) + return (0); + + memset ((char *) name, '\0', sizeof (*name)); + + /* the "compressed" part */ + if (!got_pointer) + ret += m + 2; + offset++; + while (m > 0) + { + unsigned char c1, c2; + c1 = ubuf[offset++] - 'A'; + c2 = ubuf[offset++] - 'A'; + if ((c1 & 0xF0) || (c2 & 0xF0) || ((size_t) n > sizeof (name->name) - 1)) + return (0); + name->name[n++] = (c1 << 4) | c2; + m -= 2; + } + name->name[n] = 0; + + if (n == 16) + { + /* parse out the name type, + its always in the 16th byte of the name */ + name->name_type = ((unsigned char) name->name[15]) & 0xff; + + /* remove trailing spaces */ + name->name[15] = 0; + n = 14; + while (n && name->name[n] == ' ') + name->name[n--] = 0; + } + + /* now the domain parts (if any) */ + n = 0; + while (ubuf[offset]) + { + /* we can have pointers within the domain part as well */ + if (!handle_name_ptrs (ubuf, &offset, length, &got_pointer, &ret)) + return (0); + + m = ubuf[offset]; + if (!got_pointer) + ret += m + 1; + if (n) + name->scope[n++] = '.'; + if (m + 2 + offset > length || (size_t) n + m + 1 > sizeof (name->scope)) + return (0); + offset++; + while (m--) + name->scope[n++] = (char) ubuf[offset++]; + } + name->scope[n++] = 0; + + return (ret); +} + + +/******************************************************************* + put a compressed nmb name into a buffer. return the length of the + compressed name + + compressed names are really weird. The "compression" doubles the + size. The idea is that it also means that compressed names conform + to the doman name system. See RFC1002. + ******************************************************************/ +static int +put_nmb_name (char *buf, int offset, struct nmb_name *name) +{ + int ret, m; + fstring buf1; + char *p; + + if (strcmp (name->name, "*") == 0) + { + /* special case for wildcard name */ + memset (buf1, '\0', 20); + buf1[0] = '*'; + buf1[15] = name->name_type; + } + else + { + slprintf (buf1, sizeof (buf1) - 1, "%-15.15s%c", name->name, name->name_type); + } + + buf[offset] = 0x20; + + ret = 34; + + for (m = 0; m < 16; m++) + { + buf[offset + 1 + 2 * m] = 'A' + ((buf1[m] >> 4) & 0xF); + buf[offset + 2 + 2 * m] = 'A' + (buf1[m] & 0xF); + } + offset += 33; + + buf[offset] = 0; + + if (name->scope[0]) + { + /* XXXX this scope handling needs testing */ + ret += strlen (name->scope) + 1; + pstrcpy (&buf[offset + 1], name->scope); + + p = &buf[offset + 1]; + while ((p = strchr (p, '.'))) + { + buf[offset] = PTR_DIFF (p, &buf[offset + 1]); + offset += (buf[offset] + 1); + p = &buf[offset + 1]; + } + buf[offset] = strlen (&buf[offset + 1]); + } + + return (ret); +} + +/******************************************************************* + useful for debugging messages + ******************************************************************/ +char * +nmb_namestr (struct nmb_name *n) +{ + static int i = 0; + static fstring ret[4]; + char *p = ret[i]; + + if (!n->scope[0]) + slprintf (p, sizeof (fstring) - 1, "%s<%02x>", n->name, n->name_type); + else + slprintf (p, sizeof (fstring) - 1, "%s<%02x>.%s", n->name, n->name_type, n->scope); + + i = (i + 1) % 4; + return (p); +} + +/******************************************************************* + allocate and parse some resource records + ******************************************************************/ +static BOOL +parse_alloc_res_rec (char *inbuf, int *offset, int length, struct res_rec **recs, int count) +{ + int i; + *recs = (struct res_rec *) malloc (sizeof (**recs) * count); + if (!*recs) + return (False); + + memset ((char *) *recs, '\0', sizeof (**recs) * count); + + for (i = 0; i < count; i++) + { + int l = parse_nmb_name (inbuf, *offset, length, &(*recs)[i].rr_name); + (*offset) += l; + if (!l || (*offset) + 10 > length) + { + free (*recs); + return (False); + } + (*recs)[i].rr_type = RSVAL (inbuf, (*offset)); + (*recs)[i].rr_class = RSVAL (inbuf, (*offset) + 2); + (*recs)[i].ttl = RIVAL (inbuf, (*offset) + 4); + (*recs)[i].rdlength = RSVAL (inbuf, (*offset) + 8); + (*offset) += 10; + if ((size_t) (*recs)[i].rdlength > sizeof ((*recs)[i].rdata) || + (*offset) + (*recs)[i].rdlength > length) + { + free (*recs); + return (False); + } + memcpy ((*recs)[i].rdata, inbuf + (*offset), (*recs)[i].rdlength); + (*offset) += (*recs)[i].rdlength; + } + return (True); +} + +/******************************************************************* + put a resource record into a packet + ******************************************************************/ +static int +put_res_rec (char *buf, int offset, struct res_rec *recs, int count) +{ + int ret = 0; + int i; + + for (i = 0; i < count; i++) + { + int l = put_nmb_name (buf, offset, &recs[i].rr_name); + offset += l; + ret += l; + RSSVAL (buf, offset, recs[i].rr_type); + RSSVAL (buf, offset + 2, recs[i].rr_class); + RSIVAL (buf, offset + 4, recs[i].ttl); + RSSVAL (buf, offset + 8, recs[i].rdlength); + memcpy (buf + offset + 10, recs[i].rdata, recs[i].rdlength); + offset += 10 + recs[i].rdlength; + ret += 10 + recs[i].rdlength; + } + + return (ret); +} + +/******************************************************************* + put a compressed name pointer record into a packet + ******************************************************************/ +static int +put_compressed_name_ptr (unsigned char *buf, int offset, struct res_rec *rec, int ptr_offset) +{ + int ret = 0; + buf[offset] = (0xC0 | ((ptr_offset >> 8) & 0xFF)); + buf[offset + 1] = (ptr_offset & 0xFF); + offset += 2; + ret += 2; + RSSVAL (buf, offset, rec->rr_type); + RSSVAL (buf, offset + 2, rec->rr_class); + RSIVAL (buf, offset + 4, rec->ttl); + RSSVAL (buf, offset + 8, rec->rdlength); + memcpy (buf + offset + 10, rec->rdata, rec->rdlength); + offset += 10 + rec->rdlength; + ret += 10 + rec->rdlength; + + return (ret); +} + +/******************************************************************* + parse a dgram packet. Return False if the packet can't be parsed + or is invalid for some reason, True otherwise + + this is documented in section 4.4.1 of RFC1002 + ******************************************************************/ +static BOOL +parse_dgram (char *inbuf, int length, struct dgram_packet *dgram) +{ + int offset; + int flags; + + memset ((char *) dgram, '\0', sizeof (*dgram)); + + if (length < 14) + return (False); + + dgram->header.msg_type = CVAL (inbuf, 0); + flags = CVAL (inbuf, 1); + dgram->header.flags.node_type = (enum node_type) ((flags >> 2) & 3); + if (flags & 1) + dgram->header.flags.more = True; + if (flags & 2) + dgram->header.flags.first = True; + dgram->header.dgm_id = RSVAL (inbuf, 2); + putip ((char *) &dgram->header.source_ip, inbuf + 4); + dgram->header.source_port = RSVAL (inbuf, 8); + dgram->header.dgm_length = RSVAL (inbuf, 10); + dgram->header.packet_offset = RSVAL (inbuf, 12); + + offset = 14; + + if (dgram->header.msg_type == 0x10 || + dgram->header.msg_type == 0x11 || dgram->header.msg_type == 0x12) + { + offset += parse_nmb_name (inbuf, offset, length, &dgram->source_name); + offset += parse_nmb_name (inbuf, offset, length, &dgram->dest_name); + } + + if (offset >= length || ((size_t) length - offset > sizeof (dgram->data))) + return (False); + + dgram->datasize = length - offset; + memcpy (dgram->data, inbuf + offset, dgram->datasize); + + return (True); +} + + +/******************************************************************* + parse a nmb packet. Return False if the packet can't be parsed + or is invalid for some reason, True otherwise + ******************************************************************/ +static BOOL +parse_nmb (char *inbuf, int length, struct nmb_packet *nmb) +{ + int nm_flags, offset; + + memset ((char *) nmb, '\0', sizeof (*nmb)); + + if (length < 12) + return (False); + + /* parse the header */ + nmb->header.name_trn_id = RSVAL (inbuf, 0); + + DEBUG (10, ("parse_nmb: packet id = %d\n", nmb->header.name_trn_id)); + + nmb->header.opcode = (CVAL (inbuf, 2) >> 3) & 0xF; + nmb->header.response = ((CVAL (inbuf, 2) >> 7) & 1) ? True : False; + nm_flags = ((CVAL (inbuf, 2) & 0x7) << 4) + (CVAL (inbuf, 3) >> 4); + nmb->header.nm_flags.bcast = (nm_flags & 1) ? True : False; + nmb->header.nm_flags.recursion_available = (nm_flags & 8) ? True : False; + nmb->header.nm_flags.recursion_desired = (nm_flags & 0x10) ? True : False; + nmb->header.nm_flags.trunc = (nm_flags & 0x20) ? True : False; + nmb->header.nm_flags.authoritative = (nm_flags & 0x40) ? True : False; + nmb->header.rcode = CVAL (inbuf, 3) & 0xF; + nmb->header.qdcount = RSVAL (inbuf, 4); + nmb->header.ancount = RSVAL (inbuf, 6); + nmb->header.nscount = RSVAL (inbuf, 8); + nmb->header.arcount = RSVAL (inbuf, 10); + + if (nmb->header.qdcount) + { + offset = parse_nmb_name (inbuf, 12, length, &nmb->question.question_name); + if (!offset) + return (False); + + if (length - (12 + offset) < 4) + return (False); + nmb->question.question_type = RSVAL (inbuf, 12 + offset); + nmb->question.question_class = RSVAL (inbuf, 12 + offset + 2); + + offset += 12 + 4; + } + else + { + offset = 12; + } + + /* and any resource records */ + if (nmb->header.ancount && + !parse_alloc_res_rec (inbuf, &offset, length, &nmb->answers, nmb->header.ancount)) + return (False); + + if (nmb->header.nscount && + !parse_alloc_res_rec (inbuf, &offset, length, &nmb->nsrecs, nmb->header.nscount)) + return (False); + + if (nmb->header.arcount && + !parse_alloc_res_rec (inbuf, &offset, length, &nmb->additional, nmb->header.arcount)) + return (False); + + return (True); +} + +#if 0 +/******************************************************************* + 'Copy constructor' for an nmb packet + ******************************************************************/ +static struct packet_struct * +copy_nmb_packet (struct packet_struct *packet) +{ + struct nmb_packet *nmb; + struct nmb_packet *copy_nmb; + struct packet_struct *pkt_copy; + + if ((pkt_copy = (struct packet_struct *) malloc (sizeof (*packet))) == NULL) + { + DEBUG (0, ("copy_nmb_packet: malloc fail.\n")); + return NULL; + } + + /* Structure copy of entire thing. */ + + *pkt_copy = *packet; + + /* Ensure this copy is not locked. */ + pkt_copy->locked = False; + + /* Ensure this copy has no resource records. */ + nmb = &packet->packet.nmb; + copy_nmb = &pkt_copy->packet.nmb; + + copy_nmb->answers = NULL; + copy_nmb->nsrecs = NULL; + copy_nmb->additional = NULL; + + /* Now copy any resource records. */ + + if (nmb->answers) + { + if ((copy_nmb->answers = (struct res_rec *) + malloc (nmb->header.ancount * sizeof (struct res_rec))) == NULL) + goto free_and_exit; + memcpy ((char *) copy_nmb->answers, (char *) nmb->answers, + nmb->header.ancount * sizeof (struct res_rec)); + } + if (nmb->nsrecs) + { + if ((copy_nmb->nsrecs = (struct res_rec *) + malloc (nmb->header.nscount * sizeof (struct res_rec))) == NULL) + goto free_and_exit; + memcpy ((char *) copy_nmb->nsrecs, (char *) nmb->nsrecs, + nmb->header.nscount * sizeof (struct res_rec)); + } + if (nmb->additional) + { + if ((copy_nmb->additional = (struct res_rec *) + malloc (nmb->header.arcount * sizeof (struct res_rec))) == NULL) + goto free_and_exit; + memcpy ((char *) copy_nmb->additional, (char *) nmb->additional, + nmb->header.arcount * sizeof (struct res_rec)); + } + + return pkt_copy; + + free_and_exit: + + if (copy_nmb->answers) + free ((char *) copy_nmb->answers); + if (copy_nmb->nsrecs) + free ((char *) copy_nmb->nsrecs); + if (copy_nmb->additional) + free ((char *) copy_nmb->additional); + free ((char *) pkt_copy); + + DEBUG (0, ("copy_nmb_packet: malloc fail in resource records.\n")); + return NULL; +} + +/******************************************************************* + 'Copy constructor' for a dgram packet + ******************************************************************/ +static struct packet_struct * +copy_dgram_packet (struct packet_struct *packet) +{ + struct packet_struct *pkt_copy; + + if ((pkt_copy = (struct packet_struct *) malloc (sizeof (*packet))) == NULL) + { + DEBUG (0, ("copy_dgram_packet: malloc fail.\n")); + return NULL; + } + + /* Structure copy of entire thing. */ + + *pkt_copy = *packet; + + /* Ensure this copy is not locked. */ + pkt_copy->locked = False; + + /* There are no additional pointers in a dgram packet, + we are finished. */ + return pkt_copy; +} + +/******************************************************************* + 'Copy constructor' for a generic packet + ******************************************************************/ +struct packet_struct * +copy_packet (struct packet_struct *packet) +{ + if (packet->packet_type == NMB_PACKET) + return copy_nmb_packet (packet); + else if (packet->packet_type == DGRAM_PACKET) + return copy_dgram_packet (packet); + return NULL; +} +#endif /* 0 */ +/******************************************************************* + free up any resources associated with an nmb packet + ******************************************************************/ +static void +free_nmb_packet (struct nmb_packet *nmb) +{ + if (nmb->answers) + free (nmb->answers); + if (nmb->nsrecs) + free (nmb->nsrecs); + if (nmb->additional) + free (nmb->additional); +} + +/******************************************************************* + free up any resources associated with a dgram packet + ******************************************************************/ +static void +free_dgram_packet (struct dgram_packet *nmb) +{ + /* We have nothing to do for a dgram packet. */ + (void) nmb; +} + +/******************************************************************* + free up any resources associated with a packet + ******************************************************************/ +void +free_packet (struct packet_struct *packet) +{ + if (packet->locked) + return; + if (packet->packet_type == NMB_PACKET) + free_nmb_packet (&packet->packet.nmb); + else if (packet->packet_type == DGRAM_PACKET) + free_dgram_packet (&packet->packet.dgram); + free (packet); +} + +/******************************************************************* + read a packet from a socket and parse it, returning a packet ready + to be used or put on the queue. This assumes a UDP socket + ******************************************************************/ +struct packet_struct * +read_packet (int fd, enum packet_type packet_type) +{ + extern struct in_addr lastip; + extern int lastport; + struct packet_struct *packet; + char buf[MAX_DGRAM_SIZE]; + int length; + BOOL ok = False; + + length = read_udp_socket (fd, buf, sizeof (buf)); + if (length < MIN_DGRAM_SIZE) + return (NULL); + + packet = (struct packet_struct *) malloc (sizeof (*packet)); + if (!packet) + return (NULL); + + packet->next = NULL; + packet->prev = NULL; + packet->ip = lastip; + packet->port = lastport; + packet->fd = fd; + packet->locked = False; + packet->timestamp = time (NULL); + packet->packet_type = packet_type; + switch (packet_type) + { + case NMB_PACKET: + ok = parse_nmb (buf, length, &packet->packet.nmb); + break; + + case DGRAM_PACKET: + ok = parse_dgram (buf, length, &packet->packet.dgram); + break; + } + if (!ok) + { + DEBUG (10, ("read_packet: discarding packet id = %d\n", + packet->packet.nmb.header.name_trn_id)); + free_packet (packet); + return (NULL); + } + + num_good_receives++; + + DEBUG (5, ("Received a packet of len %d from (%s) port %d\n", + length, inet_ntoa (packet->ip), packet->port)); + + return (packet); +} + + +/******************************************************************* + send a udp packet on a already open socket + ******************************************************************/ +static BOOL +send_udp (int fd, char *buf, int len, struct in_addr ip, int port) +{ + BOOL ret; + struct sockaddr_in sock_out; + + /* set the address and port */ + memset ((char *) &sock_out, '\0', sizeof (sock_out)); + putip ((char *) &sock_out.sin_addr, (char *) &ip); + sock_out.sin_port = htons (port); + sock_out.sin_family = AF_INET; + + DEBUG (5, ("Sending a packet of len %d to (%s) on port %d\n", len, inet_ntoa (ip), port)); + + ret = (sendto (fd, buf, len, 0, (struct sockaddr *) &sock_out, sizeof (sock_out)) >= 0); + + if (!ret) + DEBUG (0, ("Packet send failed to %s(%d) ERRNO=%s\n", + inet_ntoa (ip), port, unix_error_string (errno))); + + if (ret) + num_good_sends++; + + return (ret); +} + +/******************************************************************* + build a dgram packet ready for sending + + XXXX This currently doesn't handle packets too big for one + datagram. It should split them and use the packet_offset, more and + first flags to handle the fragmentation. Yuck. + ******************************************************************/ +static int +build_dgram (char *buf, struct packet_struct *p) +{ + struct dgram_packet *dgram = &p->packet.dgram; + unsigned char *ubuf = (unsigned char *) buf; + int offset = 0; + + /* put in the header */ + ubuf[0] = dgram->header.msg_type; + ubuf[1] = (((int) dgram->header.flags.node_type) << 2); + if (dgram->header.flags.more) + ubuf[1] |= 1; + if (dgram->header.flags.first) + ubuf[1] |= 2; + RSSVAL (ubuf, 2, dgram->header.dgm_id); + putip (ubuf + 4, (char *) &dgram->header.source_ip); + RSSVAL (ubuf, 8, dgram->header.source_port); + RSSVAL (ubuf, 12, dgram->header.packet_offset); + + offset = 14; + + if (dgram->header.msg_type == 0x10 || + dgram->header.msg_type == 0x11 || dgram->header.msg_type == 0x12) + { + offset += put_nmb_name ((char *) ubuf, offset, &dgram->source_name); + offset += put_nmb_name ((char *) ubuf, offset, &dgram->dest_name); + } + + memcpy (ubuf + offset, dgram->data, dgram->datasize); + offset += dgram->datasize; + + /* automatically set the dgm_length */ + dgram->header.dgm_length = offset; + RSSVAL (ubuf, 10, dgram->header.dgm_length); + + return (offset); +} + +/******************************************************************* + build a nmb name + *******************************************************************/ +void +make_nmb_name (struct nmb_name *n, const char *name, int type) +{ + extern pstring global_scope; + memset ((char *) n, '\0', sizeof (struct nmb_name)); + StrnCpy (n->name, name, 15); + strupper (n->name); + n->name_type = (unsigned int) type & 0xFF; + StrnCpy (n->scope, global_scope, 63); + strupper (n->scope); +} + +/******************************************************************* + Compare two nmb names + ******************************************************************/ +#if 0 +BOOL +nmb_name_equal (struct nmb_name *n1, struct nmb_name *n2) +{ + return ((n1->name_type == n2->name_type) && + strequal (n1->name, n2->name) && strequal (n1->scope, n2->scope)); +} +#endif /* 0 */ +/******************************************************************* + build a nmb packet ready for sending + + XXXX this currently relies on not being passed something that expands + to a packet too big for the buffer. Eventually this should be + changed to set the trunc bit so the receiver can request the rest + via tcp (when that becomes supported) + ******************************************************************/ +static int +build_nmb (char *buf, struct packet_struct *p) +{ + struct nmb_packet *nmb = &p->packet.nmb; + unsigned char *ubuf = (unsigned char *) buf; + int offset = 0; + + /* put in the header */ + RSSVAL (ubuf, offset, nmb->header.name_trn_id); + ubuf[offset + 2] = (nmb->header.opcode & 0xF) << 3; + if (nmb->header.response) + ubuf[offset + 2] |= (1 << 7); + if (nmb->header.nm_flags.authoritative && nmb->header.response) + ubuf[offset + 2] |= 0x4; + if (nmb->header.nm_flags.trunc) + ubuf[offset + 2] |= 0x2; + if (nmb->header.nm_flags.recursion_desired) + ubuf[offset + 2] |= 0x1; + if (nmb->header.nm_flags.recursion_available && nmb->header.response) + ubuf[offset + 3] |= 0x80; + if (nmb->header.nm_flags.bcast) + ubuf[offset + 3] |= 0x10; + ubuf[offset + 3] |= (nmb->header.rcode & 0xF); + + RSSVAL (ubuf, offset + 4, nmb->header.qdcount); + RSSVAL (ubuf, offset + 6, nmb->header.ancount); + RSSVAL (ubuf, offset + 8, nmb->header.nscount); + RSSVAL (ubuf, offset + 10, nmb->header.arcount); + + offset += 12; + if (nmb->header.qdcount) + { + /* XXXX this doesn't handle a qdcount of > 1 */ + offset += put_nmb_name ((char *) ubuf, offset, &nmb->question.question_name); + RSSVAL (ubuf, offset, nmb->question.question_type); + RSSVAL (ubuf, offset + 2, nmb->question.question_class); + offset += 4; + } + + if (nmb->header.ancount) + offset += put_res_rec ((char *) ubuf, offset, nmb->answers, nmb->header.ancount); + + if (nmb->header.nscount) + offset += put_res_rec ((char *) ubuf, offset, nmb->nsrecs, nmb->header.nscount); + + /* + * The spec says we must put compressed name pointers + * in the following outgoing packets : + * NAME_REGISTRATION_REQUEST, NAME_REFRESH_REQUEST, + * NAME_RELEASE_REQUEST. + */ + + if ((nmb->header.response == False) && + ((nmb->header.opcode == NMB_NAME_REG_OPCODE) || + (nmb->header.opcode == NMB_NAME_RELEASE_OPCODE) || + (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_8) || + (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_9) || + (nmb->header.opcode == NMB_NAME_MULTIHOMED_REG_OPCODE)) && (nmb->header.arcount == 1)) + { + + offset += put_compressed_name_ptr (ubuf, offset, nmb->additional, 12); + + } + else if (nmb->header.arcount) + { + offset += put_res_rec ((char *) ubuf, offset, nmb->additional, nmb->header.arcount); + } + return (offset); +} + + +/******************************************************************* + send a packet_struct + ******************************************************************/ +BOOL +send_packet (struct packet_struct * p) +{ + char buf[1024]; + int len = 0; + + memset (buf, '\0', sizeof (buf)); + + switch (p->packet_type) + { + case NMB_PACKET: + len = build_nmb (buf, p); + debug_nmb_packet (p); + break; + + case DGRAM_PACKET: + len = build_dgram (buf, p); + break; + } + + if (!len) + return (False); + + return (send_udp (p->fd, buf, len, p->ip, p->port)); +} + +/**************************************************************************** + receive a packet with timeout on a open UDP filedescriptor + The timeout is in milliseconds + ***************************************************************************/ +struct packet_struct * +receive_packet (int fd, enum packet_type type, int t) +{ + fd_set fds; + struct timeval timeout; + + FD_ZERO (&fds); + FD_SET (fd, &fds); + timeout.tv_sec = t / 1000; + timeout.tv_usec = 1000 * (t % 1000); + + sys_select (fd + 1, &fds, &timeout); + + if (FD_ISSET (fd, &fds)) + return (read_packet (fd, type)); + + return (NULL); +} + +#if 0 +/**************************************************************************** +return the number of bits that match between two 4 character buffers + ***************************************************************************/ +static int +matching_bits (uchar * p1, uchar * p2) +{ + int i, j, ret = 0; + for (i = 0; i < 4; i++) + { + if (p1[i] != p2[i]) + break; + ret += 8; + } + + if (i == 4) + return ret; + + for (j = 0; j < 8; j++) + { + if ((p1[i] & (1 << (7 - j))) != (p2[i] & (1 << (7 - j)))) + break; + ret++; + } + + return ret; +} + +static uchar sort_ip[4]; + +/**************************************************************************** +compare two query reply records + ***************************************************************************/ +static int +name_query_comp (uchar * p1, uchar * p2) +{ + return matching_bits (p2 + 2, sort_ip) - matching_bits (p1 + 2, sort_ip); +} + +/**************************************************************************** +sort a set of 6 byte name query response records so that the IPs that +have the most leading bits in common with the specified address come first + ***************************************************************************/ +void +sort_query_replies (char *data, int n, struct in_addr ip) +{ + if (n <= 1) + return; + + putip (sort_ip, (char *) &ip); + + qsort (data, n, 6, QSORT_CAST name_query_comp); +} +#endif /*0 */ diff --git a/src/vfs/smbfs/helpers/libsmb/nterr.c b/src/vfs/smbfs/helpers/libsmb/nterr.c dissimilarity index 96% index cf5ea4ef3..4612abd32 100644 --- a/src/vfs/smbfs/helpers/libsmb/nterr.c +++ b/src/vfs/smbfs/helpers/libsmb/nterr.c @@ -1,558 +1,557 @@ -/* NT error codes. please read nterr.h - - Copyright (C) 2011 - The Free Software Foundation, Inc. - - This file is part of the Midnight Commander. - - The Midnight Commander is free software: you can redistribute it - and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of the License, - or (at your option) any later version. - - The Midnight Commander is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "includes.h" -#include "nterr.h" - -typedef struct -{ - const char *nt_errstr; - uint32 nt_errcode; - -} nt_err_code_struct; - -nt_err_code_struct const nt_errs[] = -{ - { "NT_STATUS_UNSUCCESSFUL", NT_STATUS_UNSUCCESSFUL }, - { "NT_STATUS_NOT_IMPLEMENTED", NT_STATUS_NOT_IMPLEMENTED }, - { "NT_STATUS_INVALID_INFO_CLASS", NT_STATUS_INVALID_INFO_CLASS }, - { "NT_STATUS_INFO_LENGTH_MISMATCH", NT_STATUS_INFO_LENGTH_MISMATCH }, - { "NT_STATUS_ACCESS_VIOLATION", NT_STATUS_ACCESS_VIOLATION }, - { "STATUS_BUFFER_OVERFLOW", STATUS_BUFFER_OVERFLOW }, - { "NT_STATUS_IN_PAGE_ERROR", NT_STATUS_IN_PAGE_ERROR }, - { "NT_STATUS_PAGEFILE_QUOTA", NT_STATUS_PAGEFILE_QUOTA }, - { "NT_STATUS_INVALID_HANDLE", NT_STATUS_INVALID_HANDLE }, - { "NT_STATUS_BAD_INITIAL_STACK", NT_STATUS_BAD_INITIAL_STACK }, - { "NT_STATUS_BAD_INITIAL_PC", NT_STATUS_BAD_INITIAL_PC }, - { "NT_STATUS_INVALID_CID", NT_STATUS_INVALID_CID }, - { "NT_STATUS_TIMER_NOT_CANCELED", NT_STATUS_TIMER_NOT_CANCELED }, - { "NT_STATUS_INVALID_PARAMETER", NT_STATUS_INVALID_PARAMETER }, - { "NT_STATUS_NO_SUCH_DEVICE", NT_STATUS_NO_SUCH_DEVICE }, - { "NT_STATUS_NO_SUCH_FILE", NT_STATUS_NO_SUCH_FILE }, - { "NT_STATUS_INVALID_DEVICE_REQUEST", NT_STATUS_INVALID_DEVICE_REQUEST }, - { "NT_STATUS_END_OF_FILE", NT_STATUS_END_OF_FILE }, - { "NT_STATUS_WRONG_VOLUME", NT_STATUS_WRONG_VOLUME }, - { "NT_STATUS_NO_MEDIA_IN_DEVICE", NT_STATUS_NO_MEDIA_IN_DEVICE }, - { "NT_STATUS_UNRECOGNIZED_MEDIA", NT_STATUS_UNRECOGNIZED_MEDIA }, - { "NT_STATUS_NONEXISTENT_SECTOR", NT_STATUS_NONEXISTENT_SECTOR }, - { "NT_STATUS_MORE_PROCESSING_REQUIRED", NT_STATUS_MORE_PROCESSING_REQUIRED }, - { "NT_STATUS_NO_MEMORY", NT_STATUS_NO_MEMORY }, - { "NT_STATUS_CONFLICTING_ADDRESSES", NT_STATUS_CONFLICTING_ADDRESSES }, - { "NT_STATUS_NOT_MAPPED_VIEW", NT_STATUS_NOT_MAPPED_VIEW }, - { "NT_STATUS_UNABLE_TO_FREE_VM", NT_STATUS_UNABLE_TO_FREE_VM }, - { "NT_STATUS_UNABLE_TO_DELETE_SECTION", NT_STATUS_UNABLE_TO_DELETE_SECTION }, - { "NT_STATUS_INVALID_SYSTEM_SERVICE", NT_STATUS_INVALID_SYSTEM_SERVICE }, - { "NT_STATUS_ILLEGAL_INSTRUCTION", NT_STATUS_ILLEGAL_INSTRUCTION }, - { "NT_STATUS_INVALID_LOCK_SEQUENCE", NT_STATUS_INVALID_LOCK_SEQUENCE }, - { "NT_STATUS_INVALID_VIEW_SIZE", NT_STATUS_INVALID_VIEW_SIZE }, - { "NT_STATUS_INVALID_FILE_FOR_SECTION", NT_STATUS_INVALID_FILE_FOR_SECTION }, - { "NT_STATUS_ALREADY_COMMITTED", NT_STATUS_ALREADY_COMMITTED }, - { "NT_STATUS_ACCESS_DENIED", NT_STATUS_ACCESS_DENIED }, - { "NT_STATUS_BUFFER_TOO_SMALL", NT_STATUS_BUFFER_TOO_SMALL }, - { "NT_STATUS_OBJECT_TYPE_MISMATCH", NT_STATUS_OBJECT_TYPE_MISMATCH }, - { "NT_STATUS_NONCONTINUABLE_EXCEPTION", NT_STATUS_NONCONTINUABLE_EXCEPTION }, - { "NT_STATUS_INVALID_DISPOSITION", NT_STATUS_INVALID_DISPOSITION }, - { "NT_STATUS_UNWIND", NT_STATUS_UNWIND }, - { "NT_STATUS_BAD_STACK", NT_STATUS_BAD_STACK }, - { "NT_STATUS_INVALID_UNWIND_TARGET", NT_STATUS_INVALID_UNWIND_TARGET }, - { "NT_STATUS_NOT_LOCKED", NT_STATUS_NOT_LOCKED }, - { "NT_STATUS_PARITY_ERROR", NT_STATUS_PARITY_ERROR }, - { "NT_STATUS_UNABLE_TO_DECOMMIT_VM", NT_STATUS_UNABLE_TO_DECOMMIT_VM }, - { "NT_STATUS_NOT_COMMITTED", NT_STATUS_NOT_COMMITTED }, - { "NT_STATUS_INVALID_PORT_ATTRIBUTES", NT_STATUS_INVALID_PORT_ATTRIBUTES }, - { "NT_STATUS_PORT_MESSAGE_TOO_LONG", NT_STATUS_PORT_MESSAGE_TOO_LONG }, - { "NT_STATUS_INVALID_PARAMETER_MIX", NT_STATUS_INVALID_PARAMETER_MIX }, - { "NT_STATUS_INVALID_QUOTA_LOWER", NT_STATUS_INVALID_QUOTA_LOWER }, - { "NT_STATUS_DISK_CORRUPT_ERROR", NT_STATUS_DISK_CORRUPT_ERROR }, - { "NT_STATUS_OBJECT_NAME_INVALID", NT_STATUS_OBJECT_NAME_INVALID }, - { "NT_STATUS_OBJECT_NAME_NOT_FOUND", NT_STATUS_OBJECT_NAME_NOT_FOUND }, - { "NT_STATUS_OBJECT_NAME_COLLISION", NT_STATUS_OBJECT_NAME_COLLISION }, - { "NT_STATUS_HANDLE_NOT_WAITABLE", NT_STATUS_HANDLE_NOT_WAITABLE }, - { "NT_STATUS_PORT_DISCONNECTED", NT_STATUS_PORT_DISCONNECTED }, - { "NT_STATUS_DEVICE_ALREADY_ATTACHED", NT_STATUS_DEVICE_ALREADY_ATTACHED }, - { "NT_STATUS_OBJECT_PATH_INVALID", NT_STATUS_OBJECT_PATH_INVALID }, - { "NT_STATUS_OBJECT_PATH_NOT_FOUND", NT_STATUS_OBJECT_PATH_NOT_FOUND }, - { "NT_STATUS_OBJECT_PATH_SYNTAX_BAD", NT_STATUS_OBJECT_PATH_SYNTAX_BAD }, - { "NT_STATUS_DATA_OVERRUN", NT_STATUS_DATA_OVERRUN }, - { "NT_STATUS_DATA_LATE_ERROR", NT_STATUS_DATA_LATE_ERROR }, - { "NT_STATUS_DATA_ERROR", NT_STATUS_DATA_ERROR }, - { "NT_STATUS_CRC_ERROR", NT_STATUS_CRC_ERROR }, - { "NT_STATUS_SECTION_TOO_BIG", NT_STATUS_SECTION_TOO_BIG }, - { "NT_STATUS_PORT_CONNECTION_REFUSED", NT_STATUS_PORT_CONNECTION_REFUSED }, - { "NT_STATUS_INVALID_PORT_HANDLE", NT_STATUS_INVALID_PORT_HANDLE }, - { "NT_STATUS_SHARING_VIOLATION", NT_STATUS_SHARING_VIOLATION }, - { "NT_STATUS_QUOTA_EXCEEDED", NT_STATUS_QUOTA_EXCEEDED }, - { "NT_STATUS_INVALID_PAGE_PROTECTION", NT_STATUS_INVALID_PAGE_PROTECTION }, - { "NT_STATUS_MUTANT_NOT_OWNED", NT_STATUS_MUTANT_NOT_OWNED }, - { "NT_STATUS_SEMAPHORE_LIMIT_EXCEEDED", NT_STATUS_SEMAPHORE_LIMIT_EXCEEDED }, - { "NT_STATUS_PORT_ALREADY_SET", NT_STATUS_PORT_ALREADY_SET }, - { "NT_STATUS_SECTION_NOT_IMAGE", NT_STATUS_SECTION_NOT_IMAGE }, - { "NT_STATUS_SUSPEND_COUNT_EXCEEDED", NT_STATUS_SUSPEND_COUNT_EXCEEDED }, - { "NT_STATUS_THREAD_IS_TERMINATING", NT_STATUS_THREAD_IS_TERMINATING }, - { "NT_STATUS_BAD_WORKING_SET_LIMIT", NT_STATUS_BAD_WORKING_SET_LIMIT }, - { "NT_STATUS_INCOMPATIBLE_FILE_MAP", NT_STATUS_INCOMPATIBLE_FILE_MAP }, - { "NT_STATUS_SECTION_PROTECTION", NT_STATUS_SECTION_PROTECTION }, - { "NT_STATUS_EAS_NOT_SUPPORTED", NT_STATUS_EAS_NOT_SUPPORTED }, - { "NT_STATUS_EA_TOO_LARGE", NT_STATUS_EA_TOO_LARGE }, - { "NT_STATUS_NONEXISTENT_EA_ENTRY", NT_STATUS_NONEXISTENT_EA_ENTRY }, - { "NT_STATUS_NO_EAS_ON_FILE", NT_STATUS_NO_EAS_ON_FILE }, - { "NT_STATUS_EA_CORRUPT_ERROR", NT_STATUS_EA_CORRUPT_ERROR }, - { "NT_STATUS_FILE_LOCK_CONFLICT", NT_STATUS_FILE_LOCK_CONFLICT }, - { "NT_STATUS_LOCK_NOT_GRANTED", NT_STATUS_LOCK_NOT_GRANTED }, - { "NT_STATUS_DELETE_PENDING", NT_STATUS_DELETE_PENDING }, - { "NT_STATUS_CTL_FILE_NOT_SUPPORTED", NT_STATUS_CTL_FILE_NOT_SUPPORTED }, - { "NT_STATUS_UNKNOWN_REVISION", NT_STATUS_UNKNOWN_REVISION }, - { "NT_STATUS_REVISION_MISMATCH", NT_STATUS_REVISION_MISMATCH }, - { "NT_STATUS_INVALID_OWNER", NT_STATUS_INVALID_OWNER }, - { "NT_STATUS_INVALID_PRIMARY_GROUP", NT_STATUS_INVALID_PRIMARY_GROUP }, - { "NT_STATUS_NO_IMPERSONATION_TOKEN", NT_STATUS_NO_IMPERSONATION_TOKEN }, - { "NT_STATUS_CANT_DISABLE_MANDATORY", NT_STATUS_CANT_DISABLE_MANDATORY }, - { "NT_STATUS_NO_LOGON_SERVERS", NT_STATUS_NO_LOGON_SERVERS }, - { "NT_STATUS_NO_SUCH_LOGON_SESSION", NT_STATUS_NO_SUCH_LOGON_SESSION }, - { "NT_STATUS_NO_SUCH_PRIVILEGE", NT_STATUS_NO_SUCH_PRIVILEGE }, - { "NT_STATUS_PRIVILEGE_NOT_HELD", NT_STATUS_PRIVILEGE_NOT_HELD }, - { "NT_STATUS_INVALID_ACCOUNT_NAME", NT_STATUS_INVALID_ACCOUNT_NAME }, - { "NT_STATUS_USER_EXISTS", NT_STATUS_USER_EXISTS }, - { "NT_STATUS_NO_SUCH_USER", NT_STATUS_NO_SUCH_USER }, - { "NT_STATUS_GROUP_EXISTS", NT_STATUS_GROUP_EXISTS }, - { "NT_STATUS_NO_SUCH_GROUP", NT_STATUS_NO_SUCH_GROUP }, - { "NT_STATUS_MEMBER_IN_GROUP", NT_STATUS_MEMBER_IN_GROUP }, - { "NT_STATUS_MEMBER_NOT_IN_GROUP", NT_STATUS_MEMBER_NOT_IN_GROUP }, - { "NT_STATUS_LAST_ADMIN", NT_STATUS_LAST_ADMIN }, - { "NT_STATUS_WRONG_PASSWORD", NT_STATUS_WRONG_PASSWORD }, - { "NT_STATUS_ILL_FORMED_PASSWORD", NT_STATUS_ILL_FORMED_PASSWORD }, - { "NT_STATUS_PASSWORD_RESTRICTION", NT_STATUS_PASSWORD_RESTRICTION }, - { "NT_STATUS_LOGON_FAILURE", NT_STATUS_LOGON_FAILURE }, - { "NT_STATUS_ACCOUNT_RESTRICTION", NT_STATUS_ACCOUNT_RESTRICTION }, - { "NT_STATUS_INVALID_LOGON_HOURS", NT_STATUS_INVALID_LOGON_HOURS }, - { "NT_STATUS_INVALID_WORKSTATION", NT_STATUS_INVALID_WORKSTATION }, - { "NT_STATUS_PASSWORD_EXPIRED", NT_STATUS_PASSWORD_EXPIRED }, - { "NT_STATUS_ACCOUNT_DISABLED", NT_STATUS_ACCOUNT_DISABLED }, - { "NT_STATUS_NONE_MAPPED", NT_STATUS_NONE_MAPPED }, - { "NT_STATUS_TOO_MANY_LUIDS_REQUESTED", NT_STATUS_TOO_MANY_LUIDS_REQUESTED }, - { "NT_STATUS_LUIDS_EXHAUSTED", NT_STATUS_LUIDS_EXHAUSTED }, - { "NT_STATUS_INVALID_SUB_AUTHORITY", NT_STATUS_INVALID_SUB_AUTHORITY }, - { "NT_STATUS_INVALID_ACL", NT_STATUS_INVALID_ACL }, - { "NT_STATUS_INVALID_SID", NT_STATUS_INVALID_SID }, - { "NT_STATUS_INVALID_SECURITY_DESCR", NT_STATUS_INVALID_SECURITY_DESCR }, - { "NT_STATUS_PROCEDURE_NOT_FOUND", NT_STATUS_PROCEDURE_NOT_FOUND }, - { "NT_STATUS_INVALID_IMAGE_FORMAT", NT_STATUS_INVALID_IMAGE_FORMAT }, - { "NT_STATUS_NO_TOKEN", NT_STATUS_NO_TOKEN }, - { "NT_STATUS_BAD_INHERITANCE_ACL", NT_STATUS_BAD_INHERITANCE_ACL }, - { "NT_STATUS_RANGE_NOT_LOCKED", NT_STATUS_RANGE_NOT_LOCKED }, - { "NT_STATUS_DISK_FULL", NT_STATUS_DISK_FULL }, - { "NT_STATUS_SERVER_DISABLED", NT_STATUS_SERVER_DISABLED }, - { "NT_STATUS_SERVER_NOT_DISABLED", NT_STATUS_SERVER_NOT_DISABLED }, - { "NT_STATUS_TOO_MANY_GUIDS_REQUESTED", NT_STATUS_TOO_MANY_GUIDS_REQUESTED }, - { "NT_STATUS_GUIDS_EXHAUSTED", NT_STATUS_GUIDS_EXHAUSTED }, - { "NT_STATUS_INVALID_ID_AUTHORITY", NT_STATUS_INVALID_ID_AUTHORITY }, - { "NT_STATUS_AGENTS_EXHAUSTED", NT_STATUS_AGENTS_EXHAUSTED }, - { "NT_STATUS_INVALID_VOLUME_LABEL", NT_STATUS_INVALID_VOLUME_LABEL }, - { "NT_STATUS_SECTION_NOT_EXTENDED", NT_STATUS_SECTION_NOT_EXTENDED }, - { "NT_STATUS_NOT_MAPPED_DATA", NT_STATUS_NOT_MAPPED_DATA }, - { "NT_STATUS_RESOURCE_DATA_NOT_FOUND", NT_STATUS_RESOURCE_DATA_NOT_FOUND }, - { "NT_STATUS_RESOURCE_TYPE_NOT_FOUND", NT_STATUS_RESOURCE_TYPE_NOT_FOUND }, - { "NT_STATUS_RESOURCE_NAME_NOT_FOUND", NT_STATUS_RESOURCE_NAME_NOT_FOUND }, - { "NT_STATUS_ARRAY_BOUNDS_EXCEEDED", NT_STATUS_ARRAY_BOUNDS_EXCEEDED }, - { "NT_STATUS_FLOAT_DENORMAL_OPERAND", NT_STATUS_FLOAT_DENORMAL_OPERAND }, - { "NT_STATUS_FLOAT_DIVIDE_BY_ZERO", NT_STATUS_FLOAT_DIVIDE_BY_ZERO }, - { "NT_STATUS_FLOAT_INEXACT_RESULT", NT_STATUS_FLOAT_INEXACT_RESULT }, - { "NT_STATUS_FLOAT_INVALID_OPERATION", NT_STATUS_FLOAT_INVALID_OPERATION }, - { "NT_STATUS_FLOAT_OVERFLOW", NT_STATUS_FLOAT_OVERFLOW }, - { "NT_STATUS_FLOAT_STACK_CHECK", NT_STATUS_FLOAT_STACK_CHECK }, - { "NT_STATUS_FLOAT_UNDERFLOW", NT_STATUS_FLOAT_UNDERFLOW }, - { "NT_STATUS_INTEGER_DIVIDE_BY_ZERO", NT_STATUS_INTEGER_DIVIDE_BY_ZERO }, - { "NT_STATUS_INTEGER_OVERFLOW", NT_STATUS_INTEGER_OVERFLOW }, - { "NT_STATUS_PRIVILEGED_INSTRUCTION", NT_STATUS_PRIVILEGED_INSTRUCTION }, - { "NT_STATUS_TOO_MANY_PAGING_FILES", NT_STATUS_TOO_MANY_PAGING_FILES }, - { "NT_STATUS_FILE_INVALID", NT_STATUS_FILE_INVALID }, - { "NT_STATUS_ALLOTTED_SPACE_EXCEEDED", NT_STATUS_ALLOTTED_SPACE_EXCEEDED }, - { "NT_STATUS_INSUFFICIENT_RESOURCES", NT_STATUS_INSUFFICIENT_RESOURCES }, - { "NT_STATUS_DFS_EXIT_PATH_FOUND", NT_STATUS_DFS_EXIT_PATH_FOUND }, - { "NT_STATUS_DEVICE_DATA_ERROR", NT_STATUS_DEVICE_DATA_ERROR }, - { "NT_STATUS_DEVICE_NOT_CONNECTED", NT_STATUS_DEVICE_NOT_CONNECTED }, - { "NT_STATUS_DEVICE_POWER_FAILURE", NT_STATUS_DEVICE_POWER_FAILURE }, - { "NT_STATUS_FREE_VM_NOT_AT_BASE", NT_STATUS_FREE_VM_NOT_AT_BASE }, - { "NT_STATUS_MEMORY_NOT_ALLOCATED", NT_STATUS_MEMORY_NOT_ALLOCATED }, - { "NT_STATUS_WORKING_SET_QUOTA", NT_STATUS_WORKING_SET_QUOTA }, - { "NT_STATUS_MEDIA_WRITE_PROTECTED", NT_STATUS_MEDIA_WRITE_PROTECTED }, - { "NT_STATUS_DEVICE_NOT_READY", NT_STATUS_DEVICE_NOT_READY }, - { "NT_STATUS_INVALID_GROUP_ATTRIBUTES", NT_STATUS_INVALID_GROUP_ATTRIBUTES }, - { "NT_STATUS_BAD_IMPERSONATION_LEVEL", NT_STATUS_BAD_IMPERSONATION_LEVEL }, - { "NT_STATUS_CANT_OPEN_ANONYMOUS", NT_STATUS_CANT_OPEN_ANONYMOUS }, - { "NT_STATUS_BAD_VALIDATION_CLASS", NT_STATUS_BAD_VALIDATION_CLASS }, - { "NT_STATUS_BAD_TOKEN_TYPE", NT_STATUS_BAD_TOKEN_TYPE }, - { "NT_STATUS_BAD_MASTER_BOOT_RECORD", NT_STATUS_BAD_MASTER_BOOT_RECORD }, - { "NT_STATUS_INSTRUCTION_MISALIGNMENT", NT_STATUS_INSTRUCTION_MISALIGNMENT }, - { "NT_STATUS_INSTANCE_NOT_AVAILABLE", NT_STATUS_INSTANCE_NOT_AVAILABLE }, - { "NT_STATUS_PIPE_NOT_AVAILABLE", NT_STATUS_PIPE_NOT_AVAILABLE }, - { "NT_STATUS_INVALID_PIPE_STATE", NT_STATUS_INVALID_PIPE_STATE }, - { "NT_STATUS_PIPE_BUSY", NT_STATUS_PIPE_BUSY }, - { "NT_STATUS_ILLEGAL_FUNCTION", NT_STATUS_ILLEGAL_FUNCTION }, - { "NT_STATUS_PIPE_DISCONNECTED", NT_STATUS_PIPE_DISCONNECTED }, - { "NT_STATUS_PIPE_CLOSING", NT_STATUS_PIPE_CLOSING }, - { "NT_STATUS_PIPE_CONNECTED", NT_STATUS_PIPE_CONNECTED }, - { "NT_STATUS_PIPE_LISTENING", NT_STATUS_PIPE_LISTENING }, - { "NT_STATUS_INVALID_READ_MODE", NT_STATUS_INVALID_READ_MODE }, - { "NT_STATUS_IO_TIMEOUT", NT_STATUS_IO_TIMEOUT }, - { "NT_STATUS_FILE_FORCED_CLOSED", NT_STATUS_FILE_FORCED_CLOSED }, - { "NT_STATUS_PROFILING_NOT_STARTED", NT_STATUS_PROFILING_NOT_STARTED }, - { "NT_STATUS_PROFILING_NOT_STOPPED", NT_STATUS_PROFILING_NOT_STOPPED }, - { "NT_STATUS_COULD_NOT_INTERPRET", NT_STATUS_COULD_NOT_INTERPRET }, - { "NT_STATUS_FILE_IS_A_DIRECTORY", NT_STATUS_FILE_IS_A_DIRECTORY }, - { "NT_STATUS_NOT_SUPPORTED", NT_STATUS_NOT_SUPPORTED }, - { "NT_STATUS_REMOTE_NOT_LISTENING", NT_STATUS_REMOTE_NOT_LISTENING }, - { "NT_STATUS_DUPLICATE_NAME", NT_STATUS_DUPLICATE_NAME }, - { "NT_STATUS_BAD_NETWORK_PATH", NT_STATUS_BAD_NETWORK_PATH }, - { "NT_STATUS_NETWORK_BUSY", NT_STATUS_NETWORK_BUSY }, - { "NT_STATUS_DEVICE_DOES_NOT_EXIST", NT_STATUS_DEVICE_DOES_NOT_EXIST }, - { "NT_STATUS_TOO_MANY_COMMANDS", NT_STATUS_TOO_MANY_COMMANDS }, - { "NT_STATUS_ADAPTER_HARDWARE_ERROR", NT_STATUS_ADAPTER_HARDWARE_ERROR }, - { "NT_STATUS_INVALID_NETWORK_RESPONSE", NT_STATUS_INVALID_NETWORK_RESPONSE }, - { "NT_STATUS_UNEXPECTED_NETWORK_ERROR", NT_STATUS_UNEXPECTED_NETWORK_ERROR }, - { "NT_STATUS_BAD_REMOTE_ADAPTER", NT_STATUS_BAD_REMOTE_ADAPTER }, - { "NT_STATUS_PRINT_QUEUE_FULL", NT_STATUS_PRINT_QUEUE_FULL }, - { "NT_STATUS_NO_SPOOL_SPACE", NT_STATUS_NO_SPOOL_SPACE }, - { "NT_STATUS_PRINT_CANCELLED", NT_STATUS_PRINT_CANCELLED }, - { "NT_STATUS_NETWORK_NAME_DELETED", NT_STATUS_NETWORK_NAME_DELETED }, - { "NT_STATUS_NETWORK_ACCESS_DENIED", NT_STATUS_NETWORK_ACCESS_DENIED }, - { "NT_STATUS_BAD_DEVICE_TYPE", NT_STATUS_BAD_DEVICE_TYPE }, - { "NT_STATUS_BAD_NETWORK_NAME", NT_STATUS_BAD_NETWORK_NAME }, - { "NT_STATUS_TOO_MANY_NAMES", NT_STATUS_TOO_MANY_NAMES }, - { "NT_STATUS_TOO_MANY_SESSIONS", NT_STATUS_TOO_MANY_SESSIONS }, - { "NT_STATUS_SHARING_PAUSED", NT_STATUS_SHARING_PAUSED }, - { "NT_STATUS_REQUEST_NOT_ACCEPTED", NT_STATUS_REQUEST_NOT_ACCEPTED }, - { "NT_STATUS_REDIRECTOR_PAUSED", NT_STATUS_REDIRECTOR_PAUSED }, - { "NT_STATUS_NET_WRITE_FAULT", NT_STATUS_NET_WRITE_FAULT }, - { "NT_STATUS_PROFILING_AT_LIMIT", NT_STATUS_PROFILING_AT_LIMIT }, - { "NT_STATUS_NOT_SAME_DEVICE", NT_STATUS_NOT_SAME_DEVICE }, - { "NT_STATUS_FILE_RENAMED", NT_STATUS_FILE_RENAMED }, - { "NT_STATUS_VIRTUAL_CIRCUIT_CLOSED", NT_STATUS_VIRTUAL_CIRCUIT_CLOSED }, - { "NT_STATUS_NO_SECURITY_ON_OBJECT", NT_STATUS_NO_SECURITY_ON_OBJECT }, - { "NT_STATUS_CANT_WAIT", NT_STATUS_CANT_WAIT }, - { "NT_STATUS_PIPE_EMPTY", NT_STATUS_PIPE_EMPTY }, - { "NT_STATUS_CANT_ACCESS_DOMAIN_INFO", NT_STATUS_CANT_ACCESS_DOMAIN_INFO }, - { "NT_STATUS_CANT_TERMINATE_SELF", NT_STATUS_CANT_TERMINATE_SELF }, - { "NT_STATUS_INVALID_SERVER_STATE", NT_STATUS_INVALID_SERVER_STATE }, - { "NT_STATUS_INVALID_DOMAIN_STATE", NT_STATUS_INVALID_DOMAIN_STATE }, - { "NT_STATUS_INVALID_DOMAIN_ROLE", NT_STATUS_INVALID_DOMAIN_ROLE }, - { "NT_STATUS_NO_SUCH_DOMAIN", NT_STATUS_NO_SUCH_DOMAIN }, - { "NT_STATUS_DOMAIN_EXISTS", NT_STATUS_DOMAIN_EXISTS }, - { "NT_STATUS_DOMAIN_LIMIT_EXCEEDED", NT_STATUS_DOMAIN_LIMIT_EXCEEDED }, - { "NT_STATUS_OPLOCK_NOT_GRANTED", NT_STATUS_OPLOCK_NOT_GRANTED }, - { "NT_STATUS_INVALID_OPLOCK_PROTOCOL", NT_STATUS_INVALID_OPLOCK_PROTOCOL }, - { "NT_STATUS_INTERNAL_DB_CORRUPTION", NT_STATUS_INTERNAL_DB_CORRUPTION }, - { "NT_STATUS_INTERNAL_ERROR", NT_STATUS_INTERNAL_ERROR }, - { "NT_STATUS_GENERIC_NOT_MAPPED", NT_STATUS_GENERIC_NOT_MAPPED }, - { "NT_STATUS_BAD_DESCRIPTOR_FORMAT", NT_STATUS_BAD_DESCRIPTOR_FORMAT }, - { "NT_STATUS_INVALID_USER_BUFFER", NT_STATUS_INVALID_USER_BUFFER }, - { "NT_STATUS_UNEXPECTED_IO_ERROR", NT_STATUS_UNEXPECTED_IO_ERROR }, - { "NT_STATUS_UNEXPECTED_MM_CREATE_ERR", NT_STATUS_UNEXPECTED_MM_CREATE_ERR }, - { "NT_STATUS_UNEXPECTED_MM_MAP_ERROR", NT_STATUS_UNEXPECTED_MM_MAP_ERROR }, - { "NT_STATUS_UNEXPECTED_MM_EXTEND_ERR", NT_STATUS_UNEXPECTED_MM_EXTEND_ERR }, - { "NT_STATUS_NOT_LOGON_PROCESS", NT_STATUS_NOT_LOGON_PROCESS }, - { "NT_STATUS_LOGON_SESSION_EXISTS", NT_STATUS_LOGON_SESSION_EXISTS }, - { "NT_STATUS_INVALID_PARAMETER_1", NT_STATUS_INVALID_PARAMETER_1 }, - { "NT_STATUS_INVALID_PARAMETER_2", NT_STATUS_INVALID_PARAMETER_2 }, - { "NT_STATUS_INVALID_PARAMETER_3", NT_STATUS_INVALID_PARAMETER_3 }, - { "NT_STATUS_INVALID_PARAMETER_4", NT_STATUS_INVALID_PARAMETER_4 }, - { "NT_STATUS_INVALID_PARAMETER_5", NT_STATUS_INVALID_PARAMETER_5 }, - { "NT_STATUS_INVALID_PARAMETER_6", NT_STATUS_INVALID_PARAMETER_6 }, - { "NT_STATUS_INVALID_PARAMETER_7", NT_STATUS_INVALID_PARAMETER_7 }, - { "NT_STATUS_INVALID_PARAMETER_8", NT_STATUS_INVALID_PARAMETER_8 }, - { "NT_STATUS_INVALID_PARAMETER_9", NT_STATUS_INVALID_PARAMETER_9 }, - { "NT_STATUS_INVALID_PARAMETER_10", NT_STATUS_INVALID_PARAMETER_10 }, - { "NT_STATUS_INVALID_PARAMETER_11", NT_STATUS_INVALID_PARAMETER_11 }, - { "NT_STATUS_INVALID_PARAMETER_12", NT_STATUS_INVALID_PARAMETER_12 }, - { "NT_STATUS_REDIRECTOR_NOT_STARTED", NT_STATUS_REDIRECTOR_NOT_STARTED }, - { "NT_STATUS_REDIRECTOR_STARTED", NT_STATUS_REDIRECTOR_STARTED }, - { "NT_STATUS_STACK_OVERFLOW", NT_STATUS_STACK_OVERFLOW }, - { "NT_STATUS_NO_SUCH_PACKAGE", NT_STATUS_NO_SUCH_PACKAGE }, - { "NT_STATUS_BAD_FUNCTION_TABLE", NT_STATUS_BAD_FUNCTION_TABLE }, - { "NT_STATUS_DIRECTORY_NOT_EMPTY", NT_STATUS_DIRECTORY_NOT_EMPTY }, - { "NT_STATUS_FILE_CORRUPT_ERROR", NT_STATUS_FILE_CORRUPT_ERROR }, - { "NT_STATUS_NOT_A_DIRECTORY", NT_STATUS_NOT_A_DIRECTORY }, - { "NT_STATUS_BAD_LOGON_SESSION_STATE", NT_STATUS_BAD_LOGON_SESSION_STATE }, - { "NT_STATUS_LOGON_SESSION_COLLISION", NT_STATUS_LOGON_SESSION_COLLISION }, - { "NT_STATUS_NAME_TOO_LONG", NT_STATUS_NAME_TOO_LONG }, - { "NT_STATUS_FILES_OPEN", NT_STATUS_FILES_OPEN }, - { "NT_STATUS_CONNECTION_IN_USE", NT_STATUS_CONNECTION_IN_USE }, - { "NT_STATUS_MESSAGE_NOT_FOUND", NT_STATUS_MESSAGE_NOT_FOUND }, - { "NT_STATUS_PROCESS_IS_TERMINATING", NT_STATUS_PROCESS_IS_TERMINATING }, - { "NT_STATUS_INVALID_LOGON_TYPE", NT_STATUS_INVALID_LOGON_TYPE }, - { "NT_STATUS_NO_GUID_TRANSLATION", NT_STATUS_NO_GUID_TRANSLATION }, - { "NT_STATUS_CANNOT_IMPERSONATE", NT_STATUS_CANNOT_IMPERSONATE }, - { "NT_STATUS_IMAGE_ALREADY_LOADED", NT_STATUS_IMAGE_ALREADY_LOADED }, - { "NT_STATUS_ABIOS_NOT_PRESENT", NT_STATUS_ABIOS_NOT_PRESENT }, - { "NT_STATUS_ABIOS_LID_NOT_EXIST", NT_STATUS_ABIOS_LID_NOT_EXIST }, - { "NT_STATUS_ABIOS_LID_ALREADY_OWNED", NT_STATUS_ABIOS_LID_ALREADY_OWNED }, - { "NT_STATUS_ABIOS_NOT_LID_OWNER", NT_STATUS_ABIOS_NOT_LID_OWNER }, - { "NT_STATUS_ABIOS_INVALID_COMMAND", NT_STATUS_ABIOS_INVALID_COMMAND }, - { "NT_STATUS_ABIOS_INVALID_LID", NT_STATUS_ABIOS_INVALID_LID }, - { "NT_STATUS_ABIOS_SELECTOR_NOT_AVAILABLE", NT_STATUS_ABIOS_SELECTOR_NOT_AVAILABLE }, - { "NT_STATUS_ABIOS_INVALID_SELECTOR", NT_STATUS_ABIOS_INVALID_SELECTOR }, - { "NT_STATUS_NO_LDT", NT_STATUS_NO_LDT }, - { "NT_STATUS_INVALID_LDT_SIZE", NT_STATUS_INVALID_LDT_SIZE }, - { "NT_STATUS_INVALID_LDT_OFFSET", NT_STATUS_INVALID_LDT_OFFSET }, - { "NT_STATUS_INVALID_LDT_DESCRIPTOR", NT_STATUS_INVALID_LDT_DESCRIPTOR }, - { "NT_STATUS_INVALID_IMAGE_NE_FORMAT", NT_STATUS_INVALID_IMAGE_NE_FORMAT }, - { "NT_STATUS_RXACT_INVALID_STATE", NT_STATUS_RXACT_INVALID_STATE }, - { "NT_STATUS_RXACT_COMMIT_FAILURE", NT_STATUS_RXACT_COMMIT_FAILURE }, - { "NT_STATUS_MAPPED_FILE_SIZE_ZERO", NT_STATUS_MAPPED_FILE_SIZE_ZERO }, - { "NT_STATUS_TOO_MANY_OPENED_FILES", NT_STATUS_TOO_MANY_OPENED_FILES }, - { "NT_STATUS_CANCELLED", NT_STATUS_CANCELLED }, - { "NT_STATUS_CANNOT_DELETE", NT_STATUS_CANNOT_DELETE }, - { "NT_STATUS_INVALID_COMPUTER_NAME", NT_STATUS_INVALID_COMPUTER_NAME }, - { "NT_STATUS_FILE_DELETED", NT_STATUS_FILE_DELETED }, - { "NT_STATUS_SPECIAL_ACCOUNT", NT_STATUS_SPECIAL_ACCOUNT }, - { "NT_STATUS_SPECIAL_GROUP", NT_STATUS_SPECIAL_GROUP }, - { "NT_STATUS_SPECIAL_USER", NT_STATUS_SPECIAL_USER }, - { "NT_STATUS_MEMBERS_PRIMARY_GROUP", NT_STATUS_MEMBERS_PRIMARY_GROUP }, - { "NT_STATUS_FILE_CLOSED", NT_STATUS_FILE_CLOSED }, - { "NT_STATUS_TOO_MANY_THREADS", NT_STATUS_TOO_MANY_THREADS }, - { "NT_STATUS_THREAD_NOT_IN_PROCESS", NT_STATUS_THREAD_NOT_IN_PROCESS }, - { "NT_STATUS_TOKEN_ALREADY_IN_USE", NT_STATUS_TOKEN_ALREADY_IN_USE }, - { "NT_STATUS_PAGEFILE_QUOTA_EXCEEDED", NT_STATUS_PAGEFILE_QUOTA_EXCEEDED }, - { "NT_STATUS_COMMITMENT_LIMIT", NT_STATUS_COMMITMENT_LIMIT }, - { "NT_STATUS_INVALID_IMAGE_LE_FORMAT", NT_STATUS_INVALID_IMAGE_LE_FORMAT }, - { "NT_STATUS_INVALID_IMAGE_NOT_MZ", NT_STATUS_INVALID_IMAGE_NOT_MZ }, - { "NT_STATUS_INVALID_IMAGE_PROTECT", NT_STATUS_INVALID_IMAGE_PROTECT }, - { "NT_STATUS_INVALID_IMAGE_WIN_16", NT_STATUS_INVALID_IMAGE_WIN_16 }, - { "NT_STATUS_LOGON_SERVER_CONFLICT", NT_STATUS_LOGON_SERVER_CONFLICT }, - { "NT_STATUS_TIME_DIFFERENCE_AT_DC", NT_STATUS_TIME_DIFFERENCE_AT_DC }, - { "NT_STATUS_SYNCHRONIZATION_REQUIRED", NT_STATUS_SYNCHRONIZATION_REQUIRED }, - { "NT_STATUS_DLL_NOT_FOUND", NT_STATUS_DLL_NOT_FOUND }, - { "NT_STATUS_OPEN_FAILED", NT_STATUS_OPEN_FAILED }, - { "NT_STATUS_IO_PRIVILEGE_FAILED", NT_STATUS_IO_PRIVILEGE_FAILED }, - { "NT_STATUS_ORDINAL_NOT_FOUND", NT_STATUS_ORDINAL_NOT_FOUND }, - { "NT_STATUS_ENTRYPOINT_NOT_FOUND", NT_STATUS_ENTRYPOINT_NOT_FOUND }, - { "NT_STATUS_CONTROL_C_EXIT", NT_STATUS_CONTROL_C_EXIT }, - { "NT_STATUS_LOCAL_DISCONNECT", NT_STATUS_LOCAL_DISCONNECT }, - { "NT_STATUS_REMOTE_DISCONNECT", NT_STATUS_REMOTE_DISCONNECT }, - { "NT_STATUS_REMOTE_RESOURCES", NT_STATUS_REMOTE_RESOURCES }, - { "NT_STATUS_LINK_FAILED", NT_STATUS_LINK_FAILED }, - { "NT_STATUS_LINK_TIMEOUT", NT_STATUS_LINK_TIMEOUT }, - { "NT_STATUS_INVALID_CONNECTION", NT_STATUS_INVALID_CONNECTION }, - { "NT_STATUS_INVALID_ADDRESS", NT_STATUS_INVALID_ADDRESS }, - { "NT_STATUS_DLL_INIT_FAILED", NT_STATUS_DLL_INIT_FAILED }, - { "NT_STATUS_MISSING_SYSTEMFILE", NT_STATUS_MISSING_SYSTEMFILE }, - { "NT_STATUS_UNHANDLED_EXCEPTION", NT_STATUS_UNHANDLED_EXCEPTION }, - { "NT_STATUS_APP_INIT_FAILURE", NT_STATUS_APP_INIT_FAILURE }, - { "NT_STATUS_PAGEFILE_CREATE_FAILED", NT_STATUS_PAGEFILE_CREATE_FAILED }, - { "NT_STATUS_NO_PAGEFILE", NT_STATUS_NO_PAGEFILE }, - { "NT_STATUS_INVALID_LEVEL", NT_STATUS_INVALID_LEVEL }, - { "NT_STATUS_WRONG_PASSWORD_CORE", NT_STATUS_WRONG_PASSWORD_CORE }, - { "NT_STATUS_ILLEGAL_FLOAT_CONTEXT", NT_STATUS_ILLEGAL_FLOAT_CONTEXT }, - { "NT_STATUS_PIPE_BROKEN", NT_STATUS_PIPE_BROKEN }, - { "NT_STATUS_REGISTRY_CORRUPT", NT_STATUS_REGISTRY_CORRUPT }, - { "NT_STATUS_REGISTRY_IO_FAILED", NT_STATUS_REGISTRY_IO_FAILED }, - { "NT_STATUS_NO_EVENT_PAIR", NT_STATUS_NO_EVENT_PAIR }, - { "NT_STATUS_UNRECOGNIZED_VOLUME", NT_STATUS_UNRECOGNIZED_VOLUME }, - { "NT_STATUS_SERIAL_NO_DEVICE_INITED", NT_STATUS_SERIAL_NO_DEVICE_INITED }, - { "NT_STATUS_NO_SUCH_ALIAS", NT_STATUS_NO_SUCH_ALIAS }, - { "NT_STATUS_MEMBER_NOT_IN_ALIAS", NT_STATUS_MEMBER_NOT_IN_ALIAS }, - { "NT_STATUS_MEMBER_IN_ALIAS", NT_STATUS_MEMBER_IN_ALIAS }, - { "NT_STATUS_ALIAS_EXISTS", NT_STATUS_ALIAS_EXISTS }, - { "NT_STATUS_LOGON_NOT_GRANTED", NT_STATUS_LOGON_NOT_GRANTED }, - { "NT_STATUS_TOO_MANY_SECRETS", NT_STATUS_TOO_MANY_SECRETS }, - { "NT_STATUS_SECRET_TOO_LONG", NT_STATUS_SECRET_TOO_LONG }, - { "NT_STATUS_INTERNAL_DB_ERROR", NT_STATUS_INTERNAL_DB_ERROR }, - { "NT_STATUS_FULLSCREEN_MODE", NT_STATUS_FULLSCREEN_MODE }, - { "NT_STATUS_TOO_MANY_CONTEXT_IDS", NT_STATUS_TOO_MANY_CONTEXT_IDS }, - { "NT_STATUS_LOGON_TYPE_NOT_GRANTED", NT_STATUS_LOGON_TYPE_NOT_GRANTED }, - { "NT_STATUS_NOT_REGISTRY_FILE", NT_STATUS_NOT_REGISTRY_FILE }, - { "NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED", NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED }, - { "NT_STATUS_DOMAIN_CTRLR_CONFIG_ERROR", NT_STATUS_DOMAIN_CTRLR_CONFIG_ERROR }, - { "NT_STATUS_FT_MISSING_MEMBER", NT_STATUS_FT_MISSING_MEMBER }, - { "NT_STATUS_ILL_FORMED_SERVICE_ENTRY", NT_STATUS_ILL_FORMED_SERVICE_ENTRY }, - { "NT_STATUS_ILLEGAL_CHARACTER", NT_STATUS_ILLEGAL_CHARACTER }, - { "NT_STATUS_UNMAPPABLE_CHARACTER", NT_STATUS_UNMAPPABLE_CHARACTER }, - { "NT_STATUS_UNDEFINED_CHARACTER", NT_STATUS_UNDEFINED_CHARACTER }, - { "NT_STATUS_FLOPPY_VOLUME", NT_STATUS_FLOPPY_VOLUME }, - { "NT_STATUS_FLOPPY_ID_MARK_NOT_FOUND", NT_STATUS_FLOPPY_ID_MARK_NOT_FOUND }, - { "NT_STATUS_FLOPPY_WRONG_CYLINDER", NT_STATUS_FLOPPY_WRONG_CYLINDER }, - { "NT_STATUS_FLOPPY_UNKNOWN_ERROR", NT_STATUS_FLOPPY_UNKNOWN_ERROR }, - { "NT_STATUS_FLOPPY_BAD_REGISTERS", NT_STATUS_FLOPPY_BAD_REGISTERS }, - { "NT_STATUS_DISK_RECALIBRATE_FAILED", NT_STATUS_DISK_RECALIBRATE_FAILED }, - { "NT_STATUS_DISK_OPERATION_FAILED", NT_STATUS_DISK_OPERATION_FAILED }, - { "NT_STATUS_DISK_RESET_FAILED", NT_STATUS_DISK_RESET_FAILED }, - { "NT_STATUS_SHARED_IRQ_BUSY", NT_STATUS_SHARED_IRQ_BUSY }, - { "NT_STATUS_FT_ORPHANING", NT_STATUS_FT_ORPHANING }, - { "NT_STATUS_PARTITION_FAILURE", NT_STATUS_PARTITION_FAILURE }, - { "NT_STATUS_INVALID_BLOCK_LENGTH", NT_STATUS_INVALID_BLOCK_LENGTH }, - { "NT_STATUS_DEVICE_NOT_PARTITIONED", NT_STATUS_DEVICE_NOT_PARTITIONED }, - { "NT_STATUS_UNABLE_TO_LOCK_MEDIA", NT_STATUS_UNABLE_TO_LOCK_MEDIA }, - { "NT_STATUS_UNABLE_TO_UNLOAD_MEDIA", NT_STATUS_UNABLE_TO_UNLOAD_MEDIA }, - { "NT_STATUS_EOM_OVERFLOW", NT_STATUS_EOM_OVERFLOW }, - { "NT_STATUS_NO_MEDIA", NT_STATUS_NO_MEDIA }, - { "NT_STATUS_NO_SUCH_MEMBER", NT_STATUS_NO_SUCH_MEMBER }, - { "NT_STATUS_INVALID_MEMBER", NT_STATUS_INVALID_MEMBER }, - { "NT_STATUS_KEY_DELETED", NT_STATUS_KEY_DELETED }, - { "NT_STATUS_NO_LOG_SPACE", NT_STATUS_NO_LOG_SPACE }, - { "NT_STATUS_TOO_MANY_SIDS", NT_STATUS_TOO_MANY_SIDS }, - { "NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED", NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED }, - { "NT_STATUS_KEY_HAS_CHILDREN", NT_STATUS_KEY_HAS_CHILDREN }, - { "NT_STATUS_CHILD_MUST_BE_VOLATILE", NT_STATUS_CHILD_MUST_BE_VOLATILE }, - { "NT_STATUS_DEVICE_CONFIGURATION_ERROR", NT_STATUS_DEVICE_CONFIGURATION_ERROR }, - { "NT_STATUS_DRIVER_INTERNAL_ERROR", NT_STATUS_DRIVER_INTERNAL_ERROR }, - { "NT_STATUS_INVALID_DEVICE_STATE", NT_STATUS_INVALID_DEVICE_STATE }, - { "NT_STATUS_IO_DEVICE_ERROR", NT_STATUS_IO_DEVICE_ERROR }, - { "NT_STATUS_DEVICE_PROTOCOL_ERROR", NT_STATUS_DEVICE_PROTOCOL_ERROR }, - { "NT_STATUS_BACKUP_CONTROLLER", NT_STATUS_BACKUP_CONTROLLER }, - { "NT_STATUS_LOG_FILE_FULL", NT_STATUS_LOG_FILE_FULL }, - { "NT_STATUS_TOO_LATE", NT_STATUS_TOO_LATE }, - { "NT_STATUS_NO_TRUST_LSA_SECRET", NT_STATUS_NO_TRUST_LSA_SECRET }, - { "NT_STATUS_NO_TRUST_SAM_ACCOUNT", NT_STATUS_NO_TRUST_SAM_ACCOUNT }, - { "NT_STATUS_TRUSTED_DOMAIN_FAILURE", NT_STATUS_TRUSTED_DOMAIN_FAILURE }, - { "NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE", NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE }, - { "NT_STATUS_EVENTLOG_FILE_CORRUPT", NT_STATUS_EVENTLOG_FILE_CORRUPT }, - { "NT_STATUS_EVENTLOG_CANT_START", NT_STATUS_EVENTLOG_CANT_START }, - { "NT_STATUS_TRUST_FAILURE", NT_STATUS_TRUST_FAILURE }, - { "NT_STATUS_MUTANT_LIMIT_EXCEEDED", NT_STATUS_MUTANT_LIMIT_EXCEEDED }, - { "NT_STATUS_NETLOGON_NOT_STARTED", NT_STATUS_NETLOGON_NOT_STARTED }, - { "NT_STATUS_ACCOUNT_EXPIRED", NT_STATUS_ACCOUNT_EXPIRED }, - { "NT_STATUS_POSSIBLE_DEADLOCK", NT_STATUS_POSSIBLE_DEADLOCK }, - { "NT_STATUS_NETWORK_CREDENTIAL_CONFLICT", NT_STATUS_NETWORK_CREDENTIAL_CONFLICT }, - { "NT_STATUS_REMOTE_SESSION_LIMIT", NT_STATUS_REMOTE_SESSION_LIMIT }, - { "NT_STATUS_EVENTLOG_FILE_CHANGED", NT_STATUS_EVENTLOG_FILE_CHANGED }, - { "NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT", NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT }, - { "NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT", NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT }, - { "NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT", NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT }, - { "NT_STATUS_DOMAIN_TRUST_INCONSISTENT", NT_STATUS_DOMAIN_TRUST_INCONSISTENT }, - { "NT_STATUS_FS_DRIVER_REQUIRED", NT_STATUS_FS_DRIVER_REQUIRED }, - { "NT_STATUS_NO_USER_SESSION_KEY", NT_STATUS_NO_USER_SESSION_KEY }, - { "NT_STATUS_USER_SESSION_DELETED", NT_STATUS_USER_SESSION_DELETED }, - { "NT_STATUS_RESOURCE_LANG_NOT_FOUND", NT_STATUS_RESOURCE_LANG_NOT_FOUND }, - { "NT_STATUS_INSUFF_SERVER_RESOURCES", NT_STATUS_INSUFF_SERVER_RESOURCES }, - { "NT_STATUS_INVALID_BUFFER_SIZE", NT_STATUS_INVALID_BUFFER_SIZE }, - { "NT_STATUS_INVALID_ADDRESS_COMPONENT", NT_STATUS_INVALID_ADDRESS_COMPONENT }, - { "NT_STATUS_INVALID_ADDRESS_WILDCARD", NT_STATUS_INVALID_ADDRESS_WILDCARD }, - { "NT_STATUS_TOO_MANY_ADDRESSES", NT_STATUS_TOO_MANY_ADDRESSES }, - { "NT_STATUS_ADDRESS_ALREADY_EXISTS", NT_STATUS_ADDRESS_ALREADY_EXISTS }, - { "NT_STATUS_ADDRESS_CLOSED", NT_STATUS_ADDRESS_CLOSED }, - { "NT_STATUS_CONNECTION_DISCONNECTED", NT_STATUS_CONNECTION_DISCONNECTED }, - { "NT_STATUS_CONNECTION_RESET", NT_STATUS_CONNECTION_RESET }, - { "NT_STATUS_TOO_MANY_NODES", NT_STATUS_TOO_MANY_NODES }, - { "NT_STATUS_TRANSACTION_ABORTED", NT_STATUS_TRANSACTION_ABORTED }, - { "NT_STATUS_TRANSACTION_TIMED_OUT", NT_STATUS_TRANSACTION_TIMED_OUT }, - { "NT_STATUS_TRANSACTION_NO_RELEASE", NT_STATUS_TRANSACTION_NO_RELEASE }, - { "NT_STATUS_TRANSACTION_NO_MATCH", NT_STATUS_TRANSACTION_NO_MATCH }, - { "NT_STATUS_TRANSACTION_RESPONDED", NT_STATUS_TRANSACTION_RESPONDED }, - { "NT_STATUS_TRANSACTION_INVALID_ID", NT_STATUS_TRANSACTION_INVALID_ID }, - { "NT_STATUS_TRANSACTION_INVALID_TYPE", NT_STATUS_TRANSACTION_INVALID_TYPE }, - { "NT_STATUS_NOT_SERVER_SESSION", NT_STATUS_NOT_SERVER_SESSION }, - { "NT_STATUS_NOT_CLIENT_SESSION", NT_STATUS_NOT_CLIENT_SESSION }, - { "NT_STATUS_CANNOT_LOAD_REGISTRY_FILE", NT_STATUS_CANNOT_LOAD_REGISTRY_FILE }, - { "NT_STATUS_DEBUG_ATTACH_FAILED", NT_STATUS_DEBUG_ATTACH_FAILED }, - { "NT_STATUS_SYSTEM_PROCESS_TERMINATED", NT_STATUS_SYSTEM_PROCESS_TERMINATED }, - { "NT_STATUS_DATA_NOT_ACCEPTED", NT_STATUS_DATA_NOT_ACCEPTED }, - { "NT_STATUS_NO_BROWSER_SERVERS_FOUND", NT_STATUS_NO_BROWSER_SERVERS_FOUND }, - { "NT_STATUS_VDM_HARD_ERROR", NT_STATUS_VDM_HARD_ERROR }, - { "NT_STATUS_DRIVER_CANCEL_TIMEOUT", NT_STATUS_DRIVER_CANCEL_TIMEOUT }, - { "NT_STATUS_REPLY_MESSAGE_MISMATCH", NT_STATUS_REPLY_MESSAGE_MISMATCH }, - { "NT_STATUS_MAPPED_ALIGNMENT", NT_STATUS_MAPPED_ALIGNMENT }, - { "NT_STATUS_IMAGE_CHECKSUM_MISMATCH", NT_STATUS_IMAGE_CHECKSUM_MISMATCH }, - { "NT_STATUS_LOST_WRITEBEHIND_DATA", NT_STATUS_LOST_WRITEBEHIND_DATA }, - { "NT_STATUS_CLIENT_SERVER_PARAMETERS_INVALID", NT_STATUS_CLIENT_SERVER_PARAMETERS_INVALID }, - { "NT_STATUS_PASSWORD_MUST_CHANGE", NT_STATUS_PASSWORD_MUST_CHANGE }, - { "NT_STATUS_NOT_FOUND", NT_STATUS_NOT_FOUND }, - { "NT_STATUS_NOT_TINY_STREAM", NT_STATUS_NOT_TINY_STREAM }, - { "NT_STATUS_RECOVERY_FAILURE", NT_STATUS_RECOVERY_FAILURE }, - { "NT_STATUS_STACK_OVERFLOW_READ", NT_STATUS_STACK_OVERFLOW_READ }, - { "NT_STATUS_FAIL_CHECK", NT_STATUS_FAIL_CHECK }, - { "NT_STATUS_DUPLICATE_OBJECTID", NT_STATUS_DUPLICATE_OBJECTID }, - { "NT_STATUS_OBJECTID_EXISTS", NT_STATUS_OBJECTID_EXISTS }, - { "NT_STATUS_CONVERT_TO_LARGE", NT_STATUS_CONVERT_TO_LARGE }, - { "NT_STATUS_RETRY", NT_STATUS_RETRY }, - { "NT_STATUS_FOUND_OUT_OF_SCOPE", NT_STATUS_FOUND_OUT_OF_SCOPE }, - { "NT_STATUS_ALLOCATE_BUCKET", NT_STATUS_ALLOCATE_BUCKET }, - { "NT_STATUS_PROPSET_NOT_FOUND", NT_STATUS_PROPSET_NOT_FOUND }, - { "NT_STATUS_MARSHALL_OVERFLOW", NT_STATUS_MARSHALL_OVERFLOW }, - { "NT_STATUS_INVALID_VARIANT", NT_STATUS_INVALID_VARIANT }, - { "NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND", NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND }, - { "NT_STATUS_ACCOUNT_LOCKED_OUT", NT_STATUS_ACCOUNT_LOCKED_OUT }, - { "NT_STATUS_HANDLE_NOT_CLOSABLE", NT_STATUS_HANDLE_NOT_CLOSABLE }, - { "NT_STATUS_CONNECTION_REFUSED", NT_STATUS_CONNECTION_REFUSED }, - { "NT_STATUS_GRACEFUL_DISCONNECT", NT_STATUS_GRACEFUL_DISCONNECT }, - { "NT_STATUS_ADDRESS_ALREADY_ASSOCIATED", NT_STATUS_ADDRESS_ALREADY_ASSOCIATED }, - { "NT_STATUS_ADDRESS_NOT_ASSOCIATED", NT_STATUS_ADDRESS_NOT_ASSOCIATED }, - { "NT_STATUS_CONNECTION_INVALID", NT_STATUS_CONNECTION_INVALID }, - { "NT_STATUS_CONNECTION_ACTIVE", NT_STATUS_CONNECTION_ACTIVE }, - { "NT_STATUS_NETWORK_UNREACHABLE", NT_STATUS_NETWORK_UNREACHABLE }, - { "NT_STATUS_HOST_UNREACHABLE", NT_STATUS_HOST_UNREACHABLE }, - { "NT_STATUS_PROTOCOL_UNREACHABLE", NT_STATUS_PROTOCOL_UNREACHABLE }, - { "NT_STATUS_PORT_UNREACHABLE", NT_STATUS_PORT_UNREACHABLE }, - { "NT_STATUS_REQUEST_ABORTED", NT_STATUS_REQUEST_ABORTED }, - { "NT_STATUS_CONNECTION_ABORTED", NT_STATUS_CONNECTION_ABORTED }, - { "NT_STATUS_BAD_COMPRESSION_BUFFER", NT_STATUS_BAD_COMPRESSION_BUFFER }, - { "NT_STATUS_USER_MAPPED_FILE", NT_STATUS_USER_MAPPED_FILE }, - { "NT_STATUS_AUDIT_FAILED", NT_STATUS_AUDIT_FAILED }, - { "NT_STATUS_TIMER_RESOLUTION_NOT_SET", NT_STATUS_TIMER_RESOLUTION_NOT_SET }, - { "NT_STATUS_CONNECTION_COUNT_LIMIT", NT_STATUS_CONNECTION_COUNT_LIMIT }, - { "NT_STATUS_LOGIN_TIME_RESTRICTION", NT_STATUS_LOGIN_TIME_RESTRICTION }, - { "NT_STATUS_LOGIN_WKSTA_RESTRICTION", NT_STATUS_LOGIN_WKSTA_RESTRICTION }, - { "NT_STATUS_IMAGE_MP_UP_MISMATCH", NT_STATUS_IMAGE_MP_UP_MISMATCH }, - { "NT_STATUS_INSUFFICIENT_LOGON_INFO", NT_STATUS_INSUFFICIENT_LOGON_INFO }, - { "NT_STATUS_BAD_DLL_ENTRYPOINT", NT_STATUS_BAD_DLL_ENTRYPOINT }, - { "NT_STATUS_BAD_SERVICE_ENTRYPOINT", NT_STATUS_BAD_SERVICE_ENTRYPOINT }, - { "NT_STATUS_LPC_REPLY_LOST", NT_STATUS_LPC_REPLY_LOST }, - { "NT_STATUS_IP_ADDRESS_CONFLICT1", NT_STATUS_IP_ADDRESS_CONFLICT1 }, - { "NT_STATUS_IP_ADDRESS_CONFLICT2", NT_STATUS_IP_ADDRESS_CONFLICT2 }, - { "NT_STATUS_REGISTRY_QUOTA_LIMIT", NT_STATUS_REGISTRY_QUOTA_LIMIT }, - { "NT_STATUS_PATH_NOT_COVERED", NT_STATUS_PATH_NOT_COVERED }, - { "NT_STATUS_NO_CALLBACK_ACTIVE", NT_STATUS_NO_CALLBACK_ACTIVE }, - { "NT_STATUS_LICENSE_QUOTA_EXCEEDED", NT_STATUS_LICENSE_QUOTA_EXCEEDED }, - { "NT_STATUS_PWD_TOO_SHORT", NT_STATUS_PWD_TOO_SHORT }, - { "NT_STATUS_PWD_TOO_RECENT", NT_STATUS_PWD_TOO_RECENT }, - { "NT_STATUS_PWD_HISTORY_CONFLICT", NT_STATUS_PWD_HISTORY_CONFLICT }, - { "NT_STATUS_PLUGPLAY_NO_DEVICE", NT_STATUS_PLUGPLAY_NO_DEVICE }, - { "NT_STATUS_UNSUPPORTED_COMPRESSION", NT_STATUS_UNSUPPORTED_COMPRESSION }, - { "NT_STATUS_INVALID_HW_PROFILE", NT_STATUS_INVALID_HW_PROFILE }, - { "NT_STATUS_INVALID_PLUGPLAY_DEVICE_PATH", NT_STATUS_INVALID_PLUGPLAY_DEVICE_PATH }, - { "NT_STATUS_DRIVER_ORDINAL_NOT_FOUND", NT_STATUS_DRIVER_ORDINAL_NOT_FOUND }, - { "NT_STATUS_DRIVER_ENTRYPOINT_NOT_FOUND", NT_STATUS_DRIVER_ENTRYPOINT_NOT_FOUND }, - { "NT_STATUS_RESOURCE_NOT_OWNED", NT_STATUS_RESOURCE_NOT_OWNED }, - { "NT_STATUS_TOO_MANY_LINKS", NT_STATUS_TOO_MANY_LINKS }, - { "NT_STATUS_QUOTA_LIST_INCONSISTENT", NT_STATUS_QUOTA_LIST_INCONSISTENT }, - { "NT_STATUS_FILE_IS_OFFLINE", NT_STATUS_FILE_IS_OFFLINE }, - { NULL, 0 } -}; - -/***************************************************************************** - returns an NT error message. not amazingly helpful, but better than a number. - *****************************************************************************/ -const char *get_nt_error_msg(uint32 nt_code) -{ - int idx = 0; - - nt_code &= 0xFFFF; - - while (nt_errs[idx].nt_errstr != NULL) - { - if (nt_errs[idx].nt_errcode == nt_code) - { - return nt_errs[idx].nt_errstr; - } - idx++; - } - return NULL; -} - +/* NT error codes. please read nterr.h + + Copyright (C) 2011 + The Free Software Foundation, Inc. + + This file is part of the Midnight Commander. + + The Midnight Commander is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + The Midnight Commander is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + */ + +#include "includes.h" +#include "nterr.h" + +typedef struct +{ + const char *nt_errstr; + uint32 nt_errcode; + +} nt_err_code_struct; + +nt_err_code_struct const nt_errs[] = { + {"NT_STATUS_UNSUCCESSFUL", NT_STATUS_UNSUCCESSFUL}, + {"NT_STATUS_NOT_IMPLEMENTED", NT_STATUS_NOT_IMPLEMENTED}, + {"NT_STATUS_INVALID_INFO_CLASS", NT_STATUS_INVALID_INFO_CLASS}, + {"NT_STATUS_INFO_LENGTH_MISMATCH", NT_STATUS_INFO_LENGTH_MISMATCH}, + {"NT_STATUS_ACCESS_VIOLATION", NT_STATUS_ACCESS_VIOLATION}, + {"STATUS_BUFFER_OVERFLOW", STATUS_BUFFER_OVERFLOW}, + {"NT_STATUS_IN_PAGE_ERROR", NT_STATUS_IN_PAGE_ERROR}, + {"NT_STATUS_PAGEFILE_QUOTA", NT_STATUS_PAGEFILE_QUOTA}, + {"NT_STATUS_INVALID_HANDLE", NT_STATUS_INVALID_HANDLE}, + {"NT_STATUS_BAD_INITIAL_STACK", NT_STATUS_BAD_INITIAL_STACK}, + {"NT_STATUS_BAD_INITIAL_PC", NT_STATUS_BAD_INITIAL_PC}, + {"NT_STATUS_INVALID_CID", NT_STATUS_INVALID_CID}, + {"NT_STATUS_TIMER_NOT_CANCELED", NT_STATUS_TIMER_NOT_CANCELED}, + {"NT_STATUS_INVALID_PARAMETER", NT_STATUS_INVALID_PARAMETER}, + {"NT_STATUS_NO_SUCH_DEVICE", NT_STATUS_NO_SUCH_DEVICE}, + {"NT_STATUS_NO_SUCH_FILE", NT_STATUS_NO_SUCH_FILE}, + {"NT_STATUS_INVALID_DEVICE_REQUEST", NT_STATUS_INVALID_DEVICE_REQUEST}, + {"NT_STATUS_END_OF_FILE", NT_STATUS_END_OF_FILE}, + {"NT_STATUS_WRONG_VOLUME", NT_STATUS_WRONG_VOLUME}, + {"NT_STATUS_NO_MEDIA_IN_DEVICE", NT_STATUS_NO_MEDIA_IN_DEVICE}, + {"NT_STATUS_UNRECOGNIZED_MEDIA", NT_STATUS_UNRECOGNIZED_MEDIA}, + {"NT_STATUS_NONEXISTENT_SECTOR", NT_STATUS_NONEXISTENT_SECTOR}, + {"NT_STATUS_MORE_PROCESSING_REQUIRED", NT_STATUS_MORE_PROCESSING_REQUIRED}, + {"NT_STATUS_NO_MEMORY", NT_STATUS_NO_MEMORY}, + {"NT_STATUS_CONFLICTING_ADDRESSES", NT_STATUS_CONFLICTING_ADDRESSES}, + {"NT_STATUS_NOT_MAPPED_VIEW", NT_STATUS_NOT_MAPPED_VIEW}, + {"NT_STATUS_UNABLE_TO_FREE_VM", NT_STATUS_UNABLE_TO_FREE_VM}, + {"NT_STATUS_UNABLE_TO_DELETE_SECTION", NT_STATUS_UNABLE_TO_DELETE_SECTION}, + {"NT_STATUS_INVALID_SYSTEM_SERVICE", NT_STATUS_INVALID_SYSTEM_SERVICE}, + {"NT_STATUS_ILLEGAL_INSTRUCTION", NT_STATUS_ILLEGAL_INSTRUCTION}, + {"NT_STATUS_INVALID_LOCK_SEQUENCE", NT_STATUS_INVALID_LOCK_SEQUENCE}, + {"NT_STATUS_INVALID_VIEW_SIZE", NT_STATUS_INVALID_VIEW_SIZE}, + {"NT_STATUS_INVALID_FILE_FOR_SECTION", NT_STATUS_INVALID_FILE_FOR_SECTION}, + {"NT_STATUS_ALREADY_COMMITTED", NT_STATUS_ALREADY_COMMITTED}, + {"NT_STATUS_ACCESS_DENIED", NT_STATUS_ACCESS_DENIED}, + {"NT_STATUS_BUFFER_TOO_SMALL", NT_STATUS_BUFFER_TOO_SMALL}, + {"NT_STATUS_OBJECT_TYPE_MISMATCH", NT_STATUS_OBJECT_TYPE_MISMATCH}, + {"NT_STATUS_NONCONTINUABLE_EXCEPTION", NT_STATUS_NONCONTINUABLE_EXCEPTION}, + {"NT_STATUS_INVALID_DISPOSITION", NT_STATUS_INVALID_DISPOSITION}, + {"NT_STATUS_UNWIND", NT_STATUS_UNWIND}, + {"NT_STATUS_BAD_STACK", NT_STATUS_BAD_STACK}, + {"NT_STATUS_INVALID_UNWIND_TARGET", NT_STATUS_INVALID_UNWIND_TARGET}, + {"NT_STATUS_NOT_LOCKED", NT_STATUS_NOT_LOCKED}, + {"NT_STATUS_PARITY_ERROR", NT_STATUS_PARITY_ERROR}, + {"NT_STATUS_UNABLE_TO_DECOMMIT_VM", NT_STATUS_UNABLE_TO_DECOMMIT_VM}, + {"NT_STATUS_NOT_COMMITTED", NT_STATUS_NOT_COMMITTED}, + {"NT_STATUS_INVALID_PORT_ATTRIBUTES", NT_STATUS_INVALID_PORT_ATTRIBUTES}, + {"NT_STATUS_PORT_MESSAGE_TOO_LONG", NT_STATUS_PORT_MESSAGE_TOO_LONG}, + {"NT_STATUS_INVALID_PARAMETER_MIX", NT_STATUS_INVALID_PARAMETER_MIX}, + {"NT_STATUS_INVALID_QUOTA_LOWER", NT_STATUS_INVALID_QUOTA_LOWER}, + {"NT_STATUS_DISK_CORRUPT_ERROR", NT_STATUS_DISK_CORRUPT_ERROR}, + {"NT_STATUS_OBJECT_NAME_INVALID", NT_STATUS_OBJECT_NAME_INVALID}, + {"NT_STATUS_OBJECT_NAME_NOT_FOUND", NT_STATUS_OBJECT_NAME_NOT_FOUND}, + {"NT_STATUS_OBJECT_NAME_COLLISION", NT_STATUS_OBJECT_NAME_COLLISION}, + {"NT_STATUS_HANDLE_NOT_WAITABLE", NT_STATUS_HANDLE_NOT_WAITABLE}, + {"NT_STATUS_PORT_DISCONNECTED", NT_STATUS_PORT_DISCONNECTED}, + {"NT_STATUS_DEVICE_ALREADY_ATTACHED", NT_STATUS_DEVICE_ALREADY_ATTACHED}, + {"NT_STATUS_OBJECT_PATH_INVALID", NT_STATUS_OBJECT_PATH_INVALID}, + {"NT_STATUS_OBJECT_PATH_NOT_FOUND", NT_STATUS_OBJECT_PATH_NOT_FOUND}, + {"NT_STATUS_OBJECT_PATH_SYNTAX_BAD", NT_STATUS_OBJECT_PATH_SYNTAX_BAD}, + {"NT_STATUS_DATA_OVERRUN", NT_STATUS_DATA_OVERRUN}, + {"NT_STATUS_DATA_LATE_ERROR", NT_STATUS_DATA_LATE_ERROR}, + {"NT_STATUS_DATA_ERROR", NT_STATUS_DATA_ERROR}, + {"NT_STATUS_CRC_ERROR", NT_STATUS_CRC_ERROR}, + {"NT_STATUS_SECTION_TOO_BIG", NT_STATUS_SECTION_TOO_BIG}, + {"NT_STATUS_PORT_CONNECTION_REFUSED", NT_STATUS_PORT_CONNECTION_REFUSED}, + {"NT_STATUS_INVALID_PORT_HANDLE", NT_STATUS_INVALID_PORT_HANDLE}, + {"NT_STATUS_SHARING_VIOLATION", NT_STATUS_SHARING_VIOLATION}, + {"NT_STATUS_QUOTA_EXCEEDED", NT_STATUS_QUOTA_EXCEEDED}, + {"NT_STATUS_INVALID_PAGE_PROTECTION", NT_STATUS_INVALID_PAGE_PROTECTION}, + {"NT_STATUS_MUTANT_NOT_OWNED", NT_STATUS_MUTANT_NOT_OWNED}, + {"NT_STATUS_SEMAPHORE_LIMIT_EXCEEDED", NT_STATUS_SEMAPHORE_LIMIT_EXCEEDED}, + {"NT_STATUS_PORT_ALREADY_SET", NT_STATUS_PORT_ALREADY_SET}, + {"NT_STATUS_SECTION_NOT_IMAGE", NT_STATUS_SECTION_NOT_IMAGE}, + {"NT_STATUS_SUSPEND_COUNT_EXCEEDED", NT_STATUS_SUSPEND_COUNT_EXCEEDED}, + {"NT_STATUS_THREAD_IS_TERMINATING", NT_STATUS_THREAD_IS_TERMINATING}, + {"NT_STATUS_BAD_WORKING_SET_LIMIT", NT_STATUS_BAD_WORKING_SET_LIMIT}, + {"NT_STATUS_INCOMPATIBLE_FILE_MAP", NT_STATUS_INCOMPATIBLE_FILE_MAP}, + {"NT_STATUS_SECTION_PROTECTION", NT_STATUS_SECTION_PROTECTION}, + {"NT_STATUS_EAS_NOT_SUPPORTED", NT_STATUS_EAS_NOT_SUPPORTED}, + {"NT_STATUS_EA_TOO_LARGE", NT_STATUS_EA_TOO_LARGE}, + {"NT_STATUS_NONEXISTENT_EA_ENTRY", NT_STATUS_NONEXISTENT_EA_ENTRY}, + {"NT_STATUS_NO_EAS_ON_FILE", NT_STATUS_NO_EAS_ON_FILE}, + {"NT_STATUS_EA_CORRUPT_ERROR", NT_STATUS_EA_CORRUPT_ERROR}, + {"NT_STATUS_FILE_LOCK_CONFLICT", NT_STATUS_FILE_LOCK_CONFLICT}, + {"NT_STATUS_LOCK_NOT_GRANTED", NT_STATUS_LOCK_NOT_GRANTED}, + {"NT_STATUS_DELETE_PENDING", NT_STATUS_DELETE_PENDING}, + {"NT_STATUS_CTL_FILE_NOT_SUPPORTED", NT_STATUS_CTL_FILE_NOT_SUPPORTED}, + {"NT_STATUS_UNKNOWN_REVISION", NT_STATUS_UNKNOWN_REVISION}, + {"NT_STATUS_REVISION_MISMATCH", NT_STATUS_REVISION_MISMATCH}, + {"NT_STATUS_INVALID_OWNER", NT_STATUS_INVALID_OWNER}, + {"NT_STATUS_INVALID_PRIMARY_GROUP", NT_STATUS_INVALID_PRIMARY_GROUP}, + {"NT_STATUS_NO_IMPERSONATION_TOKEN", NT_STATUS_NO_IMPERSONATION_TOKEN}, + {"NT_STATUS_CANT_DISABLE_MANDATORY", NT_STATUS_CANT_DISABLE_MANDATORY}, + {"NT_STATUS_NO_LOGON_SERVERS", NT_STATUS_NO_LOGON_SERVERS}, + {"NT_STATUS_NO_SUCH_LOGON_SESSION", NT_STATUS_NO_SUCH_LOGON_SESSION}, + {"NT_STATUS_NO_SUCH_PRIVILEGE", NT_STATUS_NO_SUCH_PRIVILEGE}, + {"NT_STATUS_PRIVILEGE_NOT_HELD", NT_STATUS_PRIVILEGE_NOT_HELD}, + {"NT_STATUS_INVALID_ACCOUNT_NAME", NT_STATUS_INVALID_ACCOUNT_NAME}, + {"NT_STATUS_USER_EXISTS", NT_STATUS_USER_EXISTS}, + {"NT_STATUS_NO_SUCH_USER", NT_STATUS_NO_SUCH_USER}, + {"NT_STATUS_GROUP_EXISTS", NT_STATUS_GROUP_EXISTS}, + {"NT_STATUS_NO_SUCH_GROUP", NT_STATUS_NO_SUCH_GROUP}, + {"NT_STATUS_MEMBER_IN_GROUP", NT_STATUS_MEMBER_IN_GROUP}, + {"NT_STATUS_MEMBER_NOT_IN_GROUP", NT_STATUS_MEMBER_NOT_IN_GROUP}, + {"NT_STATUS_LAST_ADMIN", NT_STATUS_LAST_ADMIN}, + {"NT_STATUS_WRONG_PASSWORD", NT_STATUS_WRONG_PASSWORD}, + {"NT_STATUS_ILL_FORMED_PASSWORD", NT_STATUS_ILL_FORMED_PASSWORD}, + {"NT_STATUS_PASSWORD_RESTRICTION", NT_STATUS_PASSWORD_RESTRICTION}, + {"NT_STATUS_LOGON_FAILURE", NT_STATUS_LOGON_FAILURE}, + {"NT_STATUS_ACCOUNT_RESTRICTION", NT_STATUS_ACCOUNT_RESTRICTION}, + {"NT_STATUS_INVALID_LOGON_HOURS", NT_STATUS_INVALID_LOGON_HOURS}, + {"NT_STATUS_INVALID_WORKSTATION", NT_STATUS_INVALID_WORKSTATION}, + {"NT_STATUS_PASSWORD_EXPIRED", NT_STATUS_PASSWORD_EXPIRED}, + {"NT_STATUS_ACCOUNT_DISABLED", NT_STATUS_ACCOUNT_DISABLED}, + {"NT_STATUS_NONE_MAPPED", NT_STATUS_NONE_MAPPED}, + {"NT_STATUS_TOO_MANY_LUIDS_REQUESTED", NT_STATUS_TOO_MANY_LUIDS_REQUESTED}, + {"NT_STATUS_LUIDS_EXHAUSTED", NT_STATUS_LUIDS_EXHAUSTED}, + {"NT_STATUS_INVALID_SUB_AUTHORITY", NT_STATUS_INVALID_SUB_AUTHORITY}, + {"NT_STATUS_INVALID_ACL", NT_STATUS_INVALID_ACL}, + {"NT_STATUS_INVALID_SID", NT_STATUS_INVALID_SID}, + {"NT_STATUS_INVALID_SECURITY_DESCR", NT_STATUS_INVALID_SECURITY_DESCR}, + {"NT_STATUS_PROCEDURE_NOT_FOUND", NT_STATUS_PROCEDURE_NOT_FOUND}, + {"NT_STATUS_INVALID_IMAGE_FORMAT", NT_STATUS_INVALID_IMAGE_FORMAT}, + {"NT_STATUS_NO_TOKEN", NT_STATUS_NO_TOKEN}, + {"NT_STATUS_BAD_INHERITANCE_ACL", NT_STATUS_BAD_INHERITANCE_ACL}, + {"NT_STATUS_RANGE_NOT_LOCKED", NT_STATUS_RANGE_NOT_LOCKED}, + {"NT_STATUS_DISK_FULL", NT_STATUS_DISK_FULL}, + {"NT_STATUS_SERVER_DISABLED", NT_STATUS_SERVER_DISABLED}, + {"NT_STATUS_SERVER_NOT_DISABLED", NT_STATUS_SERVER_NOT_DISABLED}, + {"NT_STATUS_TOO_MANY_GUIDS_REQUESTED", NT_STATUS_TOO_MANY_GUIDS_REQUESTED}, + {"NT_STATUS_GUIDS_EXHAUSTED", NT_STATUS_GUIDS_EXHAUSTED}, + {"NT_STATUS_INVALID_ID_AUTHORITY", NT_STATUS_INVALID_ID_AUTHORITY}, + {"NT_STATUS_AGENTS_EXHAUSTED", NT_STATUS_AGENTS_EXHAUSTED}, + {"NT_STATUS_INVALID_VOLUME_LABEL", NT_STATUS_INVALID_VOLUME_LABEL}, + {"NT_STATUS_SECTION_NOT_EXTENDED", NT_STATUS_SECTION_NOT_EXTENDED}, + {"NT_STATUS_NOT_MAPPED_DATA", NT_STATUS_NOT_MAPPED_DATA}, + {"NT_STATUS_RESOURCE_DATA_NOT_FOUND", NT_STATUS_RESOURCE_DATA_NOT_FOUND}, + {"NT_STATUS_RESOURCE_TYPE_NOT_FOUND", NT_STATUS_RESOURCE_TYPE_NOT_FOUND}, + {"NT_STATUS_RESOURCE_NAME_NOT_FOUND", NT_STATUS_RESOURCE_NAME_NOT_FOUND}, + {"NT_STATUS_ARRAY_BOUNDS_EXCEEDED", NT_STATUS_ARRAY_BOUNDS_EXCEEDED}, + {"NT_STATUS_FLOAT_DENORMAL_OPERAND", NT_STATUS_FLOAT_DENORMAL_OPERAND}, + {"NT_STATUS_FLOAT_DIVIDE_BY_ZERO", NT_STATUS_FLOAT_DIVIDE_BY_ZERO}, + {"NT_STATUS_FLOAT_INEXACT_RESULT", NT_STATUS_FLOAT_INEXACT_RESULT}, + {"NT_STATUS_FLOAT_INVALID_OPERATION", NT_STATUS_FLOAT_INVALID_OPERATION}, + {"NT_STATUS_FLOAT_OVERFLOW", NT_STATUS_FLOAT_OVERFLOW}, + {"NT_STATUS_FLOAT_STACK_CHECK", NT_STATUS_FLOAT_STACK_CHECK}, + {"NT_STATUS_FLOAT_UNDERFLOW", NT_STATUS_FLOAT_UNDERFLOW}, + {"NT_STATUS_INTEGER_DIVIDE_BY_ZERO", NT_STATUS_INTEGER_DIVIDE_BY_ZERO}, + {"NT_STATUS_INTEGER_OVERFLOW", NT_STATUS_INTEGER_OVERFLOW}, + {"NT_STATUS_PRIVILEGED_INSTRUCTION", NT_STATUS_PRIVILEGED_INSTRUCTION}, + {"NT_STATUS_TOO_MANY_PAGING_FILES", NT_STATUS_TOO_MANY_PAGING_FILES}, + {"NT_STATUS_FILE_INVALID", NT_STATUS_FILE_INVALID}, + {"NT_STATUS_ALLOTTED_SPACE_EXCEEDED", NT_STATUS_ALLOTTED_SPACE_EXCEEDED}, + {"NT_STATUS_INSUFFICIENT_RESOURCES", NT_STATUS_INSUFFICIENT_RESOURCES}, + {"NT_STATUS_DFS_EXIT_PATH_FOUND", NT_STATUS_DFS_EXIT_PATH_FOUND}, + {"NT_STATUS_DEVICE_DATA_ERROR", NT_STATUS_DEVICE_DATA_ERROR}, + {"NT_STATUS_DEVICE_NOT_CONNECTED", NT_STATUS_DEVICE_NOT_CONNECTED}, + {"NT_STATUS_DEVICE_POWER_FAILURE", NT_STATUS_DEVICE_POWER_FAILURE}, + {"NT_STATUS_FREE_VM_NOT_AT_BASE", NT_STATUS_FREE_VM_NOT_AT_BASE}, + {"NT_STATUS_MEMORY_NOT_ALLOCATED", NT_STATUS_MEMORY_NOT_ALLOCATED}, + {"NT_STATUS_WORKING_SET_QUOTA", NT_STATUS_WORKING_SET_QUOTA}, + {"NT_STATUS_MEDIA_WRITE_PROTECTED", NT_STATUS_MEDIA_WRITE_PROTECTED}, + {"NT_STATUS_DEVICE_NOT_READY", NT_STATUS_DEVICE_NOT_READY}, + {"NT_STATUS_INVALID_GROUP_ATTRIBUTES", NT_STATUS_INVALID_GROUP_ATTRIBUTES}, + {"NT_STATUS_BAD_IMPERSONATION_LEVEL", NT_STATUS_BAD_IMPERSONATION_LEVEL}, + {"NT_STATUS_CANT_OPEN_ANONYMOUS", NT_STATUS_CANT_OPEN_ANONYMOUS}, + {"NT_STATUS_BAD_VALIDATION_CLASS", NT_STATUS_BAD_VALIDATION_CLASS}, + {"NT_STATUS_BAD_TOKEN_TYPE", NT_STATUS_BAD_TOKEN_TYPE}, + {"NT_STATUS_BAD_MASTER_BOOT_RECORD", NT_STATUS_BAD_MASTER_BOOT_RECORD}, + {"NT_STATUS_INSTRUCTION_MISALIGNMENT", NT_STATUS_INSTRUCTION_MISALIGNMENT}, + {"NT_STATUS_INSTANCE_NOT_AVAILABLE", NT_STATUS_INSTANCE_NOT_AVAILABLE}, + {"NT_STATUS_PIPE_NOT_AVAILABLE", NT_STATUS_PIPE_NOT_AVAILABLE}, + {"NT_STATUS_INVALID_PIPE_STATE", NT_STATUS_INVALID_PIPE_STATE}, + {"NT_STATUS_PIPE_BUSY", NT_STATUS_PIPE_BUSY}, + {"NT_STATUS_ILLEGAL_FUNCTION", NT_STATUS_ILLEGAL_FUNCTION}, + {"NT_STATUS_PIPE_DISCONNECTED", NT_STATUS_PIPE_DISCONNECTED}, + {"NT_STATUS_PIPE_CLOSING", NT_STATUS_PIPE_CLOSING}, + {"NT_STATUS_PIPE_CONNECTED", NT_STATUS_PIPE_CONNECTED}, + {"NT_STATUS_PIPE_LISTENING", NT_STATUS_PIPE_LISTENING}, + {"NT_STATUS_INVALID_READ_MODE", NT_STATUS_INVALID_READ_MODE}, + {"NT_STATUS_IO_TIMEOUT", NT_STATUS_IO_TIMEOUT}, + {"NT_STATUS_FILE_FORCED_CLOSED", NT_STATUS_FILE_FORCED_CLOSED}, + {"NT_STATUS_PROFILING_NOT_STARTED", NT_STATUS_PROFILING_NOT_STARTED}, + {"NT_STATUS_PROFILING_NOT_STOPPED", NT_STATUS_PROFILING_NOT_STOPPED}, + {"NT_STATUS_COULD_NOT_INTERPRET", NT_STATUS_COULD_NOT_INTERPRET}, + {"NT_STATUS_FILE_IS_A_DIRECTORY", NT_STATUS_FILE_IS_A_DIRECTORY}, + {"NT_STATUS_NOT_SUPPORTED", NT_STATUS_NOT_SUPPORTED}, + {"NT_STATUS_REMOTE_NOT_LISTENING", NT_STATUS_REMOTE_NOT_LISTENING}, + {"NT_STATUS_DUPLICATE_NAME", NT_STATUS_DUPLICATE_NAME}, + {"NT_STATUS_BAD_NETWORK_PATH", NT_STATUS_BAD_NETWORK_PATH}, + {"NT_STATUS_NETWORK_BUSY", NT_STATUS_NETWORK_BUSY}, + {"NT_STATUS_DEVICE_DOES_NOT_EXIST", NT_STATUS_DEVICE_DOES_NOT_EXIST}, + {"NT_STATUS_TOO_MANY_COMMANDS", NT_STATUS_TOO_MANY_COMMANDS}, + {"NT_STATUS_ADAPTER_HARDWARE_ERROR", NT_STATUS_ADAPTER_HARDWARE_ERROR}, + {"NT_STATUS_INVALID_NETWORK_RESPONSE", NT_STATUS_INVALID_NETWORK_RESPONSE}, + {"NT_STATUS_UNEXPECTED_NETWORK_ERROR", NT_STATUS_UNEXPECTED_NETWORK_ERROR}, + {"NT_STATUS_BAD_REMOTE_ADAPTER", NT_STATUS_BAD_REMOTE_ADAPTER}, + {"NT_STATUS_PRINT_QUEUE_FULL", NT_STATUS_PRINT_QUEUE_FULL}, + {"NT_STATUS_NO_SPOOL_SPACE", NT_STATUS_NO_SPOOL_SPACE}, + {"NT_STATUS_PRINT_CANCELLED", NT_STATUS_PRINT_CANCELLED}, + {"NT_STATUS_NETWORK_NAME_DELETED", NT_STATUS_NETWORK_NAME_DELETED}, + {"NT_STATUS_NETWORK_ACCESS_DENIED", NT_STATUS_NETWORK_ACCESS_DENIED}, + {"NT_STATUS_BAD_DEVICE_TYPE", NT_STATUS_BAD_DEVICE_TYPE}, + {"NT_STATUS_BAD_NETWORK_NAME", NT_STATUS_BAD_NETWORK_NAME}, + {"NT_STATUS_TOO_MANY_NAMES", NT_STATUS_TOO_MANY_NAMES}, + {"NT_STATUS_TOO_MANY_SESSIONS", NT_STATUS_TOO_MANY_SESSIONS}, + {"NT_STATUS_SHARING_PAUSED", NT_STATUS_SHARING_PAUSED}, + {"NT_STATUS_REQUEST_NOT_ACCEPTED", NT_STATUS_REQUEST_NOT_ACCEPTED}, + {"NT_STATUS_REDIRECTOR_PAUSED", NT_STATUS_REDIRECTOR_PAUSED}, + {"NT_STATUS_NET_WRITE_FAULT", NT_STATUS_NET_WRITE_FAULT}, + {"NT_STATUS_PROFILING_AT_LIMIT", NT_STATUS_PROFILING_AT_LIMIT}, + {"NT_STATUS_NOT_SAME_DEVICE", NT_STATUS_NOT_SAME_DEVICE}, + {"NT_STATUS_FILE_RENAMED", NT_STATUS_FILE_RENAMED}, + {"NT_STATUS_VIRTUAL_CIRCUIT_CLOSED", NT_STATUS_VIRTUAL_CIRCUIT_CLOSED}, + {"NT_STATUS_NO_SECURITY_ON_OBJECT", NT_STATUS_NO_SECURITY_ON_OBJECT}, + {"NT_STATUS_CANT_WAIT", NT_STATUS_CANT_WAIT}, + {"NT_STATUS_PIPE_EMPTY", NT_STATUS_PIPE_EMPTY}, + {"NT_STATUS_CANT_ACCESS_DOMAIN_INFO", NT_STATUS_CANT_ACCESS_DOMAIN_INFO}, + {"NT_STATUS_CANT_TERMINATE_SELF", NT_STATUS_CANT_TERMINATE_SELF}, + {"NT_STATUS_INVALID_SERVER_STATE", NT_STATUS_INVALID_SERVER_STATE}, + {"NT_STATUS_INVALID_DOMAIN_STATE", NT_STATUS_INVALID_DOMAIN_STATE}, + {"NT_STATUS_INVALID_DOMAIN_ROLE", NT_STATUS_INVALID_DOMAIN_ROLE}, + {"NT_STATUS_NO_SUCH_DOMAIN", NT_STATUS_NO_SUCH_DOMAIN}, + {"NT_STATUS_DOMAIN_EXISTS", NT_STATUS_DOMAIN_EXISTS}, + {"NT_STATUS_DOMAIN_LIMIT_EXCEEDED", NT_STATUS_DOMAIN_LIMIT_EXCEEDED}, + {"NT_STATUS_OPLOCK_NOT_GRANTED", NT_STATUS_OPLOCK_NOT_GRANTED}, + {"NT_STATUS_INVALID_OPLOCK_PROTOCOL", NT_STATUS_INVALID_OPLOCK_PROTOCOL}, + {"NT_STATUS_INTERNAL_DB_CORRUPTION", NT_STATUS_INTERNAL_DB_CORRUPTION}, + {"NT_STATUS_INTERNAL_ERROR", NT_STATUS_INTERNAL_ERROR}, + {"NT_STATUS_GENERIC_NOT_MAPPED", NT_STATUS_GENERIC_NOT_MAPPED}, + {"NT_STATUS_BAD_DESCRIPTOR_FORMAT", NT_STATUS_BAD_DESCRIPTOR_FORMAT}, + {"NT_STATUS_INVALID_USER_BUFFER", NT_STATUS_INVALID_USER_BUFFER}, + {"NT_STATUS_UNEXPECTED_IO_ERROR", NT_STATUS_UNEXPECTED_IO_ERROR}, + {"NT_STATUS_UNEXPECTED_MM_CREATE_ERR", NT_STATUS_UNEXPECTED_MM_CREATE_ERR}, + {"NT_STATUS_UNEXPECTED_MM_MAP_ERROR", NT_STATUS_UNEXPECTED_MM_MAP_ERROR}, + {"NT_STATUS_UNEXPECTED_MM_EXTEND_ERR", NT_STATUS_UNEXPECTED_MM_EXTEND_ERR}, + {"NT_STATUS_NOT_LOGON_PROCESS", NT_STATUS_NOT_LOGON_PROCESS}, + {"NT_STATUS_LOGON_SESSION_EXISTS", NT_STATUS_LOGON_SESSION_EXISTS}, + {"NT_STATUS_INVALID_PARAMETER_1", NT_STATUS_INVALID_PARAMETER_1}, + {"NT_STATUS_INVALID_PARAMETER_2", NT_STATUS_INVALID_PARAMETER_2}, + {"NT_STATUS_INVALID_PARAMETER_3", NT_STATUS_INVALID_PARAMETER_3}, + {"NT_STATUS_INVALID_PARAMETER_4", NT_STATUS_INVALID_PARAMETER_4}, + {"NT_STATUS_INVALID_PARAMETER_5", NT_STATUS_INVALID_PARAMETER_5}, + {"NT_STATUS_INVALID_PARAMETER_6", NT_STATUS_INVALID_PARAMETER_6}, + {"NT_STATUS_INVALID_PARAMETER_7", NT_STATUS_INVALID_PARAMETER_7}, + {"NT_STATUS_INVALID_PARAMETER_8", NT_STATUS_INVALID_PARAMETER_8}, + {"NT_STATUS_INVALID_PARAMETER_9", NT_STATUS_INVALID_PARAMETER_9}, + {"NT_STATUS_INVALID_PARAMETER_10", NT_STATUS_INVALID_PARAMETER_10}, + {"NT_STATUS_INVALID_PARAMETER_11", NT_STATUS_INVALID_PARAMETER_11}, + {"NT_STATUS_INVALID_PARAMETER_12", NT_STATUS_INVALID_PARAMETER_12}, + {"NT_STATUS_REDIRECTOR_NOT_STARTED", NT_STATUS_REDIRECTOR_NOT_STARTED}, + {"NT_STATUS_REDIRECTOR_STARTED", NT_STATUS_REDIRECTOR_STARTED}, + {"NT_STATUS_STACK_OVERFLOW", NT_STATUS_STACK_OVERFLOW}, + {"NT_STATUS_NO_SUCH_PACKAGE", NT_STATUS_NO_SUCH_PACKAGE}, + {"NT_STATUS_BAD_FUNCTION_TABLE", NT_STATUS_BAD_FUNCTION_TABLE}, + {"NT_STATUS_DIRECTORY_NOT_EMPTY", NT_STATUS_DIRECTORY_NOT_EMPTY}, + {"NT_STATUS_FILE_CORRUPT_ERROR", NT_STATUS_FILE_CORRUPT_ERROR}, + {"NT_STATUS_NOT_A_DIRECTORY", NT_STATUS_NOT_A_DIRECTORY}, + {"NT_STATUS_BAD_LOGON_SESSION_STATE", NT_STATUS_BAD_LOGON_SESSION_STATE}, + {"NT_STATUS_LOGON_SESSION_COLLISION", NT_STATUS_LOGON_SESSION_COLLISION}, + {"NT_STATUS_NAME_TOO_LONG", NT_STATUS_NAME_TOO_LONG}, + {"NT_STATUS_FILES_OPEN", NT_STATUS_FILES_OPEN}, + {"NT_STATUS_CONNECTION_IN_USE", NT_STATUS_CONNECTION_IN_USE}, + {"NT_STATUS_MESSAGE_NOT_FOUND", NT_STATUS_MESSAGE_NOT_FOUND}, + {"NT_STATUS_PROCESS_IS_TERMINATING", NT_STATUS_PROCESS_IS_TERMINATING}, + {"NT_STATUS_INVALID_LOGON_TYPE", NT_STATUS_INVALID_LOGON_TYPE}, + {"NT_STATUS_NO_GUID_TRANSLATION", NT_STATUS_NO_GUID_TRANSLATION}, + {"NT_STATUS_CANNOT_IMPERSONATE", NT_STATUS_CANNOT_IMPERSONATE}, + {"NT_STATUS_IMAGE_ALREADY_LOADED", NT_STATUS_IMAGE_ALREADY_LOADED}, + {"NT_STATUS_ABIOS_NOT_PRESENT", NT_STATUS_ABIOS_NOT_PRESENT}, + {"NT_STATUS_ABIOS_LID_NOT_EXIST", NT_STATUS_ABIOS_LID_NOT_EXIST}, + {"NT_STATUS_ABIOS_LID_ALREADY_OWNED", NT_STATUS_ABIOS_LID_ALREADY_OWNED}, + {"NT_STATUS_ABIOS_NOT_LID_OWNER", NT_STATUS_ABIOS_NOT_LID_OWNER}, + {"NT_STATUS_ABIOS_INVALID_COMMAND", NT_STATUS_ABIOS_INVALID_COMMAND}, + {"NT_STATUS_ABIOS_INVALID_LID", NT_STATUS_ABIOS_INVALID_LID}, + {"NT_STATUS_ABIOS_SELECTOR_NOT_AVAILABLE", NT_STATUS_ABIOS_SELECTOR_NOT_AVAILABLE}, + {"NT_STATUS_ABIOS_INVALID_SELECTOR", NT_STATUS_ABIOS_INVALID_SELECTOR}, + {"NT_STATUS_NO_LDT", NT_STATUS_NO_LDT}, + {"NT_STATUS_INVALID_LDT_SIZE", NT_STATUS_INVALID_LDT_SIZE}, + {"NT_STATUS_INVALID_LDT_OFFSET", NT_STATUS_INVALID_LDT_OFFSET}, + {"NT_STATUS_INVALID_LDT_DESCRIPTOR", NT_STATUS_INVALID_LDT_DESCRIPTOR}, + {"NT_STATUS_INVALID_IMAGE_NE_FORMAT", NT_STATUS_INVALID_IMAGE_NE_FORMAT}, + {"NT_STATUS_RXACT_INVALID_STATE", NT_STATUS_RXACT_INVALID_STATE}, + {"NT_STATUS_RXACT_COMMIT_FAILURE", NT_STATUS_RXACT_COMMIT_FAILURE}, + {"NT_STATUS_MAPPED_FILE_SIZE_ZERO", NT_STATUS_MAPPED_FILE_SIZE_ZERO}, + {"NT_STATUS_TOO_MANY_OPENED_FILES", NT_STATUS_TOO_MANY_OPENED_FILES}, + {"NT_STATUS_CANCELLED", NT_STATUS_CANCELLED}, + {"NT_STATUS_CANNOT_DELETE", NT_STATUS_CANNOT_DELETE}, + {"NT_STATUS_INVALID_COMPUTER_NAME", NT_STATUS_INVALID_COMPUTER_NAME}, + {"NT_STATUS_FILE_DELETED", NT_STATUS_FILE_DELETED}, + {"NT_STATUS_SPECIAL_ACCOUNT", NT_STATUS_SPECIAL_ACCOUNT}, + {"NT_STATUS_SPECIAL_GROUP", NT_STATUS_SPECIAL_GROUP}, + {"NT_STATUS_SPECIAL_USER", NT_STATUS_SPECIAL_USER}, + {"NT_STATUS_MEMBERS_PRIMARY_GROUP", NT_STATUS_MEMBERS_PRIMARY_GROUP}, + {"NT_STATUS_FILE_CLOSED", NT_STATUS_FILE_CLOSED}, + {"NT_STATUS_TOO_MANY_THREADS", NT_STATUS_TOO_MANY_THREADS}, + {"NT_STATUS_THREAD_NOT_IN_PROCESS", NT_STATUS_THREAD_NOT_IN_PROCESS}, + {"NT_STATUS_TOKEN_ALREADY_IN_USE", NT_STATUS_TOKEN_ALREADY_IN_USE}, + {"NT_STATUS_PAGEFILE_QUOTA_EXCEEDED", NT_STATUS_PAGEFILE_QUOTA_EXCEEDED}, + {"NT_STATUS_COMMITMENT_LIMIT", NT_STATUS_COMMITMENT_LIMIT}, + {"NT_STATUS_INVALID_IMAGE_LE_FORMAT", NT_STATUS_INVALID_IMAGE_LE_FORMAT}, + {"NT_STATUS_INVALID_IMAGE_NOT_MZ", NT_STATUS_INVALID_IMAGE_NOT_MZ}, + {"NT_STATUS_INVALID_IMAGE_PROTECT", NT_STATUS_INVALID_IMAGE_PROTECT}, + {"NT_STATUS_INVALID_IMAGE_WIN_16", NT_STATUS_INVALID_IMAGE_WIN_16}, + {"NT_STATUS_LOGON_SERVER_CONFLICT", NT_STATUS_LOGON_SERVER_CONFLICT}, + {"NT_STATUS_TIME_DIFFERENCE_AT_DC", NT_STATUS_TIME_DIFFERENCE_AT_DC}, + {"NT_STATUS_SYNCHRONIZATION_REQUIRED", NT_STATUS_SYNCHRONIZATION_REQUIRED}, + {"NT_STATUS_DLL_NOT_FOUND", NT_STATUS_DLL_NOT_FOUND}, + {"NT_STATUS_OPEN_FAILED", NT_STATUS_OPEN_FAILED}, + {"NT_STATUS_IO_PRIVILEGE_FAILED", NT_STATUS_IO_PRIVILEGE_FAILED}, + {"NT_STATUS_ORDINAL_NOT_FOUND", NT_STATUS_ORDINAL_NOT_FOUND}, + {"NT_STATUS_ENTRYPOINT_NOT_FOUND", NT_STATUS_ENTRYPOINT_NOT_FOUND}, + {"NT_STATUS_CONTROL_C_EXIT", NT_STATUS_CONTROL_C_EXIT}, + {"NT_STATUS_LOCAL_DISCONNECT", NT_STATUS_LOCAL_DISCONNECT}, + {"NT_STATUS_REMOTE_DISCONNECT", NT_STATUS_REMOTE_DISCONNECT}, + {"NT_STATUS_REMOTE_RESOURCES", NT_STATUS_REMOTE_RESOURCES}, + {"NT_STATUS_LINK_FAILED", NT_STATUS_LINK_FAILED}, + {"NT_STATUS_LINK_TIMEOUT", NT_STATUS_LINK_TIMEOUT}, + {"NT_STATUS_INVALID_CONNECTION", NT_STATUS_INVALID_CONNECTION}, + {"NT_STATUS_INVALID_ADDRESS", NT_STATUS_INVALID_ADDRESS}, + {"NT_STATUS_DLL_INIT_FAILED", NT_STATUS_DLL_INIT_FAILED}, + {"NT_STATUS_MISSING_SYSTEMFILE", NT_STATUS_MISSING_SYSTEMFILE}, + {"NT_STATUS_UNHANDLED_EXCEPTION", NT_STATUS_UNHANDLED_EXCEPTION}, + {"NT_STATUS_APP_INIT_FAILURE", NT_STATUS_APP_INIT_FAILURE}, + {"NT_STATUS_PAGEFILE_CREATE_FAILED", NT_STATUS_PAGEFILE_CREATE_FAILED}, + {"NT_STATUS_NO_PAGEFILE", NT_STATUS_NO_PAGEFILE}, + {"NT_STATUS_INVALID_LEVEL", NT_STATUS_INVALID_LEVEL}, + {"NT_STATUS_WRONG_PASSWORD_CORE", NT_STATUS_WRONG_PASSWORD_CORE}, + {"NT_STATUS_ILLEGAL_FLOAT_CONTEXT", NT_STATUS_ILLEGAL_FLOAT_CONTEXT}, + {"NT_STATUS_PIPE_BROKEN", NT_STATUS_PIPE_BROKEN}, + {"NT_STATUS_REGISTRY_CORRUPT", NT_STATUS_REGISTRY_CORRUPT}, + {"NT_STATUS_REGISTRY_IO_FAILED", NT_STATUS_REGISTRY_IO_FAILED}, + {"NT_STATUS_NO_EVENT_PAIR", NT_STATUS_NO_EVENT_PAIR}, + {"NT_STATUS_UNRECOGNIZED_VOLUME", NT_STATUS_UNRECOGNIZED_VOLUME}, + {"NT_STATUS_SERIAL_NO_DEVICE_INITED", NT_STATUS_SERIAL_NO_DEVICE_INITED}, + {"NT_STATUS_NO_SUCH_ALIAS", NT_STATUS_NO_SUCH_ALIAS}, + {"NT_STATUS_MEMBER_NOT_IN_ALIAS", NT_STATUS_MEMBER_NOT_IN_ALIAS}, + {"NT_STATUS_MEMBER_IN_ALIAS", NT_STATUS_MEMBER_IN_ALIAS}, + {"NT_STATUS_ALIAS_EXISTS", NT_STATUS_ALIAS_EXISTS}, + {"NT_STATUS_LOGON_NOT_GRANTED", NT_STATUS_LOGON_NOT_GRANTED}, + {"NT_STATUS_TOO_MANY_SECRETS", NT_STATUS_TOO_MANY_SECRETS}, + {"NT_STATUS_SECRET_TOO_LONG", NT_STATUS_SECRET_TOO_LONG}, + {"NT_STATUS_INTERNAL_DB_ERROR", NT_STATUS_INTERNAL_DB_ERROR}, + {"NT_STATUS_FULLSCREEN_MODE", NT_STATUS_FULLSCREEN_MODE}, + {"NT_STATUS_TOO_MANY_CONTEXT_IDS", NT_STATUS_TOO_MANY_CONTEXT_IDS}, + {"NT_STATUS_LOGON_TYPE_NOT_GRANTED", NT_STATUS_LOGON_TYPE_NOT_GRANTED}, + {"NT_STATUS_NOT_REGISTRY_FILE", NT_STATUS_NOT_REGISTRY_FILE}, + {"NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED", NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED}, + {"NT_STATUS_DOMAIN_CTRLR_CONFIG_ERROR", NT_STATUS_DOMAIN_CTRLR_CONFIG_ERROR}, + {"NT_STATUS_FT_MISSING_MEMBER", NT_STATUS_FT_MISSING_MEMBER}, + {"NT_STATUS_ILL_FORMED_SERVICE_ENTRY", NT_STATUS_ILL_FORMED_SERVICE_ENTRY}, + {"NT_STATUS_ILLEGAL_CHARACTER", NT_STATUS_ILLEGAL_CHARACTER}, + {"NT_STATUS_UNMAPPABLE_CHARACTER", NT_STATUS_UNMAPPABLE_CHARACTER}, + {"NT_STATUS_UNDEFINED_CHARACTER", NT_STATUS_UNDEFINED_CHARACTER}, + {"NT_STATUS_FLOPPY_VOLUME", NT_STATUS_FLOPPY_VOLUME}, + {"NT_STATUS_FLOPPY_ID_MARK_NOT_FOUND", NT_STATUS_FLOPPY_ID_MARK_NOT_FOUND}, + {"NT_STATUS_FLOPPY_WRONG_CYLINDER", NT_STATUS_FLOPPY_WRONG_CYLINDER}, + {"NT_STATUS_FLOPPY_UNKNOWN_ERROR", NT_STATUS_FLOPPY_UNKNOWN_ERROR}, + {"NT_STATUS_FLOPPY_BAD_REGISTERS", NT_STATUS_FLOPPY_BAD_REGISTERS}, + {"NT_STATUS_DISK_RECALIBRATE_FAILED", NT_STATUS_DISK_RECALIBRATE_FAILED}, + {"NT_STATUS_DISK_OPERATION_FAILED", NT_STATUS_DISK_OPERATION_FAILED}, + {"NT_STATUS_DISK_RESET_FAILED", NT_STATUS_DISK_RESET_FAILED}, + {"NT_STATUS_SHARED_IRQ_BUSY", NT_STATUS_SHARED_IRQ_BUSY}, + {"NT_STATUS_FT_ORPHANING", NT_STATUS_FT_ORPHANING}, + {"NT_STATUS_PARTITION_FAILURE", NT_STATUS_PARTITION_FAILURE}, + {"NT_STATUS_INVALID_BLOCK_LENGTH", NT_STATUS_INVALID_BLOCK_LENGTH}, + {"NT_STATUS_DEVICE_NOT_PARTITIONED", NT_STATUS_DEVICE_NOT_PARTITIONED}, + {"NT_STATUS_UNABLE_TO_LOCK_MEDIA", NT_STATUS_UNABLE_TO_LOCK_MEDIA}, + {"NT_STATUS_UNABLE_TO_UNLOAD_MEDIA", NT_STATUS_UNABLE_TO_UNLOAD_MEDIA}, + {"NT_STATUS_EOM_OVERFLOW", NT_STATUS_EOM_OVERFLOW}, + {"NT_STATUS_NO_MEDIA", NT_STATUS_NO_MEDIA}, + {"NT_STATUS_NO_SUCH_MEMBER", NT_STATUS_NO_SUCH_MEMBER}, + {"NT_STATUS_INVALID_MEMBER", NT_STATUS_INVALID_MEMBER}, + {"NT_STATUS_KEY_DELETED", NT_STATUS_KEY_DELETED}, + {"NT_STATUS_NO_LOG_SPACE", NT_STATUS_NO_LOG_SPACE}, + {"NT_STATUS_TOO_MANY_SIDS", NT_STATUS_TOO_MANY_SIDS}, + {"NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED", NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED}, + {"NT_STATUS_KEY_HAS_CHILDREN", NT_STATUS_KEY_HAS_CHILDREN}, + {"NT_STATUS_CHILD_MUST_BE_VOLATILE", NT_STATUS_CHILD_MUST_BE_VOLATILE}, + {"NT_STATUS_DEVICE_CONFIGURATION_ERROR", NT_STATUS_DEVICE_CONFIGURATION_ERROR}, + {"NT_STATUS_DRIVER_INTERNAL_ERROR", NT_STATUS_DRIVER_INTERNAL_ERROR}, + {"NT_STATUS_INVALID_DEVICE_STATE", NT_STATUS_INVALID_DEVICE_STATE}, + {"NT_STATUS_IO_DEVICE_ERROR", NT_STATUS_IO_DEVICE_ERROR}, + {"NT_STATUS_DEVICE_PROTOCOL_ERROR", NT_STATUS_DEVICE_PROTOCOL_ERROR}, + {"NT_STATUS_BACKUP_CONTROLLER", NT_STATUS_BACKUP_CONTROLLER}, + {"NT_STATUS_LOG_FILE_FULL", NT_STATUS_LOG_FILE_FULL}, + {"NT_STATUS_TOO_LATE", NT_STATUS_TOO_LATE}, + {"NT_STATUS_NO_TRUST_LSA_SECRET", NT_STATUS_NO_TRUST_LSA_SECRET}, + {"NT_STATUS_NO_TRUST_SAM_ACCOUNT", NT_STATUS_NO_TRUST_SAM_ACCOUNT}, + {"NT_STATUS_TRUSTED_DOMAIN_FAILURE", NT_STATUS_TRUSTED_DOMAIN_FAILURE}, + {"NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE", NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE}, + {"NT_STATUS_EVENTLOG_FILE_CORRUPT", NT_STATUS_EVENTLOG_FILE_CORRUPT}, + {"NT_STATUS_EVENTLOG_CANT_START", NT_STATUS_EVENTLOG_CANT_START}, + {"NT_STATUS_TRUST_FAILURE", NT_STATUS_TRUST_FAILURE}, + {"NT_STATUS_MUTANT_LIMIT_EXCEEDED", NT_STATUS_MUTANT_LIMIT_EXCEEDED}, + {"NT_STATUS_NETLOGON_NOT_STARTED", NT_STATUS_NETLOGON_NOT_STARTED}, + {"NT_STATUS_ACCOUNT_EXPIRED", NT_STATUS_ACCOUNT_EXPIRED}, + {"NT_STATUS_POSSIBLE_DEADLOCK", NT_STATUS_POSSIBLE_DEADLOCK}, + {"NT_STATUS_NETWORK_CREDENTIAL_CONFLICT", NT_STATUS_NETWORK_CREDENTIAL_CONFLICT}, + {"NT_STATUS_REMOTE_SESSION_LIMIT", NT_STATUS_REMOTE_SESSION_LIMIT}, + {"NT_STATUS_EVENTLOG_FILE_CHANGED", NT_STATUS_EVENTLOG_FILE_CHANGED}, + {"NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT", NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT}, + {"NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT", NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT}, + {"NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT", NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT}, + {"NT_STATUS_DOMAIN_TRUST_INCONSISTENT", NT_STATUS_DOMAIN_TRUST_INCONSISTENT}, + {"NT_STATUS_FS_DRIVER_REQUIRED", NT_STATUS_FS_DRIVER_REQUIRED}, + {"NT_STATUS_NO_USER_SESSION_KEY", NT_STATUS_NO_USER_SESSION_KEY}, + {"NT_STATUS_USER_SESSION_DELETED", NT_STATUS_USER_SESSION_DELETED}, + {"NT_STATUS_RESOURCE_LANG_NOT_FOUND", NT_STATUS_RESOURCE_LANG_NOT_FOUND}, + {"NT_STATUS_INSUFF_SERVER_RESOURCES", NT_STATUS_INSUFF_SERVER_RESOURCES}, + {"NT_STATUS_INVALID_BUFFER_SIZE", NT_STATUS_INVALID_BUFFER_SIZE}, + {"NT_STATUS_INVALID_ADDRESS_COMPONENT", NT_STATUS_INVALID_ADDRESS_COMPONENT}, + {"NT_STATUS_INVALID_ADDRESS_WILDCARD", NT_STATUS_INVALID_ADDRESS_WILDCARD}, + {"NT_STATUS_TOO_MANY_ADDRESSES", NT_STATUS_TOO_MANY_ADDRESSES}, + {"NT_STATUS_ADDRESS_ALREADY_EXISTS", NT_STATUS_ADDRESS_ALREADY_EXISTS}, + {"NT_STATUS_ADDRESS_CLOSED", NT_STATUS_ADDRESS_CLOSED}, + {"NT_STATUS_CONNECTION_DISCONNECTED", NT_STATUS_CONNECTION_DISCONNECTED}, + {"NT_STATUS_CONNECTION_RESET", NT_STATUS_CONNECTION_RESET}, + {"NT_STATUS_TOO_MANY_NODES", NT_STATUS_TOO_MANY_NODES}, + {"NT_STATUS_TRANSACTION_ABORTED", NT_STATUS_TRANSACTION_ABORTED}, + {"NT_STATUS_TRANSACTION_TIMED_OUT", NT_STATUS_TRANSACTION_TIMED_OUT}, + {"NT_STATUS_TRANSACTION_NO_RELEASE", NT_STATUS_TRANSACTION_NO_RELEASE}, + {"NT_STATUS_TRANSACTION_NO_MATCH", NT_STATUS_TRANSACTION_NO_MATCH}, + {"NT_STATUS_TRANSACTION_RESPONDED", NT_STATUS_TRANSACTION_RESPONDED}, + {"NT_STATUS_TRANSACTION_INVALID_ID", NT_STATUS_TRANSACTION_INVALID_ID}, + {"NT_STATUS_TRANSACTION_INVALID_TYPE", NT_STATUS_TRANSACTION_INVALID_TYPE}, + {"NT_STATUS_NOT_SERVER_SESSION", NT_STATUS_NOT_SERVER_SESSION}, + {"NT_STATUS_NOT_CLIENT_SESSION", NT_STATUS_NOT_CLIENT_SESSION}, + {"NT_STATUS_CANNOT_LOAD_REGISTRY_FILE", NT_STATUS_CANNOT_LOAD_REGISTRY_FILE}, + {"NT_STATUS_DEBUG_ATTACH_FAILED", NT_STATUS_DEBUG_ATTACH_FAILED}, + {"NT_STATUS_SYSTEM_PROCESS_TERMINATED", NT_STATUS_SYSTEM_PROCESS_TERMINATED}, + {"NT_STATUS_DATA_NOT_ACCEPTED", NT_STATUS_DATA_NOT_ACCEPTED}, + {"NT_STATUS_NO_BROWSER_SERVERS_FOUND", NT_STATUS_NO_BROWSER_SERVERS_FOUND}, + {"NT_STATUS_VDM_HARD_ERROR", NT_STATUS_VDM_HARD_ERROR}, + {"NT_STATUS_DRIVER_CANCEL_TIMEOUT", NT_STATUS_DRIVER_CANCEL_TIMEOUT}, + {"NT_STATUS_REPLY_MESSAGE_MISMATCH", NT_STATUS_REPLY_MESSAGE_MISMATCH}, + {"NT_STATUS_MAPPED_ALIGNMENT", NT_STATUS_MAPPED_ALIGNMENT}, + {"NT_STATUS_IMAGE_CHECKSUM_MISMATCH", NT_STATUS_IMAGE_CHECKSUM_MISMATCH}, + {"NT_STATUS_LOST_WRITEBEHIND_DATA", NT_STATUS_LOST_WRITEBEHIND_DATA}, + {"NT_STATUS_CLIENT_SERVER_PARAMETERS_INVALID", NT_STATUS_CLIENT_SERVER_PARAMETERS_INVALID}, + {"NT_STATUS_PASSWORD_MUST_CHANGE", NT_STATUS_PASSWORD_MUST_CHANGE}, + {"NT_STATUS_NOT_FOUND", NT_STATUS_NOT_FOUND}, + {"NT_STATUS_NOT_TINY_STREAM", NT_STATUS_NOT_TINY_STREAM}, + {"NT_STATUS_RECOVERY_FAILURE", NT_STATUS_RECOVERY_FAILURE}, + {"NT_STATUS_STACK_OVERFLOW_READ", NT_STATUS_STACK_OVERFLOW_READ}, + {"NT_STATUS_FAIL_CHECK", NT_STATUS_FAIL_CHECK}, + {"NT_STATUS_DUPLICATE_OBJECTID", NT_STATUS_DUPLICATE_OBJECTID}, + {"NT_STATUS_OBJECTID_EXISTS", NT_STATUS_OBJECTID_EXISTS}, + {"NT_STATUS_CONVERT_TO_LARGE", NT_STATUS_CONVERT_TO_LARGE}, + {"NT_STATUS_RETRY", NT_STATUS_RETRY}, + {"NT_STATUS_FOUND_OUT_OF_SCOPE", NT_STATUS_FOUND_OUT_OF_SCOPE}, + {"NT_STATUS_ALLOCATE_BUCKET", NT_STATUS_ALLOCATE_BUCKET}, + {"NT_STATUS_PROPSET_NOT_FOUND", NT_STATUS_PROPSET_NOT_FOUND}, + {"NT_STATUS_MARSHALL_OVERFLOW", NT_STATUS_MARSHALL_OVERFLOW}, + {"NT_STATUS_INVALID_VARIANT", NT_STATUS_INVALID_VARIANT}, + {"NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND", NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND}, + {"NT_STATUS_ACCOUNT_LOCKED_OUT", NT_STATUS_ACCOUNT_LOCKED_OUT}, + {"NT_STATUS_HANDLE_NOT_CLOSABLE", NT_STATUS_HANDLE_NOT_CLOSABLE}, + {"NT_STATUS_CONNECTION_REFUSED", NT_STATUS_CONNECTION_REFUSED}, + {"NT_STATUS_GRACEFUL_DISCONNECT", NT_STATUS_GRACEFUL_DISCONNECT}, + {"NT_STATUS_ADDRESS_ALREADY_ASSOCIATED", NT_STATUS_ADDRESS_ALREADY_ASSOCIATED}, + {"NT_STATUS_ADDRESS_NOT_ASSOCIATED", NT_STATUS_ADDRESS_NOT_ASSOCIATED}, + {"NT_STATUS_CONNECTION_INVALID", NT_STATUS_CONNECTION_INVALID}, + {"NT_STATUS_CONNECTION_ACTIVE", NT_STATUS_CONNECTION_ACTIVE}, + {"NT_STATUS_NETWORK_UNREACHABLE", NT_STATUS_NETWORK_UNREACHABLE}, + {"NT_STATUS_HOST_UNREACHABLE", NT_STATUS_HOST_UNREACHABLE}, + {"NT_STATUS_PROTOCOL_UNREACHABLE", NT_STATUS_PROTOCOL_UNREACHABLE}, + {"NT_STATUS_PORT_UNREACHABLE", NT_STATUS_PORT_UNREACHABLE}, + {"NT_STATUS_REQUEST_ABORTED", NT_STATUS_REQUEST_ABORTED}, + {"NT_STATUS_CONNECTION_ABORTED", NT_STATUS_CONNECTION_ABORTED}, + {"NT_STATUS_BAD_COMPRESSION_BUFFER", NT_STATUS_BAD_COMPRESSION_BUFFER}, + {"NT_STATUS_USER_MAPPED_FILE", NT_STATUS_USER_MAPPED_FILE}, + {"NT_STATUS_AUDIT_FAILED", NT_STATUS_AUDIT_FAILED}, + {"NT_STATUS_TIMER_RESOLUTION_NOT_SET", NT_STATUS_TIMER_RESOLUTION_NOT_SET}, + {"NT_STATUS_CONNECTION_COUNT_LIMIT", NT_STATUS_CONNECTION_COUNT_LIMIT}, + {"NT_STATUS_LOGIN_TIME_RESTRICTION", NT_STATUS_LOGIN_TIME_RESTRICTION}, + {"NT_STATUS_LOGIN_WKSTA_RESTRICTION", NT_STATUS_LOGIN_WKSTA_RESTRICTION}, + {"NT_STATUS_IMAGE_MP_UP_MISMATCH", NT_STATUS_IMAGE_MP_UP_MISMATCH}, + {"NT_STATUS_INSUFFICIENT_LOGON_INFO", NT_STATUS_INSUFFICIENT_LOGON_INFO}, + {"NT_STATUS_BAD_DLL_ENTRYPOINT", NT_STATUS_BAD_DLL_ENTRYPOINT}, + {"NT_STATUS_BAD_SERVICE_ENTRYPOINT", NT_STATUS_BAD_SERVICE_ENTRYPOINT}, + {"NT_STATUS_LPC_REPLY_LOST", NT_STATUS_LPC_REPLY_LOST}, + {"NT_STATUS_IP_ADDRESS_CONFLICT1", NT_STATUS_IP_ADDRESS_CONFLICT1}, + {"NT_STATUS_IP_ADDRESS_CONFLICT2", NT_STATUS_IP_ADDRESS_CONFLICT2}, + {"NT_STATUS_REGISTRY_QUOTA_LIMIT", NT_STATUS_REGISTRY_QUOTA_LIMIT}, + {"NT_STATUS_PATH_NOT_COVERED", NT_STATUS_PATH_NOT_COVERED}, + {"NT_STATUS_NO_CALLBACK_ACTIVE", NT_STATUS_NO_CALLBACK_ACTIVE}, + {"NT_STATUS_LICENSE_QUOTA_EXCEEDED", NT_STATUS_LICENSE_QUOTA_EXCEEDED}, + {"NT_STATUS_PWD_TOO_SHORT", NT_STATUS_PWD_TOO_SHORT}, + {"NT_STATUS_PWD_TOO_RECENT", NT_STATUS_PWD_TOO_RECENT}, + {"NT_STATUS_PWD_HISTORY_CONFLICT", NT_STATUS_PWD_HISTORY_CONFLICT}, + {"NT_STATUS_PLUGPLAY_NO_DEVICE", NT_STATUS_PLUGPLAY_NO_DEVICE}, + {"NT_STATUS_UNSUPPORTED_COMPRESSION", NT_STATUS_UNSUPPORTED_COMPRESSION}, + {"NT_STATUS_INVALID_HW_PROFILE", NT_STATUS_INVALID_HW_PROFILE}, + {"NT_STATUS_INVALID_PLUGPLAY_DEVICE_PATH", NT_STATUS_INVALID_PLUGPLAY_DEVICE_PATH}, + {"NT_STATUS_DRIVER_ORDINAL_NOT_FOUND", NT_STATUS_DRIVER_ORDINAL_NOT_FOUND}, + {"NT_STATUS_DRIVER_ENTRYPOINT_NOT_FOUND", NT_STATUS_DRIVER_ENTRYPOINT_NOT_FOUND}, + {"NT_STATUS_RESOURCE_NOT_OWNED", NT_STATUS_RESOURCE_NOT_OWNED}, + {"NT_STATUS_TOO_MANY_LINKS", NT_STATUS_TOO_MANY_LINKS}, + {"NT_STATUS_QUOTA_LIST_INCONSISTENT", NT_STATUS_QUOTA_LIST_INCONSISTENT}, + {"NT_STATUS_FILE_IS_OFFLINE", NT_STATUS_FILE_IS_OFFLINE}, + {NULL, 0} +}; + +/***************************************************************************** + returns an NT error message. not amazingly helpful, but better than a number. + *****************************************************************************/ +const char * +get_nt_error_msg (uint32 nt_code) +{ + int idx = 0; + + nt_code &= 0xFFFF; + + while (nt_errs[idx].nt_errstr != NULL) + { + if (nt_errs[idx].nt_errcode == nt_code) + { + return nt_errs[idx].nt_errstr; + } + idx++; + } + return NULL; +} diff --git a/src/vfs/smbfs/helpers/libsmb/pwd_cache.c b/src/vfs/smbfs/helpers/libsmb/pwd_cache.c index cc1a5a05b..09c6b0812 100644 --- a/src/vfs/smbfs/helpers/libsmb/pwd_cache.c +++ b/src/vfs/smbfs/helpers/libsmb/pwd_cache.c @@ -22,7 +22,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . -*/ + */ #include "includes.h" @@ -32,23 +32,25 @@ extern int DEBUGLEVEL; /**************************************************************************** initialises a password structure ****************************************************************************/ -void pwd_init(struct pwd_info *pwd) +void +pwd_init (struct pwd_info *pwd) { - memset((char *)pwd->password , '\0', sizeof(pwd->password )); - memset((char *)pwd->smb_lm_pwd, '\0', sizeof(pwd->smb_lm_pwd)); - memset((char *)pwd->smb_nt_pwd, '\0', sizeof(pwd->smb_nt_pwd)); - memset((char *)pwd->smb_lm_owf, '\0', sizeof(pwd->smb_lm_owf)); - memset((char *)pwd->smb_nt_owf, '\0', sizeof(pwd->smb_nt_owf)); - - pwd->null_pwd = True; /* safest option... */ - pwd->cleartext = False; - pwd->crypted = False; + memset ((char *) pwd->password, '\0', sizeof (pwd->password)); + memset ((char *) pwd->smb_lm_pwd, '\0', sizeof (pwd->smb_lm_pwd)); + memset ((char *) pwd->smb_nt_pwd, '\0', sizeof (pwd->smb_nt_pwd)); + memset ((char *) pwd->smb_lm_owf, '\0', sizeof (pwd->smb_lm_owf)); + memset ((char *) pwd->smb_nt_owf, '\0', sizeof (pwd->smb_nt_owf)); + + pwd->null_pwd = True; /* safest option... */ + pwd->cleartext = False; + pwd->crypted = False; } /**************************************************************************** de-obfuscates a password ****************************************************************************/ -static void pwd_deobfuscate(struct pwd_info *pwd) +static void +pwd_deobfuscate (struct pwd_info *pwd) { (void) pwd; } @@ -56,7 +58,8 @@ static void pwd_deobfuscate(struct pwd_info *pwd) /**************************************************************************** obfuscates a password ****************************************************************************/ -static void pwd_obfuscate(struct pwd_info *pwd) +static void +pwd_obfuscate (struct pwd_info *pwd) { (void) pwd; } @@ -64,7 +67,8 @@ static void pwd_obfuscate(struct pwd_info *pwd) /**************************************************************************** sets the obfuscation key info ****************************************************************************/ -void pwd_obfuscate_key(struct pwd_info *pwd, uint32 int_key, char *str_key) +void +pwd_obfuscate_key (struct pwd_info *pwd, uint32 int_key, char *str_key) { (void) pwd; (void) int_key; @@ -75,185 +79,194 @@ void pwd_obfuscate_key(struct pwd_info *pwd, uint32 int_key, char *str_key) /**************************************************************************** reads a password ****************************************************************************/ -void pwd_read(struct pwd_info *pwd, char *passwd_report, BOOL do_encrypt) +void +pwd_read (struct pwd_info *pwd, char *passwd_report, BOOL do_encrypt) { - /* grab a password */ - char *user_pass; - - pwd_init(pwd); - - user_pass = (char*)getpass(passwd_report); - - if (user_pass == NULL || user_pass[0] == 0) - { - pwd_set_nullpwd(pwd); - } - else if (do_encrypt) - { - pwd_make_lm_nt_16(pwd, user_pass); - } - else - { - pwd_set_cleartext(pwd, user_pass); - } + /* grab a password */ + char *user_pass; + + pwd_init (pwd); + + user_pass = (char *) getpass (passwd_report); + + if (user_pass == NULL || user_pass[0] == 0) + { + pwd_set_nullpwd (pwd); + } + else if (do_encrypt) + { + pwd_make_lm_nt_16 (pwd, user_pass); + } + else + { + pwd_set_cleartext (pwd, user_pass); + } } #endif /**************************************************************************** stores a cleartext password ****************************************************************************/ -void pwd_set_nullpwd(struct pwd_info *pwd) +void +pwd_set_nullpwd (struct pwd_info *pwd) { - pwd_init(pwd); + pwd_init (pwd); - pwd->cleartext = False; - pwd->null_pwd = True; - pwd->crypted = False; + pwd->cleartext = False; + pwd->null_pwd = True; + pwd->crypted = False; } /**************************************************************************** stores a cleartext password ****************************************************************************/ -void pwd_set_cleartext(struct pwd_info *pwd, char *clr) +void +pwd_set_cleartext (struct pwd_info *pwd, char *clr) { - pwd_init(pwd); - fstrcpy(pwd->password, clr); - pwd->cleartext = True; - pwd->null_pwd = False; - pwd->crypted = False; + pwd_init (pwd); + fstrcpy (pwd->password, clr); + pwd->cleartext = True; + pwd->null_pwd = False; + pwd->crypted = False; - pwd_obfuscate(pwd); + pwd_obfuscate (pwd); } /**************************************************************************** gets a cleartext password ****************************************************************************/ -void pwd_get_cleartext(struct pwd_info *pwd, char *clr) +void +pwd_get_cleartext (struct pwd_info *pwd, char *clr) { - pwd_deobfuscate(pwd); - if (pwd->cleartext) - { - fstrcpy(clr, pwd->password); - } - else - { - clr[0] = 0; - } - pwd_obfuscate(pwd); + pwd_deobfuscate (pwd); + if (pwd->cleartext) + { + fstrcpy (clr, pwd->password); + } + else + { + clr[0] = 0; + } + pwd_obfuscate (pwd); } /**************************************************************************** stores lm and nt hashed passwords ****************************************************************************/ -void pwd_set_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]) +void +pwd_set_lm_nt_16 (struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]) { - pwd_init(pwd); - - if (lm_pwd) - { - memcpy(pwd->smb_lm_pwd, lm_pwd, 16); - } - else - { - memset((char *)pwd->smb_lm_pwd, '\0', 16); - } - - if (nt_pwd) - { - memcpy(pwd->smb_nt_pwd, nt_pwd, 16); - } - else - { - memset((char *)pwd->smb_nt_pwd, '\0', 16); - } - - pwd->null_pwd = False; - pwd->cleartext = False; - pwd->crypted = False; - - pwd_obfuscate(pwd); + pwd_init (pwd); + + if (lm_pwd) + { + memcpy (pwd->smb_lm_pwd, lm_pwd, 16); + } + else + { + memset ((char *) pwd->smb_lm_pwd, '\0', 16); + } + + if (nt_pwd) + { + memcpy (pwd->smb_nt_pwd, nt_pwd, 16); + } + else + { + memset ((char *) pwd->smb_nt_pwd, '\0', 16); + } + + pwd->null_pwd = False; + pwd->cleartext = False; + pwd->crypted = False; + + pwd_obfuscate (pwd); } /**************************************************************************** gets lm and nt hashed passwords ****************************************************************************/ -void pwd_get_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]) +void +pwd_get_lm_nt_16 (struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]) { - pwd_deobfuscate(pwd); - if (lm_pwd != NULL) - { - memcpy(lm_pwd, pwd->smb_lm_pwd, 16); - } - if (nt_pwd != NULL) - { - memcpy(nt_pwd, pwd->smb_nt_pwd, 16); - } - pwd_obfuscate(pwd); + pwd_deobfuscate (pwd); + if (lm_pwd != NULL) + { + memcpy (lm_pwd, pwd->smb_lm_pwd, 16); + } + if (nt_pwd != NULL) + { + memcpy (nt_pwd, pwd->smb_nt_pwd, 16); + } + pwd_obfuscate (pwd); } /**************************************************************************** makes lm and nt hashed passwords ****************************************************************************/ -void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr) +void +pwd_make_lm_nt_16 (struct pwd_info *pwd, char *clr) { - pwd_init(pwd); + pwd_init (pwd); - nt_lm_owf_gen(clr, pwd->smb_nt_pwd, pwd->smb_lm_pwd); - pwd->null_pwd = False; - pwd->cleartext = False; - pwd->crypted = False; + nt_lm_owf_gen (clr, pwd->smb_nt_pwd, pwd->smb_lm_pwd); + pwd->null_pwd = False; + pwd->cleartext = False; + pwd->crypted = False; - pwd_obfuscate(pwd); + pwd_obfuscate (pwd); } /**************************************************************************** makes lm and nt OWF crypts ****************************************************************************/ -void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8]) +void +pwd_make_lm_nt_owf (struct pwd_info *pwd, uchar cryptkey[8]) { - pwd_deobfuscate(pwd); + pwd_deobfuscate (pwd); #ifdef DEBUG_PASSWORD - DEBUG(100,("client cryptkey: ")); - dump_data(100, (char *)cryptkey, 8); + DEBUG (100, ("client cryptkey: ")); + dump_data (100, (char *) cryptkey, 8); #endif - SMBOWFencrypt(pwd->smb_nt_pwd, cryptkey, pwd->smb_nt_owf); + SMBOWFencrypt (pwd->smb_nt_pwd, cryptkey, pwd->smb_nt_owf); #ifdef DEBUG_PASSWORD - DEBUG(100,("nt_owf_passwd: ")); - dump_data(100, (char *)pwd->smb_nt_owf, sizeof(pwd->smb_nt_owf)); - DEBUG(100,("nt_sess_pwd: ")); - dump_data(100, (char *)pwd->smb_nt_pwd, sizeof(pwd->smb_nt_pwd)); + DEBUG (100, ("nt_owf_passwd: ")); + dump_data (100, (char *) pwd->smb_nt_owf, sizeof (pwd->smb_nt_owf)); + DEBUG (100, ("nt_sess_pwd: ")); + dump_data (100, (char *) pwd->smb_nt_pwd, sizeof (pwd->smb_nt_pwd)); #endif - SMBOWFencrypt(pwd->smb_lm_pwd, cryptkey, pwd->smb_lm_owf); + SMBOWFencrypt (pwd->smb_lm_pwd, cryptkey, pwd->smb_lm_owf); #ifdef DEBUG_PASSWORD - DEBUG(100,("lm_owf_passwd: ")); - dump_data(100, (char *)pwd->smb_lm_owf, sizeof(pwd->smb_lm_owf)); - DEBUG(100,("lm_sess_pwd: ")); - dump_data(100, (char *)pwd->smb_lm_pwd, sizeof(pwd->smb_lm_pwd)); + DEBUG (100, ("lm_owf_passwd: ")); + dump_data (100, (char *) pwd->smb_lm_owf, sizeof (pwd->smb_lm_owf)); + DEBUG (100, ("lm_sess_pwd: ")); + dump_data (100, (char *) pwd->smb_lm_pwd, sizeof (pwd->smb_lm_pwd)); #endif - pwd->crypted = True; + pwd->crypted = True; - pwd_obfuscate(pwd); + pwd_obfuscate (pwd); } /**************************************************************************** gets lm and nt crypts ****************************************************************************/ -void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24], uchar nt_owf[24]) +void +pwd_get_lm_nt_owf (struct pwd_info *pwd, uchar lm_owf[24], uchar nt_owf[24]) { - pwd_deobfuscate(pwd); - if (lm_owf != NULL) - { - memcpy(lm_owf, pwd->smb_lm_owf, 24); - } - if (nt_owf != NULL) - { - memcpy(nt_owf, pwd->smb_nt_owf, 24); - } - pwd_obfuscate(pwd); + pwd_deobfuscate (pwd); + if (lm_owf != NULL) + { + memcpy (lm_owf, pwd->smb_lm_owf, 24); + } + if (nt_owf != NULL) + { + memcpy (nt_owf, pwd->smb_nt_owf, 24); + } + pwd_obfuscate (pwd); } diff --git a/src/vfs/smbfs/helpers/libsmb/smbdes.c b/src/vfs/smbfs/helpers/libsmb/smbdes.c dissimilarity index 81% index 60d8b82a5..bac091a90 100644 --- a/src/vfs/smbfs/helpers/libsmb/smbdes.c +++ b/src/vfs/smbfs/helpers/libsmb/smbdes.c @@ -1,403 +1,433 @@ -/* - Unix SMB/Netbios implementation. - Version 1.9. - - a partial implementation of DES designed for use in the - SMB authentication protocol - - Copyright (C) Andrew Tridgell 1998 - - Copyright (C) 2011 - The Free Software Foundation, Inc. - - This file is part of the Midnight Commander. - - The Midnight Commander is free software: you can redistribute it - and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of the License, - or (at your option) any later version. - - The Midnight Commander is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "includes.h" - -/* NOTES: - - This code makes no attempt to be fast! In fact, it is a very - slow implementation - - This code is NOT a complete DES implementation. It implements only - the minimum necessary for SMB authentication, as used by all SMB - products (including every copy of Microsoft Windows95 ever sold) - - In particular, it can only do a unchained forward DES pass. This - means it is not possible to use this code for encryption/decryption - of data, instead it is only useful as a "hash" algorithm. - - There is no entry point into this code that allows normal DES operation. - - I believe this means that this code does not come under ITAR - regulations but this is NOT a legal opinion. If you are concerned - about the applicability of ITAR regulations to this code then you - should confirm it for yourself (and maybe let me know if you come - up with a different answer to the one above) -*/ - -#undef uchar -#define uchar const unsigned char - -static uchar perm1[56] = {57, 49, 41, 33, 25, 17, 9, - 1, 58, 50, 42, 34, 26, 18, - 10, 2, 59, 51, 43, 35, 27, - 19, 11, 3, 60, 52, 44, 36, - 63, 55, 47, 39, 31, 23, 15, - 7, 62, 54, 46, 38, 30, 22, - 14, 6, 61, 53, 45, 37, 29, - 21, 13, 5, 28, 20, 12, 4}; - -static uchar perm2[48] = {14, 17, 11, 24, 1, 5, - 3, 28, 15, 6, 21, 10, - 23, 19, 12, 4, 26, 8, - 16, 7, 27, 20, 13, 2, - 41, 52, 31, 37, 47, 55, - 30, 40, 51, 45, 33, 48, - 44, 49, 39, 56, 34, 53, - 46, 42, 50, 36, 29, 32}; - -static uchar perm3[64] = {58, 50, 42, 34, 26, 18, 10, 2, - 60, 52, 44, 36, 28, 20, 12, 4, - 62, 54, 46, 38, 30, 22, 14, 6, - 64, 56, 48, 40, 32, 24, 16, 8, - 57, 49, 41, 33, 25, 17, 9, 1, - 59, 51, 43, 35, 27, 19, 11, 3, - 61, 53, 45, 37, 29, 21, 13, 5, - 63, 55, 47, 39, 31, 23, 15, 7}; - -static uchar perm4[48] = { 32, 1, 2, 3, 4, 5, - 4, 5, 6, 7, 8, 9, - 8, 9, 10, 11, 12, 13, - 12, 13, 14, 15, 16, 17, - 16, 17, 18, 19, 20, 21, - 20, 21, 22, 23, 24, 25, - 24, 25, 26, 27, 28, 29, - 28, 29, 30, 31, 32, 1}; - -static uchar perm5[32] = { 16, 7, 20, 21, - 29, 12, 28, 17, - 1, 15, 23, 26, - 5, 18, 31, 10, - 2, 8, 24, 14, - 32, 27, 3, 9, - 19, 13, 30, 6, - 22, 11, 4, 25}; - - -static uchar perm6[64] ={ 40, 8, 48, 16, 56, 24, 64, 32, - 39, 7, 47, 15, 55, 23, 63, 31, - 38, 6, 46, 14, 54, 22, 62, 30, - 37, 5, 45, 13, 53, 21, 61, 29, - 36, 4, 44, 12, 52, 20, 60, 28, - 35, 3, 43, 11, 51, 19, 59, 27, - 34, 2, 42, 10, 50, 18, 58, 26, - 33, 1, 41, 9, 49, 17, 57, 25}; - - -static uchar sc[16] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1}; - -static uchar sbox[8][4][16] = { - {{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7}, - {0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8}, - {4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0}, - {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}}, - - {{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10}, - {3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5}, - {0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15}, - {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}}, - - {{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8}, - {13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1}, - {13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7}, - {1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}}, - - {{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15}, - {13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9}, - {10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4}, - {3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}}, - - {{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9}, - {14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6}, - {4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14}, - {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}}, - - {{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11}, - {10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8}, - {9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6}, - {4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}}, - - {{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1}, - {13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6}, - {1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2}, - {6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}}, - - {{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7}, - {1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2}, - {7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8}, - {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}}}; - -static void permute(char *out, char *in, uchar *p, int n) -{ - int i; - for (i=0;i>1; - key[1] = ((str[0]&0x01)<<6) | (str[1]>>2); - key[2] = ((str[1]&0x03)<<5) | (str[2]>>3); - key[3] = ((str[2]&0x07)<<4) | (str[3]>>4); - key[4] = ((str[3]&0x0F)<<3) | (str[4]>>5); - key[5] = ((str[4]&0x1F)<<2) | (str[5]>>6); - key[6] = ((str[5]&0x3F)<<1) | (str[6]>>7); - key[7] = str[6]&0x7F; - for (i=0;i<8;i++) { - key[i] = (key[i]<<1); - } -} - - -static void smbhash(unsigned char *out, unsigned char *in, unsigned char *key, int forw) -{ - int i; - char outb[64]; - char inb[64]; - char keyb[64]; - unsigned char key2[8]; - - str_to_key(key, key2); - - for (i=0;i<64;i++) { - inb[i] = (in[i/8] & (1<<(7-(i%8)))) ? 1 : 0; - keyb[i] = (key2[i/8] & (1<<(7-(i%8)))) ? 1 : 0; - outb[i] = 0; - } - - dohash(outb, inb, keyb, forw); - - for (i=0;i<8;i++) { - out[i] = 0; - } - - for (i=0;i<64;i++) { - if (outb[i]) - out[i/8] |= (1<<(7-(i%8))); - } -} - -void E_P16(unsigned char *p14,unsigned char *p16) -{ - unsigned char sp8[8] = {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25}; - smbhash(p16, sp8, p14, 1); - smbhash(p16+8, sp8, p14+7, 1); -} - -void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24) -{ - smbhash(p24, c8, p21, 1); - smbhash(p24+8, c8, p21+7, 1); - smbhash(p24+16, c8, p21+14, 1); -} - -void D_P16(unsigned char *p14, unsigned char *in, unsigned char *out) -{ - smbhash(out, in, p14, 0); - smbhash(out+8, in+8, p14+7, 0); -} - -void E_old_pw_hash( unsigned char *p14, unsigned char *in, unsigned char *out) -{ - smbhash(out, in, p14, 1); - smbhash(out+8, in+8, p14+7, 1); -} - -void cred_hash1(unsigned char *out,unsigned char *in,unsigned char *key) -{ - unsigned char buf[8]; - - smbhash(buf, in, key, 1); - smbhash(out, buf, key+9, 1); -} - -void cred_hash2(unsigned char *out,unsigned char *in,unsigned char *key) -{ - unsigned char buf[8]; - static unsigned char key2[8]; - - smbhash(buf, in, key, 1); - key2[0] = key[7]; - smbhash(out, buf, key2, 1); -} - -void cred_hash3(unsigned char *out,unsigned char *in,unsigned char *key, int forw) -{ - static unsigned char key2[8]; - - smbhash(out, in, key, forw); - key2[0] = key[7]; - smbhash(out + 8, in + 8, key2, forw); -} - -void SamOEMhash( unsigned char *data, unsigned char *key, int val) -{ - unsigned char s_box[256]; - unsigned char index_i = 0; - unsigned char index_j = 0; - unsigned char j = 0; - int ind; - - for (ind = 0; ind < 256; ind++) - { - s_box[ind] = (unsigned char)ind; - } - - for( ind = 0; ind < 256; ind++) - { - unsigned char tc; - - j += (s_box[ind] + key[ind%16]); - - tc = s_box[ind]; - s_box[ind] = s_box[j]; - s_box[j] = tc; - } - for( ind = 0; ind < (val ? 516 : 16); ind++) - { - unsigned char tc; - unsigned char t; - - index_i++; - index_j += s_box[index_i]; - - tc = s_box[index_i]; - s_box[index_i] = s_box[index_j]; - s_box[index_j] = tc; - - t = s_box[index_i] + s_box[index_j]; - data[ind] = data[ind] ^ s_box[t]; - } -} +/* + Unix SMB/Netbios implementation. + Version 1.9. + + a partial implementation of DES designed for use in the + SMB authentication protocol + + Copyright (C) Andrew Tridgell 1998 + + Copyright (C) 2011 + The Free Software Foundation, Inc. + + This file is part of the Midnight Commander. + + The Midnight Commander is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + The Midnight Commander is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + */ + +#include "includes.h" + +/* NOTES: + + This code makes no attempt to be fast! In fact, it is a very + slow implementation + + This code is NOT a complete DES implementation. It implements only + the minimum necessary for SMB authentication, as used by all SMB + products (including every copy of Microsoft Windows95 ever sold) + + In particular, it can only do a unchained forward DES pass. This + means it is not possible to use this code for encryption/decryption + of data, instead it is only useful as a "hash" algorithm. + + There is no entry point into this code that allows normal DES operation. + + I believe this means that this code does not come under ITAR + regulations but this is NOT a legal opinion. If you are concerned + about the applicability of ITAR regulations to this code then you + should confirm it for yourself (and maybe let me know if you come + up with a different answer to the one above) + */ + +#undef uchar +#define uchar const unsigned char + +static uchar perm1[56] = { 57, 49, 41, 33, 25, 17, 9, + 1, 58, 50, 42, 34, 26, 18, + 10, 2, 59, 51, 43, 35, 27, + 19, 11, 3, 60, 52, 44, 36, + 63, 55, 47, 39, 31, 23, 15, + 7, 62, 54, 46, 38, 30, 22, + 14, 6, 61, 53, 45, 37, 29, + 21, 13, 5, 28, 20, 12, 4 +}; + +static uchar perm2[48] = { 14, 17, 11, 24, 1, 5, + 3, 28, 15, 6, 21, 10, + 23, 19, 12, 4, 26, 8, + 16, 7, 27, 20, 13, 2, + 41, 52, 31, 37, 47, 55, + 30, 40, 51, 45, 33, 48, + 44, 49, 39, 56, 34, 53, + 46, 42, 50, 36, 29, 32 +}; + +static uchar perm3[64] = { 58, 50, 42, 34, 26, 18, 10, 2, + 60, 52, 44, 36, 28, 20, 12, 4, + 62, 54, 46, 38, 30, 22, 14, 6, + 64, 56, 48, 40, 32, 24, 16, 8, + 57, 49, 41, 33, 25, 17, 9, 1, + 59, 51, 43, 35, 27, 19, 11, 3, + 61, 53, 45, 37, 29, 21, 13, 5, + 63, 55, 47, 39, 31, 23, 15, 7 +}; + +static uchar perm4[48] = { 32, 1, 2, 3, 4, 5, + 4, 5, 6, 7, 8, 9, + 8, 9, 10, 11, 12, 13, + 12, 13, 14, 15, 16, 17, + 16, 17, 18, 19, 20, 21, + 20, 21, 22, 23, 24, 25, + 24, 25, 26, 27, 28, 29, + 28, 29, 30, 31, 32, 1 +}; + +static uchar perm5[32] = { 16, 7, 20, 21, + 29, 12, 28, 17, + 1, 15, 23, 26, + 5, 18, 31, 10, + 2, 8, 24, 14, + 32, 27, 3, 9, + 19, 13, 30, 6, + 22, 11, 4, 25 +}; + + +static uchar perm6[64] = { 40, 8, 48, 16, 56, 24, 64, 32, + 39, 7, 47, 15, 55, 23, 63, 31, + 38, 6, 46, 14, 54, 22, 62, 30, + 37, 5, 45, 13, 53, 21, 61, 29, + 36, 4, 44, 12, 52, 20, 60, 28, + 35, 3, 43, 11, 51, 19, 59, 27, + 34, 2, 42, 10, 50, 18, 58, 26, + 33, 1, 41, 9, 49, 17, 57, 25 +}; + + +static uchar sc[16] = { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 }; + +static uchar sbox[8][4][16] = { + {{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7}, + {0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8}, + {4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0}, + {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}}, + + {{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10}, + {3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5}, + {0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15}, + {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}}, + + {{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8}, + {13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1}, + {13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7}, + {1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}}, + + {{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15}, + {13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9}, + {10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4}, + {3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}}, + + {{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9}, + {14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6}, + {4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14}, + {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}}, + + {{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11}, + {10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8}, + {9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6}, + {4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}}, + + {{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1}, + {13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6}, + {1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2}, + {6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}}, + + {{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7}, + {1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2}, + {7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8}, + {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}} +}; + +static void +permute (char *out, char *in, uchar * p, int n) +{ + int i; + for (i = 0; i < n; i++) + out[i] = in[p[i] - 1]; +} + +static void +lshift (char *d, int count, int n) +{ + char out[64]; + int i; + for (i = 0; i < n; i++) + out[i] = d[(i + count) % n]; + for (i = 0; i < n; i++) + d[i] = out[i]; +} + +static void +concat (char *out, char *in1, char *in2, int l1, int l2) +{ + while (l1--) + *out++ = *in1++; + while (l2--) + *out++ = *in2++; +} + +static void +xor (char *out, char *in1, char *in2, int n) +{ + int i; + for (i = 0; i < n; i++) + out[i] = in1[i] ^ in2[i]; +} + +static void +dohash (char *out, char *in, char *key, int forw) +{ + int i, j, k; + char pk1[56]; + char c[28]; + char d[28]; + char cd[56]; + char ki[16][48]; + char pd1[64]; + char l[32], r[32]; + char rl[64]; + + permute (pk1, key, perm1, 56); + + for (i = 0; i < 28; i++) + c[i] = pk1[i]; + for (i = 0; i < 28; i++) + d[i] = pk1[i + 28]; + + for (i = 0; i < 16; i++) + { + lshift (c, sc[i], 28); + lshift (d, sc[i], 28); + + concat (cd, c, d, 28, 28); + permute (ki[i], cd, perm2, 48); + } + + permute (pd1, in, perm3, 64); + + for (j = 0; j < 32; j++) + { + l[j] = pd1[j]; + r[j] = pd1[j + 32]; + } + + for (i = 0; i < 16; i++) + { + char er[48]; + char erk[48]; + char b[8][6]; + char cb[32]; + char pcb[32]; + char r2[32]; + + permute (er, r, perm4, 48); + + xor (erk, er, ki[forw ? i : 15 - i], 48); + + for (j = 0; j < 8; j++) + for (k = 0; k < 6; k++) + b[j][k] = erk[j * 6 + k]; + + for (j = 0; j < 8; j++) + { + int m, n; + m = (b[j][0] << 1) | b[j][5]; + + n = (b[j][1] << 3) | (b[j][2] << 2) | (b[j][3] << 1) | b[j][4]; + + for (k = 0; k < 4; k++) + b[j][k] = (sbox[j][m][n] & (1 << (3 - k))) ? 1 : 0; + } + + for (j = 0; j < 8; j++) + for (k = 0; k < 4; k++) + cb[j * 4 + k] = b[j][k]; + permute (pcb, cb, perm5, 32); + + xor (r2, l, pcb, 32); + + for (j = 0; j < 32; j++) + l[j] = r[j]; + + for (j = 0; j < 32; j++) + r[j] = r2[j]; + } + + concat (rl, r, l, 32, 32); + + permute (out, rl, perm6, 64); +} + +static void +str_to_key (unsigned char *str, unsigned char *key) +{ + int i; + + key[0] = str[0] >> 1; + key[1] = ((str[0] & 0x01) << 6) | (str[1] >> 2); + key[2] = ((str[1] & 0x03) << 5) | (str[2] >> 3); + key[3] = ((str[2] & 0x07) << 4) | (str[3] >> 4); + key[4] = ((str[3] & 0x0F) << 3) | (str[4] >> 5); + key[5] = ((str[4] & 0x1F) << 2) | (str[5] >> 6); + key[6] = ((str[5] & 0x3F) << 1) | (str[6] >> 7); + key[7] = str[6] & 0x7F; + for (i = 0; i < 8; i++) + { + key[i] = (key[i] << 1); + } +} + + +static void +smbhash (unsigned char *out, unsigned char *in, unsigned char *key, int forw) +{ + int i; + char outb[64]; + char inb[64]; + char keyb[64]; + unsigned char key2[8]; + + str_to_key (key, key2); + + for (i = 0; i < 64; i++) + { + inb[i] = (in[i / 8] & (1 << (7 - (i % 8)))) ? 1 : 0; + keyb[i] = (key2[i / 8] & (1 << (7 - (i % 8)))) ? 1 : 0; + outb[i] = 0; + } + + dohash (outb, inb, keyb, forw); + + for (i = 0; i < 8; i++) + { + out[i] = 0; + } + + for (i = 0; i < 64; i++) + { + if (outb[i]) + out[i / 8] |= (1 << (7 - (i % 8))); + } +} + +void +E_P16 (unsigned char *p14, unsigned char *p16) +{ + unsigned char sp8[8] = { 0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 }; + smbhash (p16, sp8, p14, 1); + smbhash (p16 + 8, sp8, p14 + 7, 1); +} + +void +E_P24 (unsigned char *p21, unsigned char *c8, unsigned char *p24) +{ + smbhash (p24, c8, p21, 1); + smbhash (p24 + 8, c8, p21 + 7, 1); + smbhash (p24 + 16, c8, p21 + 14, 1); +} + +void +D_P16 (unsigned char *p14, unsigned char *in, unsigned char *out) +{ + smbhash (out, in, p14, 0); + smbhash (out + 8, in + 8, p14 + 7, 0); +} + +void +E_old_pw_hash (unsigned char *p14, unsigned char *in, unsigned char *out) +{ + smbhash (out, in, p14, 1); + smbhash (out + 8, in + 8, p14 + 7, 1); +} + +void +cred_hash1 (unsigned char *out, unsigned char *in, unsigned char *key) +{ + unsigned char buf[8]; + + smbhash (buf, in, key, 1); + smbhash (out, buf, key + 9, 1); +} + +void +cred_hash2 (unsigned char *out, unsigned char *in, unsigned char *key) +{ + unsigned char buf[8]; + static unsigned char key2[8]; + + smbhash (buf, in, key, 1); + key2[0] = key[7]; + smbhash (out, buf, key2, 1); +} + +void +cred_hash3 (unsigned char *out, unsigned char *in, unsigned char *key, int forw) +{ + static unsigned char key2[8]; + + smbhash (out, in, key, forw); + key2[0] = key[7]; + smbhash (out + 8, in + 8, key2, forw); +} + +void +SamOEMhash (unsigned char *data, unsigned char *key, int val) +{ + unsigned char s_box[256]; + unsigned char index_i = 0; + unsigned char index_j = 0; + unsigned char j = 0; + int ind; + + for (ind = 0; ind < 256; ind++) + { + s_box[ind] = (unsigned char) ind; + } + + for (ind = 0; ind < 256; ind++) + { + unsigned char tc; + + j += (s_box[ind] + key[ind % 16]); + + tc = s_box[ind]; + s_box[ind] = s_box[j]; + s_box[j] = tc; + } + for (ind = 0; ind < (val ? 516 : 16); ind++) + { + unsigned char tc; + unsigned char t; + + index_i++; + index_j += s_box[index_i]; + + tc = s_box[index_i]; + s_box[index_i] = s_box[index_j]; + s_box[index_j] = tc; + + t = s_box[index_i] + s_box[index_j]; + data[ind] = data[ind] ^ s_box[t]; + } +} diff --git a/src/vfs/smbfs/helpers/libsmb/smbencrypt.c b/src/vfs/smbfs/helpers/libsmb/smbencrypt.c index b0d5f44b2..9fc2bdfb4 100644 --- a/src/vfs/smbfs/helpers/libsmb/smbencrypt.c +++ b/src/vfs/smbfs/helpers/libsmb/smbencrypt.c @@ -24,7 +24,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . -*/ + */ #include "includes.h" @@ -36,34 +36,36 @@ extern int DEBUGLEVEL; This implements the X/Open SMB password encryption It takes a password, a 8 byte "crypt key" and puts 24 bytes of encrypted password into p24 */ -void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24) +void +SMBencrypt (uchar * passwd, uchar * c8, uchar * p24) { - uchar p14[15], p21[21]; + uchar p14[15], p21[21]; - memset(p21,'\0',21); - memset(p14,'\0',14); - StrnCpy((char *)p14,(char *)passwd,14); + memset (p21, '\0', 21); + memset (p14, '\0', 14); + StrnCpy ((char *) p14, (char *) passwd, 14); - strupper((char *)p14); - E_P16(p14, p21); + strupper ((char *) p14); + E_P16 (p14, p21); - SMBOWFencrypt(p21, c8, p24); + SMBOWFencrypt (p21, c8, p24); #ifdef DEBUG_PASSWORD - DEBUG(100,("SMBencrypt: lm#, challenge, response\n")); - dump_data(100, (char *)p21, 16); - dump_data(100, (char *)c8, 8); - dump_data(100, (char *)p24, 24); + DEBUG (100, ("SMBencrypt: lm#, challenge, response\n")); + dump_data (100, (char *) p21, 16); + dump_data (100, (char *) c8, 8); + dump_data (100, (char *) p24, 24); #endif } /* Routines for Windows NT MD4 Hash functions. */ -static int _my_wcslen(int16 *str) +static int +_my_wcslen (int16 * str) { - int len = 0; - while(*str++ != 0) - len++; - return len; + int len = 0; + while (*str++ != 0) + len++; + return len; } /* @@ -72,126 +74,133 @@ static int _my_wcslen(int16 *str) * this must be in intel (little-endian) * format. */ - -static int _my_mbstowcs(int16 *dst, uchar *src, int len) + +static int +_my_mbstowcs (int16 * dst, uchar * src, int len) { - int i; - int16 val; - - for(i = 0; i < len; i++) { - val = *src; - SSVAL(dst,0,val); - dst++; - src++; - if(val == 0) - break; - } - return i; + int i; + int16 val; + + for (i = 0; i < len; i++) + { + val = *src; + SSVAL (dst, 0, val); + dst++; + src++; + if (val == 0) + break; + } + return i; } /* * Creates the MD4 Hash of the users password in NT UNICODE. */ - -void E_md4hash(uchar *passwd, uchar *p16) + +void +E_md4hash (uchar * passwd, uchar * p16) { - int len; - int16 wpwd[129]; - - /* Password cannot be longer than 128 characters */ - len = strlen((char *)passwd); - if(len > 128) - len = 128; - /* Password must be converted to NT unicode */ - _my_mbstowcs(wpwd, passwd, len); - wpwd[len] = 0; /* Ensure string is null terminated */ - /* Calculate length in bytes */ - len = _my_wcslen(wpwd) * sizeof(int16); - - mdfour(p16, (unsigned char *)wpwd, len); + int len; + int16 wpwd[129]; + + /* Password cannot be longer than 128 characters */ + len = strlen ((char *) passwd); + if (len > 128) + len = 128; + /* Password must be converted to NT unicode */ + _my_mbstowcs (wpwd, passwd, len); + wpwd[len] = 0; /* Ensure string is null terminated */ + /* Calculate length in bytes */ + len = _my_wcslen (wpwd) * sizeof (int16); + + mdfour (p16, (unsigned char *) wpwd, len); } /* Does both the NT and LM owfs of a user's password */ -void nt_lm_owf_gen(char *pwd, uchar nt_p16[16], uchar p16[16]) +void +nt_lm_owf_gen (char *pwd, uchar nt_p16[16], uchar p16[16]) { - char passwd[130]; + char passwd[130]; - memset(passwd,'\0',130); - safe_strcpy( passwd, pwd, sizeof(passwd)-1); + memset (passwd, '\0', 130); + safe_strcpy (passwd, pwd, sizeof (passwd) - 1); - /* Calculate the MD4 hash (NT compatible) of the password */ - memset(nt_p16, '\0', 16); - E_md4hash((uchar *)passwd, nt_p16); + /* Calculate the MD4 hash (NT compatible) of the password */ + memset (nt_p16, '\0', 16); + E_md4hash ((uchar *) passwd, nt_p16); #ifdef DEBUG_PASSWORD - DEBUG(100,("nt_lm_owf_gen: pwd, nt#\n")); - dump_data(120, passwd, strlen(passwd)); - dump_data(100, (char *)nt_p16, 16); + DEBUG (100, ("nt_lm_owf_gen: pwd, nt#\n")); + dump_data (120, passwd, strlen (passwd)); + dump_data (100, (char *) nt_p16, 16); #endif - /* Mangle the passwords into Lanman format */ - passwd[14] = '\0'; - strupper(passwd); + /* Mangle the passwords into Lanman format */ + passwd[14] = '\0'; + strupper (passwd); - /* Calculate the SMB (lanman) hash functions of the password */ + /* Calculate the SMB (lanman) hash functions of the password */ - memset(p16, '\0', 16); - E_P16((uchar *) passwd, (uchar *)p16); + memset (p16, '\0', 16); + E_P16 ((uchar *) passwd, (uchar *) p16); #ifdef DEBUG_PASSWORD - DEBUG(100,("nt_lm_owf_gen: pwd, lm#\n")); - dump_data(120, passwd, strlen(passwd)); - dump_data(100, (char *)p16, 16); + DEBUG (100, ("nt_lm_owf_gen: pwd, lm#\n")); + dump_data (120, passwd, strlen (passwd)); + dump_data (100, (char *) p16, 16); #endif - /* clear out local copy of user's password (just being paranoid). */ - memset(passwd, '\0', sizeof(passwd)); + /* clear out local copy of user's password (just being paranoid). */ + memset (passwd, '\0', sizeof (passwd)); } /* Does the des encryption from the NT or LM MD4 hash. */ -void SMBOWFencrypt(uchar passwd[16], uchar *c8, uchar p24[24]) +void +SMBOWFencrypt (uchar passwd[16], uchar * c8, uchar p24[24]) { - uchar p21[21]; - - memset(p21,'\0',21); - - memcpy(p21, passwd, 16); - E_P24(p21, c8, p24); + uchar p21[21]; + + memset (p21, '\0', 21); + + memcpy (p21, passwd, 16); + E_P24 (p21, c8, p24); } /* Does the des encryption from the FIRST 8 BYTES of the NT or LM MD4 hash. */ -void NTLMSSPOWFencrypt(uchar passwd[8], uchar *ntlmchalresp, uchar p24[24]) +void +NTLMSSPOWFencrypt (uchar passwd[8], uchar * ntlmchalresp, uchar p24[24]) { - uchar p21[21]; - - memset(p21,'\0',21); - memcpy(p21, passwd, 8); - memset(p21 + 8, 0xbd, 8); + uchar p21[21]; - E_P24(p21, ntlmchalresp, p24); + memset (p21, '\0', 21); + memcpy (p21, passwd, 8); + memset (p21 + 8, 0xbd, 8); + + E_P24 (p21, ntlmchalresp, p24); #ifdef DEBUG_PASSWORD - DEBUG(100,("NTLMSSPOWFencrypt: p21, c8, p24\n")); - dump_data(100, (char *)p21, 21); - dump_data(100, (char *)ntlmchalresp, 8); - dump_data(100, (char *)p24, 24); + DEBUG (100, ("NTLMSSPOWFencrypt: p21, c8, p24\n")); + dump_data (100, (char *) p21, 21); + dump_data (100, (char *) ntlmchalresp, 8); + dump_data (100, (char *) p24, 24); #endif } /* Does the NT MD4 hash then des encryption. */ - -void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24) + +void +SMBNTencrypt (uchar * passwd, uchar * c8, uchar * p24) { - uchar p21[21]; - - memset(p21,'\0',21); - - E_md4hash(passwd, p21); - SMBOWFencrypt(p21, c8, p24); + uchar p21[21]; + + memset (p21, '\0', 21); + + E_md4hash (passwd, p21); + SMBOWFencrypt (p21, c8, p24); #ifdef DEBUG_PASSWORD - DEBUG(100,("SMBNTencrypt: nt#, challenge, response\n")); - dump_data(100, (char *)p21, 16); - dump_data(100, (char *)c8, 8); - dump_data(100, (char *)p24, 24); + DEBUG (100, ("SMBNTencrypt: nt#, challenge, response\n")); + dump_data (100, (char *) p21, 16); + dump_data (100, (char *) c8, 8); + dump_data (100, (char *) p24, 24); #endif } diff --git a/src/vfs/smbfs/helpers/libsmb/smberr.c b/src/vfs/smbfs/helpers/libsmb/smberr.c dissimilarity index 80% index ac169e9f4..cfef8d48a 100644 --- a/src/vfs/smbfs/helpers/libsmb/smberr.c +++ b/src/vfs/smbfs/helpers/libsmb/smberr.c @@ -1,186 +1,203 @@ -/* - Unix SMB/Netbios implementation. - Version 1.9. - - Copyright (C) Andrew Tridgell 1998 - - Copyright (C) 2011 - The Free Software Foundation, Inc. - - This file is part of the Midnight Commander. - - The Midnight Commander is free software: you can redistribute it - and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of the License, - or (at your option) any later version. - - The Midnight Commander is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#define NO_SYSLOG - -#include "includes.h" - -extern int DEBUGLEVEL; - -/* error code stuff - put together by Merik Karman - merik@blackadder.dsh.oz.au */ - -typedef struct -{ - const char *name; - int code; - const char *message; -} err_code_struct; - -/* Dos Error Messages */ -static err_code_struct const dos_msgs[] = { - {"ERRbadfunc",1,"Invalid function."}, - {"ERRbadfile",2,"File not found."}, - {"ERRbadpath",3,"Directory invalid."}, - {"ERRnofids",4,"No file descriptors available"}, - {"ERRnoaccess",5,"Access denied."}, - {"ERRbadfid",6,"Invalid file handle."}, - {"ERRbadmcb",7,"Memory control blocks destroyed."}, - {"ERRnomem",8,"Insufficient server memory to perform the requested function."}, - {"ERRbadmem",9,"Invalid memory block address."}, - {"ERRbadenv",10,"Invalid environment."}, - {"ERRbadformat",11,"Invalid format."}, - {"ERRbadaccess",12,"Invalid open mode."}, - {"ERRbaddata",13,"Invalid data."}, - {"ERR",14,"reserved."}, - {"ERRbaddrive",15,"Invalid drive specified."}, - {"ERRremcd",16,"A Delete Directory request attempted to remove the server's current directory."}, - {"ERRdiffdevice",17,"Not same device."}, - {"ERRnofiles",18,"A File Search command can find no more files matching the specified criteria."}, - {"ERRbadshare",32,"The sharing mode specified for an Open conflicts with existing FIDs on the file."}, - {"ERRlock",33,"A Lock request conflicted with an existing lock or specified an invalid mode, or an Unlock requested attempted to remove a lock held by another process."}, - {"ERRunsup", 50, "The operation is unsupported"}, - {"ERRnosuchshare", 67, "You specified an invalid share name"}, - {"ERRfilexists",80,"The file named in a Create Directory, Make New File or Link request already exists."}, - {"ERRbadpipe",230,"Pipe invalid."}, - {"ERRpipebusy",231,"All instances of the requested pipe are busy."}, - {"ERRpipeclosing",232,"Pipe close in progress."}, - {"ERRnotconnected",233,"No process on other end of pipe."}, - {"ERRmoredata",234,"There is more data to be returned."}, - {"ERRinvgroup",2455,"Invalid workgroup (try the -W option)"}, - {NULL,-1,NULL}}; - -/* Server Error Messages */ -static err_code_struct const server_msgs[] = { - {"ERRerror",1,"Non-specific error code."}, - {"ERRbadpw",2,"Bad password - name/password pair in a Tree Connect or Session Setup are invalid."}, - {"ERRbadtype",3,"reserved."}, - {"ERRaccess",4,"The requester does not have the necessary access rights within the specified context for the requested function. The context is defined by the TID or the UID."}, - {"ERRinvnid",5,"The tree ID (TID) specified in a command was invalid."}, - {"ERRinvnetname",6,"Invalid network name in tree connect."}, - {"ERRinvdevice",7,"Invalid device - printer request made to non-printer connection or non-printer request made to printer connection."}, - {"ERRqfull",49,"Print queue full (files) -- returned by open print file."}, - {"ERRqtoobig",50,"Print queue full -- no space."}, - {"ERRqeof",51,"EOF on print queue dump."}, - {"ERRinvpfid",52,"Invalid print file FID."}, - {"ERRsmbcmd",64,"The server did not recognize the command received."}, - {"ERRsrverror",65,"The server encountered an internal error, e.g., system file unavailable."}, - {"ERRfilespecs",67,"The file handle (FID) and pathname parameters contained an invalid combination of values."}, - {"ERRreserved",68,"reserved."}, - {"ERRbadpermits",69,"The access permissions specified for a file or directory are not a valid combination. The server cannot set the requested attribute."}, - {"ERRreserved",70,"reserved."}, - {"ERRsetattrmode",71,"The attribute mode in the Set File Attribute request is invalid."}, - {"ERRpaused",81,"Server is paused."}, - {"ERRmsgoff",82,"Not receiving messages."}, - {"ERRnoroom",83,"No room to buffer message."}, - {"ERRrmuns",87,"Too many remote user names."}, - {"ERRtimeout",88,"Operation timed out."}, - {"ERRnoresource",89,"No resources currently available for request."}, - {"ERRtoomanyuids",90,"Too many UIDs active on this session."}, - {"ERRbaduid",91,"The UID is not known as a valid ID on this session."}, - {"ERRusempx",250,"Temp unable to support Raw, use MPX mode."}, - {"ERRusestd",251,"Temp unable to support Raw, use standard read/write."}, - {"ERRcontmpx",252,"Continue in MPX mode."}, - {"ERRreserved",253,"reserved."}, - {"ERRreserved",254,"reserved."}, - {"ERRnosupport",0xFFFF,"Function not supported."}, - {NULL,-1,NULL}}; - -/* Hard Error Messages */ -static err_code_struct const hard_msgs[] = { - {"ERRnowrite",19,"Attempt to write on write-protected diskette."}, - {"ERRbadunit",20,"Unknown unit."}, - {"ERRnotready",21,"Drive not ready."}, - {"ERRbadcmd",22,"Unknown command."}, - {"ERRdata",23,"Data error (CRC)."}, - {"ERRbadreq",24,"Bad request structure length."}, - {"ERRseek",25 ,"Seek error."}, - {"ERRbadmedia",26,"Unknown media type."}, - {"ERRbadsector",27,"Sector not found."}, - {"ERRnopaper",28,"Printer out of paper."}, - {"ERRwrite",29,"Write fault."}, - {"ERRread",30,"Read fault."}, - {"ERRgeneral",31,"General failure."}, - {"ERRbadshare",32,"An open conflicts with an existing open."}, - {"ERRlock",33,"A Lock request conflicted with an existing lock or specified an invalid mode, or an Unlock requested attempted to remove a lock held by another process."}, - {"ERRwrongdisk",34,"The wrong disk was found in a drive."}, - {"ERRFCBUnavail",35,"No FCBs are available to process request."}, - {"ERRsharebufexc",36,"A sharing buffer has been exceeded."}, - {NULL,-1,NULL}}; - - -struct -{ - int code; - const char *class; - err_code_struct const *err_msgs; -} const err_classes [] = { - {0,"SUCCESS",NULL}, - {0x01,"ERRDOS",dos_msgs}, - {0x02,"ERRSRV",server_msgs}, - {0x03,"ERRHRD",hard_msgs}, - {0x04,"ERRXOS",NULL}, - {0xE1,"ERRRMX1",NULL}, - {0xE2,"ERRRMX2",NULL}, - {0xE3,"ERRRMX3",NULL}, - {0xFF,"ERRCMD",NULL}, - {-1,NULL,NULL}}; - - -/**************************************************************************** -return a SMB error string from a SMB buffer -****************************************************************************/ -char *smb_errstr(char *inbuf) -{ - static pstring ret; - int class = CVAL(inbuf,smb_rcls); - int num = SVAL(inbuf,smb_err); - int i,j; - - for (i=0;err_classes[i].class;i++) - if (err_classes[i].code == class) - { - if (err_classes[i].err_msgs) - { - const err_code_struct *err = err_classes[i].err_msgs; - for (j=0;err[j].name;j++) - if (num == err[j].code) - { - if (DEBUGLEVEL > 0) - slprintf(ret, sizeof(ret) - 1, "%s - %s (%s)",err_classes[i].class, - err[j].name,err[j].message); - else - slprintf(ret, sizeof(ret) - 1, "%s - %s",err_classes[i].class,err[j].name); - return ret; - } - } - - slprintf(ret, sizeof(ret) - 1, "%s - %d",err_classes[i].class,num); - return ret; - } - - slprintf(ret, sizeof(ret) - 1, "Error: Unknown error (%d,%d)",class,num); - return(ret); -} +/* + Unix SMB/Netbios implementation. + Version 1.9. + + Copyright (C) Andrew Tridgell 1998 + + Copyright (C) 2011 + The Free Software Foundation, Inc. + + This file is part of the Midnight Commander. + + The Midnight Commander is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + The Midnight Commander is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + */ + +#define NO_SYSLOG + +#include "includes.h" + +extern int DEBUGLEVEL; + +/* error code stuff - put together by Merik Karman + merik@blackadder.dsh.oz.au */ + +typedef struct +{ + const char *name; + int code; + const char *message; +} err_code_struct; + +/* Dos Error Messages */ +static err_code_struct const dos_msgs[] = { + {"ERRbadfunc", 1, "Invalid function."}, + {"ERRbadfile", 2, "File not found."}, + {"ERRbadpath", 3, "Directory invalid."}, + {"ERRnofids", 4, "No file descriptors available"}, + {"ERRnoaccess", 5, "Access denied."}, + {"ERRbadfid", 6, "Invalid file handle."}, + {"ERRbadmcb", 7, "Memory control blocks destroyed."}, + {"ERRnomem", 8, "Insufficient server memory to perform the requested function."}, + {"ERRbadmem", 9, "Invalid memory block address."}, + {"ERRbadenv", 10, "Invalid environment."}, + {"ERRbadformat", 11, "Invalid format."}, + {"ERRbadaccess", 12, "Invalid open mode."}, + {"ERRbaddata", 13, "Invalid data."}, + {"ERR", 14, "reserved."}, + {"ERRbaddrive", 15, "Invalid drive specified."}, + {"ERRremcd", 16, + "A Delete Directory request attempted to remove the server's current directory."}, + {"ERRdiffdevice", 17, "Not same device."}, + {"ERRnofiles", 18, + "A File Search command can find no more files matching the specified criteria."}, + {"ERRbadshare", 32, + "The sharing mode specified for an Open conflicts with existing FIDs on the file."}, + {"ERRlock", 33, + "A Lock request conflicted with an existing lock or specified an invalid mode, or an Unlock requested attempted to remove a lock held by another process."}, + {"ERRunsup", 50, "The operation is unsupported"}, + {"ERRnosuchshare", 67, "You specified an invalid share name"}, + {"ERRfilexists", 80, + "The file named in a Create Directory, Make New File or Link request already exists."}, + {"ERRbadpipe", 230, "Pipe invalid."}, + {"ERRpipebusy", 231, "All instances of the requested pipe are busy."}, + {"ERRpipeclosing", 232, "Pipe close in progress."}, + {"ERRnotconnected", 233, "No process on other end of pipe."}, + {"ERRmoredata", 234, "There is more data to be returned."}, + {"ERRinvgroup", 2455, "Invalid workgroup (try the -W option)"}, + {NULL, -1, NULL} +}; + +/* Server Error Messages */ +static err_code_struct const server_msgs[] = { + {"ERRerror", 1, "Non-specific error code."}, + {"ERRbadpw", 2, + "Bad password - name/password pair in a Tree Connect or Session Setup are invalid."}, + {"ERRbadtype", 3, "reserved."}, + {"ERRaccess", 4, + "The requester does not have the necessary access rights within the specified context for the requested function. The context is defined by the TID or the UID."}, + {"ERRinvnid", 5, "The tree ID (TID) specified in a command was invalid."}, + {"ERRinvnetname", 6, "Invalid network name in tree connect."}, + {"ERRinvdevice", 7, + "Invalid device - printer request made to non-printer connection or non-printer request made to printer connection."}, + {"ERRqfull", 49, "Print queue full (files) -- returned by open print file."}, + {"ERRqtoobig", 50, "Print queue full -- no space."}, + {"ERRqeof", 51, "EOF on print queue dump."}, + {"ERRinvpfid", 52, "Invalid print file FID."}, + {"ERRsmbcmd", 64, "The server did not recognize the command received."}, + {"ERRsrverror", 65, "The server encountered an internal error, e.g., system file unavailable."}, + {"ERRfilespecs", 67, + "The file handle (FID) and pathname parameters contained an invalid combination of values."}, + {"ERRreserved", 68, "reserved."}, + {"ERRbadpermits", 69, + "The access permissions specified for a file or directory are not a valid combination. The server cannot set the requested attribute."}, + {"ERRreserved", 70, "reserved."}, + {"ERRsetattrmode", 71, "The attribute mode in the Set File Attribute request is invalid."}, + {"ERRpaused", 81, "Server is paused."}, + {"ERRmsgoff", 82, "Not receiving messages."}, + {"ERRnoroom", 83, "No room to buffer message."}, + {"ERRrmuns", 87, "Too many remote user names."}, + {"ERRtimeout", 88, "Operation timed out."}, + {"ERRnoresource", 89, "No resources currently available for request."}, + {"ERRtoomanyuids", 90, "Too many UIDs active on this session."}, + {"ERRbaduid", 91, "The UID is not known as a valid ID on this session."}, + {"ERRusempx", 250, "Temp unable to support Raw, use MPX mode."}, + {"ERRusestd", 251, "Temp unable to support Raw, use standard read/write."}, + {"ERRcontmpx", 252, "Continue in MPX mode."}, + {"ERRreserved", 253, "reserved."}, + {"ERRreserved", 254, "reserved."}, + {"ERRnosupport", 0xFFFF, "Function not supported."}, + {NULL, -1, NULL} +}; + +/* Hard Error Messages */ +static err_code_struct const hard_msgs[] = { + {"ERRnowrite", 19, "Attempt to write on write-protected diskette."}, + {"ERRbadunit", 20, "Unknown unit."}, + {"ERRnotready", 21, "Drive not ready."}, + {"ERRbadcmd", 22, "Unknown command."}, + {"ERRdata", 23, "Data error (CRC)."}, + {"ERRbadreq", 24, "Bad request structure length."}, + {"ERRseek", 25, "Seek error."}, + {"ERRbadmedia", 26, "Unknown media type."}, + {"ERRbadsector", 27, "Sector not found."}, + {"ERRnopaper", 28, "Printer out of paper."}, + {"ERRwrite", 29, "Write fault."}, + {"ERRread", 30, "Read fault."}, + {"ERRgeneral", 31, "General failure."}, + {"ERRbadshare", 32, "An open conflicts with an existing open."}, + {"ERRlock", 33, + "A Lock request conflicted with an existing lock or specified an invalid mode, or an Unlock requested attempted to remove a lock held by another process."}, + {"ERRwrongdisk", 34, "The wrong disk was found in a drive."}, + {"ERRFCBUnavail", 35, "No FCBs are available to process request."}, + {"ERRsharebufexc", 36, "A sharing buffer has been exceeded."}, + {NULL, -1, NULL} +}; + + +struct +{ + int code; + const char *class; + err_code_struct const *err_msgs; +} const err_classes[] = { + {0, "SUCCESS", NULL}, + {0x01, "ERRDOS", dos_msgs}, + {0x02, "ERRSRV", server_msgs}, + {0x03, "ERRHRD", hard_msgs}, + {0x04, "ERRXOS", NULL}, + {0xE1, "ERRRMX1", NULL}, + {0xE2, "ERRRMX2", NULL}, + {0xE3, "ERRRMX3", NULL}, + {0xFF, "ERRCMD", NULL}, + {-1, NULL, NULL} +}; + + +/**************************************************************************** +return a SMB error string from a SMB buffer +****************************************************************************/ +char * +smb_errstr (char *inbuf) +{ + static pstring ret; + int class = CVAL (inbuf, smb_rcls); + int num = SVAL (inbuf, smb_err); + int i, j; + + for (i = 0; err_classes[i].class; i++) + if (err_classes[i].code == class) + { + if (err_classes[i].err_msgs) + { + const err_code_struct *err = err_classes[i].err_msgs; + for (j = 0; err[j].name; j++) + if (num == err[j].code) + { + if (DEBUGLEVEL > 0) + slprintf (ret, sizeof (ret) - 1, "%s - %s (%s)", err_classes[i].class, + err[j].name, err[j].message); + else + slprintf (ret, sizeof (ret) - 1, "%s - %s", err_classes[i].class, + err[j].name); + return ret; + } + } + + slprintf (ret, sizeof (ret) - 1, "%s - %d", err_classes[i].class, num); + return ret; + } + + slprintf (ret, sizeof (ret) - 1, "Error: Unknown error (%d,%d)", class, num); + return (ret); +} diff --git a/src/vfs/smbfs/helpers/param/loadparm.c b/src/vfs/smbfs/helpers/param/loadparm.c dissimilarity index 79% index f160adc9f..1484917c5 100644 --- a/src/vfs/smbfs/helpers/param/loadparm.c +++ b/src/vfs/smbfs/helpers/param/loadparm.c @@ -1,2459 +1,2589 @@ -/* - Unix SMB/Netbios implementation. - Version 1.9. - Parameter loading functions - - Copyright (C) Karl Auer 1993-1998 - - Copyright (C) 2011 - The Free Software Foundation, Inc. - - Largely re-written by Andrew Tridgell, September 1994 - - This file is part of the Midnight Commander. - - The Midnight Commander is free software: you can redistribute it - and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of the License, - or (at your option) any later version. - - The Midnight Commander is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -/* - * Load parameters. - * - * This module provides suitable callback functions for the params - * module. It builds the internal table of service details which is - * then used by the rest of the server. - * - * To add a parameter: - * - * 1) add it to the global or service structure definition - * 2) add it to the parm_table - * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING()) - * 4) If it's a global then initialise it in init_globals. If a local - * (ie. service) parameter then initialise it in the sDefault structure - * - * - * Notes: - * The configuration file is processed sequentially for speed. It is NOT - * accessed randomly as happens in 'real' Windows. For this reason, there - * is a fair bit of sequence-dependent code here - ie., code which assumes - * that certain things happen before others. In particular, the code which - * happens at the boundary between sections is delicately poised, so be - * careful! - * - */ - -#include "includes.h" - -/* Set default coding system for KANJI if none specified in Makefile. */ -/* - * We treat KANJI specially due to historical precedent (it was the - * first non-english codepage added to Samba). With the new dynamic - * codepage support this is not needed anymore. - * - * The define 'KANJI' is being overloaded to mean 'use kanji codepage - * by default' and also 'this is the filename-to-disk conversion - * method to use'. This really should be removed and all control - * over this left in the smb.conf parameters 'client codepage' - * and 'coding system'. - */ -#ifndef KANJI -#define KANJI "sbcs" -#endif /* KANJI */ - -BOOL in_client = False; /* Not in the client by default */ -BOOL bLoaded = False; - -extern int DEBUGLEVEL; -extern pstring user_socket_options; -extern pstring global_myname; -pstring global_scope = ""; - -#ifndef GLOBAL_NAME -#define GLOBAL_NAME "global" -#endif - -#ifndef PRINTERS_NAME -#define PRINTERS_NAME "printers" -#endif - -#ifndef HOMES_NAME -#define HOMES_NAME "homes" -#endif - -/* some helpful bits */ -#define pSERVICE(i) ServicePtrs[i] -#define iSERVICE(i) (*pSERVICE(i)) -#define LP_SNUM_OK(iService) (((iService) >= 0) && ((iService) < iNumServices) && iSERVICE(iService).valid) -#define VALID(i) iSERVICE(i).valid - -int keepalive=DEFAULT_KEEPALIVE; -static BOOL use_getwd_cache; - -extern int extra_time_offset; - -/* - * This structure describes global (ie., server-wide) parameters. - */ -typedef struct -{ - char *szPrintcapname; - char *szLockDir; - char *szRootdir; - char *szDefaultService; - char *szDfree; - char *szMsgCommand; - char *szHostsEquiv; - char *szServerString; - char *szAutoServices; - char *szPasswdProgram; - char *szPasswdChat; - char *szLogFile; - char *szConfigFile; - char *szSMBPasswdFile; - char *szPasswordServer; - char *szSocketOptions; - char *szValidChars; - char *szWorkGroup; - char *szDomainAdminGroup; - char *szDomainGuestGroup; - char *szDomainAdminUsers; - char *szDomainGuestUsers; - char *szDomainHostsallow; - char *szDomainHostsdeny; - char *szUsernameMap; -#ifdef USING_GROUPNAME_MAP - char *szGroupnameMap; -#endif /* USING_GROUPNAME_MAP */ - char *szCharacterSet; - char *szLogonScript; - char *szLogonPath; - char *szLogonDrive; - char *szLogonHome; - char *szSmbrun; - char *szWINSserver; - char *szCodingSystem; - char *szInterfaces; - char *szRemoteAnnounce; - char *szRemoteBrowseSync; - char *szSocketAddress; - char *szNISHomeMapName; - char *szAnnounceVersion; /* This is initialised in init_globals */ - char *szNetbiosAliases; - char *szDomainOtherSIDs; - char *szDomainGroups; - char *szDriverFile; - char *szNameResolveOrder; - char *szLdapServer; - char *szLdapSuffix; - char *szLdapFilter; - char *szLdapRoot; - char *szLdapRootPassword; - char *szPanicAction; - char *szAddUserScript; - char *szDelUserScript; - int max_log_size; - int mangled_stack; - int max_xmit; - int max_mux; - int max_open_files; - int max_packet; - int pwordlevel; - int unamelevel; - int deadtime; - int maxprotocol; - int security; - int maxdisksize; - int lpqcachetime; - int syslog; - int os_level; - int max_ttl; - int max_wins_ttl; - int min_wins_ttl; - int ReadSize; - int lm_announce; - int lm_interval; - int shmem_size; - int client_code_page; - int announce_as; /* This is initialised in init_globals */ - int machine_password_timeout; - int change_notify_timeout; - int stat_cache_size; - int map_to_guest; - int min_passwd_length; - int oplock_break_wait_time; -#ifdef WITH_LDAP - int ldap_port; -#endif /* WITH_LDAP */ -#ifdef WITH_SSL - int sslVersion; - char *sslHostsRequire; - char *sslHostsResign; - char *sslCaCertDir; - char *sslCaCertFile; - char *sslCert; - char *sslPrivKey; - char *sslClientCert; - char *sslClientPrivKey; - char *sslCiphers; - BOOL sslEnabled; - BOOL sslReqClientCert; - BOOL sslReqServerCert; - BOOL sslCompatibility; -#endif /* WITH_SSL */ - BOOL bDNSproxy; - BOOL bWINSsupport; - BOOL bWINSproxy; - BOOL bLocalMaster; - BOOL bPreferredMaster; - BOOL bDomainMaster; - BOOL bDomainLogons; - BOOL bEncryptPasswords; - BOOL bUpdateEncrypt; - BOOL bStripDot; - BOOL bNullPasswords; - BOOL bLoadPrinters; - BOOL bUseRhosts; - BOOL bReadRaw; - BOOL bWriteRaw; - BOOL bReadPrediction; - BOOL bReadbmpx; - BOOL bSyslogOnly; - BOOL bBrowseList; - BOOL bUnixRealname; - BOOL bNISHomeMap; - BOOL bTimeServer; - BOOL bBindInterfacesOnly; - BOOL bUnixPasswdSync; - BOOL bPasswdChatDebug; - BOOL bOleLockingCompat; - BOOL bTimestampLogs; - BOOL bNTSmbSupport; - BOOL bNTPipeSupport; - BOOL bNTAclSupport; - BOOL bStatCache; - BOOL bKernelOplocks; - BOOL bAllowTrustedDomains; - BOOL bRestrictAnonymous; -} global; - -static global Globals; - - - -/* - * This structure describes a single service. - */ -typedef struct -{ - BOOL valid; - char *szService; - char *szPath; - char *szUsername; - char *szGuestaccount; - char *szInvalidUsers; - char *szValidUsers; - char *szAdminUsers; - char *szCopy; - char *szInclude; - char *szPreExec; - char *szPostExec; - char *szRootPreExec; - char *szRootPostExec; - char *szPrintcommand; - char *szLpqcommand; - char *szLprmcommand; - char *szLppausecommand; - char *szLpresumecommand; - char *szQueuepausecommand; - char *szQueueresumecommand; - char *szPrintername; - char *szPrinterDriver; - char *szPrinterDriverLocation; - char *szDontdescend; - char *szHostsallow; - char *szHostsdeny; - char *szMagicScript; - char *szMagicOutput; - char *szMangledMap; - char *szVetoFiles; - char *szHideFiles; - char *szVetoOplockFiles; - char *comment; - char *force_user; - char *force_group; - char *readlist; - char *writelist; - char *volume; - char *fstype; - int iMinPrintSpace; - int iCreate_mask; - int iCreate_force_mode; - int iDir_mask; - int iDir_force_mode; - int iMaxConnections; - int iDefaultCase; - int iPrinting; - int iOplockContentionLimit; - BOOL bAlternatePerm; - BOOL bRevalidate; - BOOL bCaseSensitive; - BOOL bCasePreserve; - BOOL bShortCasePreserve; - BOOL bCaseMangle; - BOOL status; - BOOL bHideDotFiles; - BOOL bBrowseable; - BOOL bAvailable; - BOOL bRead_only; - BOOL bNo_set_dir; - BOOL bGuest_only; - BOOL bGuest_ok; - BOOL bPrint_ok; - BOOL bPostscript; - BOOL bMap_system; - BOOL bMap_hidden; - BOOL bMap_archive; - BOOL bLocking; - BOOL bStrictLocking; - BOOL bShareModes; - BOOL bOpLocks; - BOOL bOnlyUser; - BOOL bMangledNames; - BOOL bWidelinks; - BOOL bSymlinks; - BOOL bSyncAlways; - BOOL bStrictSync; - char magic_char; - BOOL *copymap; - BOOL bDeleteReadonly; - BOOL bFakeOplocks; - BOOL bDeleteVetoFiles; - BOOL bDosFiletimes; - BOOL bDosFiletimeResolution; - BOOL bFakeDirCreateTimes; - BOOL bBlockingLocks; - BOOL bMangleLocks; - char dummy[3]; /* for alignment */ -} service; - - -/* This is a default service used to prime a services structure */ -static service sDefault = -{ - True, /* valid */ - NULL, /* szService */ - NULL, /* szPath */ - NULL, /* szUsername */ - NULL, /* szGuestAccount - this is set in init_globals() */ - NULL, /* szInvalidUsers */ - NULL, /* szValidUsers */ - NULL, /* szAdminUsers */ - NULL, /* szCopy */ - NULL, /* szInclude */ - NULL, /* szPreExec */ - NULL, /* szPostExec */ - NULL, /* szRootPreExec */ - NULL, /* szRootPostExec */ - NULL, /* szPrintcommand */ - NULL, /* szLpqcommand */ - NULL, /* szLprmcommand */ - NULL, /* szLppausecommand */ - NULL, /* szLpresumecommand */ - NULL, /* szQueuepausecommand */ - NULL, /* szQueueresumecommand */ - NULL, /* szPrintername */ - NULL, /* szPrinterDriver - this is set in init_globals() */ - NULL, /* szPrinterDriverLocation */ - NULL, /* szDontdescend */ - NULL, /* szHostsallow */ - NULL, /* szHostsdeny */ - NULL, /* szMagicScript */ - NULL, /* szMagicOutput */ - NULL, /* szMangledMap */ - NULL, /* szVetoFiles */ - NULL, /* szHideFiles */ - NULL, /* szVetoOplockFiles */ - NULL, /* comment */ - NULL, /* force user */ - NULL, /* force group */ - NULL, /* readlist */ - NULL, /* writelist */ - NULL, /* volume */ - NULL, /* fstype */ - 0, /* iMinPrintSpace */ - 0744, /* iCreate_mask */ - 0000, /* iCreate_force_mode */ - 0755, /* iDir_mask */ - 0000, /* iDir_force_mode */ - 0, /* iMaxConnections */ - CASE_LOWER, /* iDefaultCase */ - DEFAULT_PRINTING, /* iPrinting */ - 2, /* iOplockContentionLimit */ - False, /* bAlternatePerm */ - False, /* revalidate */ - False, /* case sensitive */ - True, /* case preserve */ - True, /* short case preserve */ - False, /* case mangle */ - True, /* status */ - True, /* bHideDotFiles */ - True, /* bBrowseable */ - True, /* bAvailable */ - True, /* bRead_only */ - True, /* bNo_set_dir */ - False, /* bGuest_only */ - False, /* bGuest_ok */ - False, /* bPrint_ok */ - False, /* bPostscript */ - False, /* bMap_system */ - False, /* bMap_hidden */ - True, /* bMap_archive */ - True, /* bLocking */ - False, /* bStrictLocking */ - True, /* bShareModes */ - True, /* bOpLocks */ - False, /* bOnlyUser */ - True, /* bMangledNames */ - True, /* bWidelinks */ - True, /* bSymlinks */ - False, /* bSyncAlways */ - False, /* bStrictSync */ - '~', /* magic char */ - NULL, /* copymap */ - False, /* bDeleteReadonly */ - False, /* bFakeOplocks */ - False, /* bDeleteVetoFiles */ - False, /* bDosFiletimes */ - False, /* bDosFiletimeResolution */ - False, /* bFakeDirCreateTimes */ - True, /* bBlockingLocks */ - True, /* bMangleLocks */ - "" /* dummy */ -}; - - - -/* local variables */ -static service **ServicePtrs = NULL; -static int iNumServices = 0; -static int iServiceIndex = 0; -static BOOL bInGlobalSection = True; -static BOOL bGlobalOnly = False; -#if 0 -static int default_server_announce; -#endif /* 0 */ -#define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct)) - -/* prototypes for the special type handlers */ -static BOOL handle_valid_chars(const char *pszParmValue, char **ptr); -static BOOL handle_include(const char *pszParmValue, char **ptr); -static BOOL handle_copy(const char *pszParmValue, char **ptr); -static BOOL handle_character_set(const char *pszParmValue,char **ptr); -static BOOL handle_coding_system(const char *pszParmValue,char **ptr); -#if 0 -static void set_default_server_announce_type(void); -#endif /* 0 */ -static struct enum_list const enum_protocol[] = {{PROTOCOL_NT1, "NT1"}, {PROTOCOL_LANMAN2, "LANMAN2"}, - {PROTOCOL_LANMAN1, "LANMAN1"}, {PROTOCOL_CORE,"CORE"}, - {PROTOCOL_COREPLUS, "COREPLUS"}, - {PROTOCOL_COREPLUS, "CORE+"}, {-1, NULL}}; - -static struct enum_list const enum_security[] = {{SEC_SHARE, "SHARE"}, {SEC_USER, "USER"}, - {SEC_SERVER, "SERVER"}, {SEC_DOMAIN, "DOMAIN"}, - {-1, NULL}}; - -static struct enum_list const enum_printing[] = {{PRINT_SYSV, "sysv"}, {PRINT_AIX, "aix"}, - {PRINT_HPUX, "hpux"}, {PRINT_BSD, "bsd"}, - {PRINT_QNX, "qnx"}, {PRINT_PLP, "plp"}, - {PRINT_LPRNG, "lprng"}, {PRINT_SOFTQ, "softq"}, - {-1, NULL}}; - -/* Types of machine we can announce as. */ -#define ANNOUNCE_AS_NT_SERVER 1 -#define ANNOUNCE_AS_WIN95 2 -#define ANNOUNCE_AS_WFW 3 -#define ANNOUNCE_AS_NT_WORKSTATION 4 - -static struct enum_list const enum_announce_as[] = {{ANNOUNCE_AS_NT_SERVER, "NT"}, {ANNOUNCE_AS_NT_SERVER, "NT Server"}, {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"}, {ANNOUNCE_AS_WIN95, "win95"}, {ANNOUNCE_AS_WFW, "WfW"}, {-1, NULL}}; - -static struct enum_list const enum_case[] = {{CASE_LOWER, "lower"}, {CASE_UPPER, "upper"}, {-1, NULL}}; - -static struct enum_list const enum_lm_announce[] = {{0, "False"}, {1, "True"}, {2, "Auto"}, {-1, NULL}}; - -/* - Do you want session setups at user level security with a invalid - password to be rejected or allowed in as guest? WinNT rejects them - but it can be a pain as it means "net view" needs to use a password - - You have 3 choices in the setting of map_to_guest: - - "Never" means session setups with an invalid password - are rejected. This is the default. - - "Bad User" means session setups with an invalid password - are rejected, unless the username does not exist, in which case it - is treated as a guest login - - "Bad Password" means session setups with an invalid password - are treated as a guest login - - Note that map_to_guest only has an effect in user or server - level security. -*/ - -static struct enum_list const enum_map_to_guest[] = {{NEVER_MAP_TO_GUEST, "Never"}, {MAP_TO_GUEST_ON_BAD_USER, "Bad User"}, {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"}, {-1, NULL}}; - -#ifdef WITH_SSL -static struct enum_list const enum_ssl_version[] = {{SMB_SSL_V2, "ssl2"}, {SMB_SSL_V3, "ssl3"}, - {SMB_SSL_V23, "ssl2or3"}, {SMB_SSL_TLS1, "tls1"}, {-1, NULL}}; -#endif - -#define PARM_SEPARATOR(label) {label, P_SEP, P_SEPARATOR, NULL, NULL, NULL, 0, {0}} -/* note that we do not initialise the defaults union - it is not allowed in ANSI C */ -static struct parm_struct parm_table[] = -{ - PARM_SEPARATOR("Base Options"), - {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC|FLAG_SHARE|FLAG_PRINT, {0}}, - {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC|FLAG_SHARE|FLAG_PRINT, {0}}, - {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, 0, {0}}, - {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkGroup, NULL, NULL, FLAG_BASIC, {0}}, - {"netbios name", P_UGSTRING,P_GLOBAL, global_myname, NULL, NULL, FLAG_BASIC, {0}}, - {"netbios aliases", P_STRING, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, 0, {0}}, - {"netbios scope", P_UGSTRING,P_GLOBAL, global_scope, NULL, NULL, 0, {0}}, - {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC, {0}}, - {"interfaces", P_STRING, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC, {0}}, - {"bind interfaces only", P_BOOL,P_GLOBAL, &Globals.bBindInterfacesOnly,NULL, NULL, 0, {0}}, - - PARM_SEPARATOR("Security Options"), - {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC, {0}}, - {"encrypt passwords",P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC, {0}}, - {"update encrypted", P_BOOL, P_GLOBAL, &Globals.bUpdateEncrypt, NULL, NULL, FLAG_BASIC, {0}}, - {"allow trusted domains",P_BOOL,P_GLOBAL, &Globals.bAllowTrustedDomains,NULL, NULL, 0, {0}}, - {"alternate permissions",P_BOOL,P_LOCAL, &sDefault.bAlternatePerm, NULL, NULL, FLAG_GLOBAL|FLAG_DEPRECATED, {0}}, - {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, 0, {0}}, - {"min passwd length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, 0, {0}}, - {"min password length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, 0, {0}}, - {"map to guest", P_ENUM, P_GLOBAL, &Globals.map_to_guest, NULL, enum_map_to_guest, 0, {0}}, - {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, 0, {0}}, - {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, 0, {0}}, - {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, 0, {0}}, - {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0, {0}}, - {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0, {0}}, - {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0, {0}}, - {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, 0, {0}}, - {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, 0, {0}}, - {"passwd chat debug",P_BOOL, P_GLOBAL, &Globals.bPasswdChatDebug, NULL, NULL, 0, {0}}, - {"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL, NULL, 0, {0}}, - {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, 0, {0}}, - {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, 0, {0}}, - {"unix password sync", P_BOOL, P_GLOBAL, &Globals.bUnixPasswdSync, NULL, NULL, 0, {0}}, - {"restrict anonymous", P_BOOL, P_GLOBAL, &Globals.bRestrictAnonymous,NULL, NULL, 0, {0}}, - {"revalidate", P_BOOL, P_LOCAL, &sDefault.bRevalidate, NULL, NULL, FLAG_GLOBAL|FLAG_SHARE, {0}}, - {"use rhosts", P_BOOL, P_GLOBAL, &Globals.bUseRhosts, NULL, NULL, 0, {0}}, - {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_GLOBAL|FLAG_SHARE, {0}}, - {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, 0, {0}}, - {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, 0, {0}}, - {"guest account", P_STRING, P_LOCAL, &sDefault.szGuestaccount, NULL, NULL, FLAG_BASIC|FLAG_SHARE|FLAG_PRINT|FLAG_GLOBAL, {0}}, - {"invalid users", P_STRING, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_GLOBAL|FLAG_SHARE, {0}}, - {"valid users", P_STRING, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_GLOBAL|FLAG_SHARE, {0}}, - {"admin users", P_STRING, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_GLOBAL|FLAG_SHARE, {0}}, - {"read list", P_STRING, P_LOCAL, &sDefault.readlist, NULL, NULL, FLAG_GLOBAL|FLAG_SHARE, {0}}, - {"write list", P_STRING, P_LOCAL, &sDefault.writelist, NULL, NULL, FLAG_GLOBAL|FLAG_SHARE, {0}}, - {"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL, NULL, FLAG_SHARE, {0}}, - {"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_SHARE, {0}}, - {"group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, 0, {0}}, - {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC|FLAG_SHARE, {0}}, - {"write ok", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0, {0}}, - {"writeable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0, {0}}, - {"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0, {0}}, - {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_GLOBAL|FLAG_SHARE, {0}}, - {"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_GLOBAL, {0}}, - {"force create mode",P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL, NULL, FLAG_GLOBAL|FLAG_SHARE, {0}}, - {"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_GLOBAL|FLAG_SHARE, {0}}, - {"directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_GLOBAL, {0}}, - {"force directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_force_mode, NULL, NULL, FLAG_GLOBAL|FLAG_SHARE, {0}}, - {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_SHARE, {0}}, - {"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, 0, {0}}, - {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC|FLAG_SHARE|FLAG_PRINT, {0}}, - {"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, 0, {0}}, - {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, FLAG_SHARE, {0}}, - {"hosts allow", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL|FLAG_BASIC|FLAG_SHARE|FLAG_PRINT, {0}}, - {"allow hosts", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, 0, {0}}, - {"hosts deny", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL|FLAG_BASIC|FLAG_SHARE|FLAG_PRINT, {0}}, - {"deny hosts", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, 0, {0}}, - -#ifdef WITH_SSL - PARM_SEPARATOR("Secure Socket Layer Options"), - {"ssl", P_BOOL, P_GLOBAL, &Globals.sslEnabled, NULL, NULL, 0 , {0}}, - {"ssl hosts", P_STRING, P_GLOBAL, &Globals.sslHostsRequire, NULL, NULL, 0 , {0}}, - {"ssl hosts resign", P_STRING, P_GLOBAL, &Globals.sslHostsResign, NULL, NULL, 0} , - {"ssl CA certDir", P_STRING, P_GLOBAL, &Globals.sslCaCertDir, NULL, NULL, 0 , {0}}, - {"ssl CA certFile", P_STRING, P_GLOBAL, &Globals.sslCaCertFile, NULL, NULL, 0 , {0}}, - {"ssl server cert", P_STRING, P_GLOBAL, &Globals.sslCert, NULL, NULL, 0 , {0}}, - {"ssl server key", P_STRING, P_GLOBAL, &Globals.sslPrivKey, NULL, NULL, 0 , {0}}, - {"ssl client cert", P_STRING, P_GLOBAL, &Globals.sslClientCert, NULL, NULL, 0 , {0}}, - {"ssl client key", P_STRING, P_GLOBAL, &Globals.sslClientPrivKey, NULL, NULL, 0 , {0}}, - {"ssl require clientcert", P_BOOL, P_GLOBAL, &Globals.sslReqClientCert, NULL, NULL , 0, {0}}, - {"ssl require servercert", P_BOOL, P_GLOBAL, &Globals.sslReqServerCert, NULL, NULL , 0, {0}}, - {"ssl ciphers", P_STRING, P_GLOBAL, &Globals.sslCiphers, NULL, NULL, 0 , {0}}, - {"ssl version", P_ENUM, P_GLOBAL, &Globals.sslVersion, NULL, enum_ssl_version, 0, {0}}, - {"ssl compatibility", P_BOOL, P_GLOBAL, &Globals.sslCompatibility, NULL, NULL, 0 , {0}}, -#endif /* WITH_SSL */ - - PARM_SEPARATOR("Logging Options"), - {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_BASIC, {0}}, - {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, 0, {0}}, - {"syslog", P_INTEGER, P_GLOBAL, &Globals.syslog, NULL, NULL, 0, {0}}, - {"syslog only", P_BOOL, P_GLOBAL, &Globals.bSyslogOnly, NULL, NULL, 0, {0}}, - {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, 0, {0}}, - {"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL, NULL, 0, {0}}, - {"timestamp logs", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, 0, {0}}, - {"debug timestamp", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, 0, {0}}, - {"status", P_BOOL, P_LOCAL, &sDefault.status, NULL, NULL, FLAG_GLOBAL|FLAG_SHARE|FLAG_PRINT, {0}}, - - PARM_SEPARATOR("Protocol Options"), - {"protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, 0, {0}}, - {"read bmpx", P_BOOL, P_GLOBAL, &Globals.bReadbmpx, NULL, NULL, 0, {0}}, - {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, 0, {0}}, - {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, 0, {0}}, - {"nt smb support", P_BOOL, P_GLOBAL, &Globals.bNTSmbSupport, NULL, NULL, 0, {0}}, - {"nt pipe support", P_BOOL, P_GLOBAL, &Globals.bNTPipeSupport, NULL, NULL, 0, {0}}, - {"nt acl support", P_BOOL, P_GLOBAL, &Globals.bNTAclSupport, NULL, NULL, 0, {0}}, - {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, 0, {0}}, - {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, 0, {0}}, - {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, 0, {0}}, - {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, 0, {0}}, - {"name resolve order",P_STRING, P_GLOBAL, &Globals.szNameResolveOrder,NULL, NULL, 0, {0}}, - {"max packet", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL, NULL, 0, {0}}, - {"packet size", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL, NULL, 0, {0}}, - {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, 0, {0}}, - {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, 0, {0}}, - {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, 0, {0}}, - {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, 0, {0}}, - - PARM_SEPARATOR("Tuning Options"), - {"change notify timeout", P_INTEGER, P_GLOBAL, &Globals.change_notify_timeout, NULL, NULL, 0, {0}}, - {"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL, NULL, 0, {0}}, - {"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL, NULL, 0, {0}}, - {"keepalive", P_INTEGER, P_GLOBAL, &keepalive, NULL, NULL, 0, {0}}, - {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, 0, {0}}, - {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_SHARE, {0}}, - {"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL, NULL, 0, {0}}, - {"max open files", P_INTEGER, P_GLOBAL, &Globals.max_open_files, NULL, NULL, 0, {0}}, - {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, FLAG_PRINT, {0}}, - {"read prediction", P_BOOL, P_GLOBAL, &Globals.bReadPrediction, NULL, NULL, 0, {0}}, - {"read size", P_INTEGER, P_GLOBAL, &Globals.ReadSize, NULL, NULL, 0, {0}}, - {"shared mem size", P_INTEGER, P_GLOBAL, &Globals.shmem_size, NULL, NULL, 0, {0}}, - {"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL, NULL, 0, {0}}, - {"stat cache size", P_INTEGER, P_GLOBAL, &Globals.stat_cache_size, NULL, NULL, 0, {0}}, - {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_SHARE, {0}}, - {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL, NULL, FLAG_SHARE, {0}}, - - PARM_SEPARATOR("Printing Options"), - {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, FLAG_PRINT, {0}}, - {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_PRINT, {0}}, - {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, 0, {0}}, - {"printer driver file", P_STRING, P_GLOBAL, &Globals.szDriverFile, NULL, NULL, FLAG_PRINT, {0}}, - {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_PRINT, {0}}, - {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, 0, {0}}, - {"postscript", P_BOOL, P_LOCAL, &sDefault.bPostscript, NULL, NULL, FLAG_PRINT, {0}}, - {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, NULL, enum_printing, FLAG_PRINT|FLAG_GLOBAL, {0}}, - {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_PRINT|FLAG_GLOBAL, {0}}, - {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_PRINT|FLAG_GLOBAL, {0}}, - {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_PRINT|FLAG_GLOBAL, {0}}, - {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_PRINT|FLAG_GLOBAL, {0}}, - {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand,NULL, NULL, FLAG_PRINT|FLAG_GLOBAL, {0}}, - {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_PRINT|FLAG_GLOBAL, {0}}, - {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_PRINT|FLAG_GLOBAL, {0}}, - - {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT, {0}}, - {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, 0, {0}}, - {"printer driver", P_STRING, P_LOCAL, &sDefault.szPrinterDriver, NULL, NULL, FLAG_PRINT, {0}}, - {"printer driver location", P_STRING, P_LOCAL, &sDefault.szPrinterDriverLocation, NULL, NULL, FLAG_PRINT|FLAG_GLOBAL, {0}}, - - - PARM_SEPARATOR("Filename Handling"), - {"strip dot", P_BOOL, P_GLOBAL, &Globals.bStripDot, NULL, NULL, 0, {0}}, - {"character set", P_STRING, P_GLOBAL, &Globals.szCharacterSet, handle_character_set, NULL, 0, {0}}, - {"mangled stack", P_INTEGER, P_GLOBAL, &Globals.mangled_stack, NULL, NULL, 0, {0}}, - {"coding system", P_STRING, P_GLOBAL, &Globals.szCodingSystem, handle_coding_system, NULL, 0, {0}}, - {"client code page", P_INTEGER, P_GLOBAL, &Globals.client_code_page, NULL, NULL, 0, {0}}, - {"default case", P_ENUM, P_LOCAL, &sDefault.iDefaultCase, NULL, enum_case, FLAG_SHARE, {0}}, - {"case sensitive", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL, {0}}, - {"casesignames", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, 0, {0}}, - {"preserve case", P_BOOL, P_LOCAL, &sDefault.bCasePreserve, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL, {0}}, - {"short preserve case",P_BOOL, P_LOCAL, &sDefault.bShortCasePreserve,NULL, NULL, FLAG_SHARE|FLAG_GLOBAL, {0}}, - {"mangle case", P_BOOL, P_LOCAL, &sDefault.bCaseMangle, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL, {0}}, - {"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL, {0}}, - {"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL, {0}}, - {"delete veto files",P_BOOL, P_LOCAL, &sDefault.bDeleteVetoFiles, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL, {0}}, - {"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL, {0}}, - {"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL, {0}}, - {"veto oplock files",P_STRING, P_LOCAL, &sDefault.szVetoOplockFiles,NULL, NULL, FLAG_SHARE|FLAG_GLOBAL, {0}}, - {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL, {0}}, - {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL, {0}}, - {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL, {0}}, - {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL, {0}}, - {"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL, {0}}, - {"stat cache", P_BOOL, P_GLOBAL, &Globals.bStatCache, NULL, NULL, 0, {0}}, - - PARM_SEPARATOR("Domain Options"), - {"domain groups", P_STRING, P_GLOBAL, &Globals.szDomainGroups, NULL, NULL, 0, {0}}, - {"domain admin group",P_STRING, P_GLOBAL, &Globals.szDomainAdminGroup, NULL, NULL, 0, {0}}, - {"domain guest group",P_STRING, P_GLOBAL, &Globals.szDomainGuestGroup, NULL, NULL, 0, {0}}, - {"domain admin users",P_STRING, P_GLOBAL, &Globals.szDomainAdminUsers, NULL, NULL, 0, {0}}, - {"domain guest users",P_STRING, P_GLOBAL, &Globals.szDomainGuestUsers, NULL, NULL, 0, {0}}, -#ifdef USING_GROUPNAME_MAP - {"groupname map", P_STRING, P_GLOBAL, &Globals.szGroupnameMap, NULL, NULL, 0, {0}}, -#endif /* USING_GROUPNAME_MAP */ - {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, 0, {0}}, - - PARM_SEPARATOR("Logon Options"), - {"add user script", P_STRING, P_GLOBAL, &Globals.szAddUserScript, NULL, NULL, 0, {0}}, - {"delete user script",P_STRING, P_GLOBAL, &Globals.szDelUserScript, NULL, NULL, 0, {0}}, - {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, 0, {0}}, - {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, 0, {0}}, - {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, 0, {0}}, - {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, 0, {0}}, - {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, 0, {0}}, - - PARM_SEPARATOR("Browse Options"), - {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC, {0}}, - {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_lm_announce, 0, {0}}, - {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, 0, {0}}, - {"preferred master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL, NULL, FLAG_BASIC, {0}}, - {"prefered master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL, NULL, 0, {0}}, - {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC, {0}}, - {"domain master", P_BOOL, P_GLOBAL, &Globals.bDomainMaster, NULL, NULL, FLAG_BASIC, {0}}, - {"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL, NULL, 0, {0}}, - {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC|FLAG_SHARE|FLAG_PRINT, {0}}, - {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, 0, {0}}, - - PARM_SEPARATOR("WINS Options"), - {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, 0, {0}}, - {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, 0, {0}}, - {"wins server", P_STRING, P_GLOBAL, &Globals.szWINSserver, NULL, NULL, FLAG_BASIC, {0}}, - {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC, {0}}, - - PARM_SEPARATOR("Locking Options"), - {"blocking locks", P_BOOL, P_LOCAL, &sDefault.bBlockingLocks, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL, {0}}, - {"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL, NULL, FLAG_SHARE, {0}}, - {"kernel oplocks", P_BOOL, P_GLOBAL, &Globals.bKernelOplocks, NULL, NULL, FLAG_GLOBAL, {0}}, - {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL, {0}}, - {"mangle locks", P_BOOL, P_LOCAL, &sDefault.bMangleLocks, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL, {0}}, - {"ole locking compatibility", P_BOOL, P_GLOBAL, &Globals.bOleLockingCompat, NULL, NULL, FLAG_GLOBAL, {0}}, - {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL, {0}}, - {"oplock break wait time",P_INTEGER,P_GLOBAL,&Globals.oplock_break_wait_time,NULL,NULL,FLAG_GLOBAL, {0}}, - {"oplock contention limit",P_INTEGER,P_LOCAL,&sDefault.iOplockContentionLimit,NULL,NULL,FLAG_SHARE|FLAG_GLOBAL, {0}}, - {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL, {0}}, - {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL, {0}}, - -#ifdef WITH_LDAP - PARM_SEPARATOR("Ldap Options"), - {"ldap server", P_STRING, P_GLOBAL, &Globals.szLdapServer, NULL, NULL, 0, {0}}, - {"ldap port", P_INTEGER, P_GLOBAL, &Globals.ldap_port, NULL, NULL, 0, {0}}, - {"ldap suffix", P_STRING, P_GLOBAL, &Globals.szLdapSuffix, NULL, NULL, 0, {0}}, - {"ldap filter", P_STRING, P_GLOBAL, &Globals.szLdapFilter, NULL, NULL, 0, {0}}, - {"ldap root", P_STRING, P_GLOBAL, &Globals.szLdapRoot, NULL, NULL, 0, {0}}, - {"ldap root passwd", P_STRING, P_GLOBAL, &Globals.szLdapRootPassword,NULL, NULL, 0, {0}}, -#endif /* WITH_LDAP */ - - - PARM_SEPARATOR("Miscellaneous Options"), - {"smbrun", P_STRING, P_GLOBAL, &Globals.szSmbrun, NULL, NULL, 0, {0}}, - {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE, {0}}, - {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, 0, {0}}, - {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, 0, {0}}, - {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, 0, {0}}, - {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, 0, {0}}, - {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, 0, {0}}, - {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, 0, {0}}, - {"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL, NULL, 0, {0}}, - {"dfree command", P_STRING, P_GLOBAL, &Globals.szDfree, NULL, NULL, 0, {0}}, - {"valid chars", P_STRING, P_GLOBAL, &Globals.szValidChars, handle_valid_chars, NULL, 0, {0}}, - {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, 0, {0}}, - {"remote browse sync",P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync,NULL, NULL, 0, {0}}, - {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, 0, {0}}, - {"homedir map", P_STRING, P_GLOBAL, &Globals.szNISHomeMapName, NULL, NULL, 0, {0}}, - {"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL, NULL, 0, {0}}, - {"unix realname", P_BOOL, P_GLOBAL, &Globals.bUnixRealname, NULL, NULL, 0, {0}}, - {"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL, NULL, 0, {0}}, - {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE, {0}}, - {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE, {0}}, - {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE, {0}}, - {"exec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, FLAG_SHARE|FLAG_PRINT, {0}}, - {"preexec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, 0, {0}}, - {"postexec", P_STRING, P_LOCAL, &sDefault.szPostExec, NULL, NULL, FLAG_SHARE|FLAG_PRINT, {0}}, - {"root preexec", P_STRING, P_LOCAL, &sDefault.szRootPreExec, NULL, NULL, FLAG_SHARE|FLAG_PRINT, {0}}, - {"root postexec", P_STRING, P_LOCAL, &sDefault.szRootPostExec, NULL, NULL, FLAG_SHARE|FLAG_PRINT, {0}}, - {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC|FLAG_SHARE|FLAG_PRINT, {0}}, - {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_SHARE, {0}}, - {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_SHARE, {0}}, - {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL, NULL, FLAG_SHARE, {0}}, - {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL, {0}}, - {"follow symlinks", P_BOOL, P_LOCAL, &sDefault.bSymlinks, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL, {0}}, - {"dont descend", P_STRING, P_LOCAL, &sDefault.szDontdescend, NULL, NULL, FLAG_SHARE, {0}}, - {"magic script", P_STRING, P_LOCAL, &sDefault.szMagicScript, NULL, NULL, FLAG_SHARE, {0}}, - {"magic output", P_STRING, P_LOCAL, &sDefault.szMagicOutput, NULL, NULL, FLAG_SHARE, {0}}, - {"delete readonly", P_BOOL, P_LOCAL, &sDefault.bDeleteReadonly, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL, {0}}, - {"dos filetimes", P_BOOL, P_LOCAL, &sDefault.bDosFiletimes, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL, {0}}, - {"dos filetime resolution",P_BOOL,P_LOCAL,&sDefault.bDosFiletimeResolution, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL, {0}}, - - {"fake directory create times", P_BOOL,P_LOCAL, &sDefault.bFakeDirCreateTimes, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL, {0}}, - {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, 0, {0}}, - - {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0, {0}} -}; - - - -/*************************************************************************** -Initialise the global parameter structure. -***************************************************************************/ -static void init_globals(void) -{ - static BOOL done_init = False; - pstring s; - - if (!done_init) - { - int i; - memset((void *)&Globals,'\0',sizeof(Globals)); - - for (i = 0; parm_table[i].label; i++) - if ((parm_table[i].type == P_STRING || - parm_table[i].type == P_USTRING) && - parm_table[i].ptr) - string_init(parm_table[i].ptr,""); - - string_set(&sDefault.szGuestaccount, GUEST_ACCOUNT); - string_set(&sDefault.szPrinterDriver, "NULL"); - string_set(&sDefault.fstype, FSTYPE_STRING); - - done_init = True; - } - - - DEBUG(3,("Initialising global parameters\n")); - - string_set(&Globals.szWorkGroup, WORKGROUP); - string_set(&Globals.szPrintcapname, PRINTCAP_NAME); - string_set(&Globals.szDriverFile, DRIVERFILE); - string_set(&Globals.szRootdir, "/"); - string_set(&Globals.szSocketAddress, "0.0.0.0"); - string_set(&Globals.szServerString, "Samba " VERSION); - slprintf(s,sizeof(s)-1, "%d.%d", DEFAULT_MAJOR_VERSION, DEFAULT_MINOR_VERSION); - string_set(&Globals.szAnnounceVersion,s); - - pstrcpy(user_socket_options, DEFAULT_SOCKET_OPTIONS); - - string_set(&Globals.szLogonDrive, ""); - /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */ - string_set(&Globals.szLogonHome, "\\\\%N\\%U"); - string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile"); - - string_set(&Globals.szNameResolveOrder, "lmhosts host wins bcast"); - - Globals.bLoadPrinters = True; - Globals.bUseRhosts = False; - Globals.max_packet = 65535; - Globals.mangled_stack = 50; - Globals.max_xmit = 65535; - Globals.max_mux = 50; /* This is *needed* for profile support. */ - Globals.lpqcachetime = 10; - Globals.pwordlevel = 0; - Globals.unamelevel = 0; - Globals.deadtime = 0; - Globals.max_log_size = 5000; - Globals.max_open_files = MAX_OPEN_FILES; - Globals.maxprotocol = PROTOCOL_NT1; - Globals.security = SEC_USER; - Globals.bEncryptPasswords = False; - Globals.bUpdateEncrypt = False; - Globals.bReadRaw = True; - Globals.bWriteRaw = True; - Globals.bReadPrediction = False; - Globals.bReadbmpx = False; - Globals.bNullPasswords = False; - Globals.bStripDot = False; - Globals.syslog = 1; - Globals.bSyslogOnly = False; - Globals.bTimestampLogs = True; - Globals.os_level = 0; - Globals.max_ttl = 60*60*24*3; /* 3 days default. */ - Globals.max_wins_ttl = 60*60*24*6; /* 6 days default. */ - Globals.min_wins_ttl = 60*60*6; /* 6 hours default. */ - Globals.machine_password_timeout = 60*60*24*7; /* 7 days default. */ - Globals.change_notify_timeout = 60; /* 1 minute default. */ - Globals.ReadSize = 16*1024; - Globals.lm_announce = 2; /* = Auto: send only if LM clients found */ - Globals.lm_interval = 60; - Globals.shmem_size = SHMEM_SIZE; - Globals.stat_cache_size = 50; /* Number of stat translations we'll keep */ - Globals.announce_as = ANNOUNCE_AS_NT_SERVER; - Globals.bUnixRealname = False; -#if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT)) - Globals.bNISHomeMap = False; -#ifdef WITH_NISPLUS_HOME - string_set(&Globals.szNISHomeMapName, "auto_home.org_dir"); -#else - string_set(&Globals.szNISHomeMapName, "auto.home"); -#endif -#endif - Globals.client_code_page = DEFAULT_CLIENT_CODE_PAGE; - Globals.bTimeServer = False; - Globals.bBindInterfacesOnly = False; - Globals.bUnixPasswdSync = False; - Globals.bPasswdChatDebug = False; - Globals.bOleLockingCompat = True; - Globals.bNTSmbSupport = True; /* Do NT SMB's by default. */ - Globals.bNTPipeSupport = True; /* Do NT pipes by default. */ - Globals.bNTAclSupport = True; /* Use NT ACLs by default. */ - Globals.bStatCache = True; /* use stat cache by default */ - Globals.bRestrictAnonymous = False; - Globals.map_to_guest = 0; /* By Default, "Never" */ - Globals.min_passwd_length = MINPASSWDLENGTH; /* By Default, 5. */ - Globals.oplock_break_wait_time = 10; /* By Default, 10 msecs. */ - -#ifdef WITH_LDAP - /* default values for ldap */ - string_set(&Globals.szLdapServer, "localhost"); - Globals.ldap_port=389; -#endif /* WITH_LDAP */ - -#ifdef WITH_SSL - Globals.sslVersion = SMB_SSL_V23; - string_set(&Globals.sslHostsRequire, ""); - string_set(&Globals.sslHostsResign, ""); - string_set(&Globals.sslCaCertDir, ""); - string_set(&Globals.sslCaCertFile, ""); - string_set(&Globals.sslCert, ""); - string_set(&Globals.sslPrivKey, ""); - string_set(&Globals.sslClientCert, ""); - string_set(&Globals.sslClientPrivKey, ""); - string_set(&Globals.sslCiphers, ""); - Globals.sslEnabled = False; - Globals.sslReqClientCert = False; - Globals.sslReqServerCert = False; - Globals.sslCompatibility = False; -#endif /* WITH_SSL */ - -/* these parameters are set to defaults that are more appropriate - for the increasing samba install base: - - as a member of the workgroup, that will possibly become a - _local_ master browser (lm = True). this is opposed to a forced - local master browser startup (pm = True). - - doesn't provide WINS server service by default (wsupp = False), - and doesn't provide domain master browser services by default, either. - -*/ - - Globals.bPreferredMaster = False; - Globals.bLocalMaster = True; - Globals.bDomainMaster = False; - Globals.bDomainLogons = False; - Globals.bBrowseList = True; - Globals.bWINSsupport = False; - Globals.bWINSproxy = False; - - Globals.bDNSproxy = True; - - /* - * smbd will check at runtime to see if this value - * will really be used or not. - */ - Globals.bKernelOplocks = True; - - Globals.bAllowTrustedDomains = True; - - /* - * This must be done last as it checks the value in - * client_code_page. - */ - - interpret_coding_system(KANJI); -} - -#if 0 -/*************************************************************************** -check if a string is initialised and if not then initialise it -***************************************************************************/ -static void string_initial(char **s,char *v) -{ - if (!*s || !**s) - string_init(s,v); -} - -#else -#define init_locals() -#endif /* 0 */ - -static size_t size_max(size_t a, size_t b) -{ - return (a > b) ? a : b; -} - -/******************************************************************* a -convenience routine to grab string parameters into a rotating buffer, -and run standard_sub_basic on them. The buffers can be written to by -callers without affecting the source string. -********************************************************************/ -static char *lp_string(const char *s) -{ - static char *bufs[10]; - static int buflen[10]; - static int next = -1; - char *ret; - int i; - int len = s?strlen(s):0; - - if (next == -1) { - /* initialisation */ - for (i=0;i<10;i++) { - bufs[i] = NULL; - buflen[i] = 0; - } - next = 0; - } - - len = size_max(len+100,sizeof(pstring)); /* the +100 is for some - substitution room */ - - if (buflen[next] != len) { - buflen[next] = len; - if (bufs[next]) free(bufs[next]); - bufs[next] = (char *)malloc(len); - if (!bufs[next]) { - DEBUG(0,("out of memory in lp_string()")); - exit(1); - } - } - - ret = &bufs[next][0]; - next = (next+1)%10; - - if (!s) - *ret = 0; - else - StrCpy(ret,s); - - trim_string(ret, "\"", "\""); - - standard_sub_basic(ret); - return(ret); -} - - -/* - In this section all the functions that are used to access the - parameters from the rest of the program are defined -*/ - -#define FN_GLOBAL_STRING(fn_name,ptr) \ - char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));} -#define FN_GLOBAL_BOOL(fn_name,ptr) \ - BOOL fn_name(void) {return(*(BOOL *)(ptr));} -#define FN_GLOBAL_CHAR(fn_name,ptr) \ - char fn_name(void) {return(*(char *)(ptr));} -#define FN_GLOBAL_INTEGER(fn_name,ptr) \ - int fn_name(void) {return(*(int *)(ptr));} - -#define FN_LOCAL_STRING(fn_name,val) \ - char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i)&&pSERVICE(i)->val)?pSERVICE(i)->val : sDefault.val));} -#define FN_LOCAL_BOOL(fn_name,val) \ - BOOL fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);} -#define FN_LOCAL_CHAR(fn_name,val) \ - char fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);} -#define FN_LOCAL_INTEGER(fn_name,val) \ - int fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);} - -FN_GLOBAL_STRING(lp_logfile,&Globals.szLogFile) -FN_GLOBAL_STRING(lp_configfile,&Globals.szConfigFile) -FN_GLOBAL_STRING(lp_serverstring,&Globals.szServerString) -FN_GLOBAL_STRING(lp_printcapname,&Globals.szPrintcapname) -FN_GLOBAL_STRING(lp_lockdir,&Globals.szLockDir) -FN_GLOBAL_STRING(lp_rootdir,&Globals.szRootdir) -FN_GLOBAL_STRING(lp_defaultservice,&Globals.szDefaultService) -FN_GLOBAL_STRING(lp_msg_command,&Globals.szMsgCommand) -FN_GLOBAL_STRING(lp_hosts_equiv,&Globals.szHostsEquiv) -FN_GLOBAL_STRING(lp_auto_services,&Globals.szAutoServices) -FN_GLOBAL_STRING(lp_passwordserver,&Globals.szPasswordServer) -FN_GLOBAL_STRING(lp_name_resolve_order,&Globals.szNameResolveOrder) -FN_GLOBAL_STRING(lp_workgroup,&Globals.szWorkGroup) -FN_GLOBAL_STRING(lp_username_map,&Globals.szUsernameMap) -#ifdef USING_GROUPNAME_MAP -FN_GLOBAL_STRING(lp_groupname_map,&Globals.szGroupnameMap) -#endif /* USING_GROUPNAME_MAP */ -FN_GLOBAL_STRING(lp_remote_announce,&Globals.szRemoteAnnounce) -FN_GLOBAL_STRING(lp_remote_browse_sync,&Globals.szRemoteBrowseSync) -FN_GLOBAL_STRING(lp_wins_server,&Globals.szWINSserver) -FN_GLOBAL_STRING(lp_interfaces,&Globals.szInterfaces) -FN_GLOBAL_STRING(lp_socket_address,&Globals.szSocketAddress) -FN_GLOBAL_STRING(lp_nis_home_map_name,&Globals.szNISHomeMapName) -#if 0 -static FN_GLOBAL_STRING(lp_announce_version,&Globals.szAnnounceVersion) -#endif /* 0 */ -FN_GLOBAL_STRING(lp_netbios_aliases,&Globals.szNetbiosAliases) -FN_GLOBAL_STRING(lp_driverfile,&Globals.szDriverFile) -FN_GLOBAL_STRING(lp_panic_action,&Globals.szPanicAction) -FN_GLOBAL_STRING(lp_domain_groups,&Globals.szDomainGroups) -FN_GLOBAL_STRING(lp_domain_admin_group,&Globals.szDomainAdminGroup) -FN_GLOBAL_STRING(lp_domain_guest_group,&Globals.szDomainGuestGroup) -FN_GLOBAL_STRING(lp_domain_admin_users,&Globals.szDomainAdminUsers) -FN_GLOBAL_STRING(lp_domain_guest_users,&Globals.szDomainGuestUsers) - -#ifdef WITH_LDAP -FN_GLOBAL_STRING(lp_ldap_server,&Globals.szLdapServer); -FN_GLOBAL_STRING(lp_ldap_suffix,&Globals.szLdapSuffix); -FN_GLOBAL_STRING(lp_ldap_filter,&Globals.szLdapFilter); -FN_GLOBAL_STRING(lp_ldap_root,&Globals.szLdapRoot); -FN_GLOBAL_STRING(lp_ldap_rootpasswd,&Globals.szLdapRootPassword); -#endif /* WITH_LDAP */ - -#ifdef WITH_SSL -FN_GLOBAL_INTEGER(lp_ssl_version,&Globals.sslVersion); -FN_GLOBAL_STRING(lp_ssl_hosts,&Globals.sslHostsRequire); -FN_GLOBAL_STRING(lp_ssl_hosts_resign,&Globals.sslHostsResign); -FN_GLOBAL_STRING(lp_ssl_cacertdir,&Globals.sslCaCertDir); -FN_GLOBAL_STRING(lp_ssl_cacertfile,&Globals.sslCaCertFile); -FN_GLOBAL_STRING(lp_ssl_cert,&Globals.sslCert); -FN_GLOBAL_STRING(lp_ssl_privkey,&Globals.sslPrivKey); -FN_GLOBAL_STRING(lp_ssl_client_cert,&Globals.sslClientCert); -FN_GLOBAL_STRING(lp_ssl_client_privkey,&Globals.sslClientPrivKey); -FN_GLOBAL_STRING(lp_ssl_ciphers,&Globals.sslCiphers); -FN_GLOBAL_BOOL(lp_ssl_enabled,&Globals.sslEnabled); -FN_GLOBAL_BOOL(lp_ssl_reqClientCert,&Globals.sslReqClientCert); -FN_GLOBAL_BOOL(lp_ssl_reqServerCert,&Globals.sslReqServerCert); -FN_GLOBAL_BOOL(lp_ssl_compatibility,&Globals.sslCompatibility); -#endif /* WITH_SSL */ - -FN_GLOBAL_BOOL(lp_dns_proxy,&Globals.bDNSproxy) -FN_GLOBAL_BOOL(lp_wins_support,&Globals.bWINSsupport) -FN_GLOBAL_BOOL(lp_we_are_a_wins_server,&Globals.bWINSsupport) -FN_GLOBAL_BOOL(lp_wins_proxy,&Globals.bWINSproxy) -FN_GLOBAL_BOOL(lp_local_master,&Globals.bLocalMaster) -FN_GLOBAL_BOOL(lp_domain_master,&Globals.bDomainMaster) -FN_GLOBAL_BOOL(lp_domain_logons,&Globals.bDomainLogons) -FN_GLOBAL_BOOL(lp_preferred_master,&Globals.bPreferredMaster) -FN_GLOBAL_BOOL(lp_use_rhosts,&Globals.bUseRhosts) -FN_GLOBAL_BOOL(lp_readprediction,&Globals.bReadPrediction) -FN_GLOBAL_BOOL(lp_readbmpx,&Globals.bReadbmpx) -FN_GLOBAL_BOOL(lp_readraw,&Globals.bReadRaw) -FN_GLOBAL_BOOL(lp_writeraw,&Globals.bWriteRaw) -FN_GLOBAL_BOOL(lp_null_passwords,&Globals.bNullPasswords) -FN_GLOBAL_BOOL(lp_strip_dot,&Globals.bStripDot) -FN_GLOBAL_BOOL(lp_encrypted_passwords,&Globals.bEncryptPasswords) -FN_GLOBAL_BOOL(lp_update_encrypted,&Globals.bUpdateEncrypt) -FN_GLOBAL_BOOL(lp_syslog_only,&Globals.bSyslogOnly) -FN_GLOBAL_BOOL(lp_timestamp_logs,&Globals.bTimestampLogs) -FN_GLOBAL_BOOL(lp_browse_list,&Globals.bBrowseList) -FN_GLOBAL_BOOL(lp_unix_realname,&Globals.bUnixRealname) -FN_GLOBAL_BOOL(lp_nis_home_map,&Globals.bNISHomeMap) -#if 0 -static FN_GLOBAL_BOOL(lp_time_server,&Globals.bTimeServer) -#endif /* 0 */ -FN_GLOBAL_BOOL(lp_bind_interfaces_only,&Globals.bBindInterfacesOnly) -FN_GLOBAL_BOOL(lp_passwd_chat_debug,&Globals.bPasswdChatDebug) -FN_GLOBAL_BOOL(lp_ole_locking_compat,&Globals.bOleLockingCompat) -FN_GLOBAL_BOOL(lp_nt_smb_support,&Globals.bNTSmbSupport) -FN_GLOBAL_BOOL(lp_nt_pipe_support,&Globals.bNTPipeSupport) -FN_GLOBAL_BOOL(lp_nt_acl_support,&Globals.bNTAclSupport) -FN_GLOBAL_BOOL(lp_stat_cache,&Globals.bStatCache) -FN_GLOBAL_BOOL(lp_allow_trusted_domains,&Globals.bAllowTrustedDomains) -FN_GLOBAL_BOOL(lp_restrict_anonymous,&Globals.bRestrictAnonymous) - -FN_GLOBAL_INTEGER(lp_os_level,&Globals.os_level) -FN_GLOBAL_INTEGER(lp_max_ttl,&Globals.max_ttl) -FN_GLOBAL_INTEGER(lp_max_wins_ttl,&Globals.max_wins_ttl) -FN_GLOBAL_INTEGER(lp_min_wins_ttl,&Globals.min_wins_ttl) -FN_GLOBAL_INTEGER(lp_maxxmit,&Globals.max_xmit) -FN_GLOBAL_INTEGER(lp_maxmux,&Globals.max_mux) -FN_GLOBAL_INTEGER(lp_passwordlevel,&Globals.pwordlevel) -FN_GLOBAL_INTEGER(lp_usernamelevel,&Globals.unamelevel) -FN_GLOBAL_INTEGER(lp_readsize,&Globals.ReadSize) -FN_GLOBAL_INTEGER(lp_deadtime,&Globals.deadtime) -FN_GLOBAL_INTEGER(lp_maxprotocol,&Globals.maxprotocol) -FN_GLOBAL_INTEGER(lp_security,&Globals.security) -FN_GLOBAL_INTEGER(lp_maxdisksize,&Globals.maxdisksize) -FN_GLOBAL_INTEGER(lp_client_code_page,&Globals.client_code_page) -#if 0 -static FN_GLOBAL_INTEGER(lp_announce_as,&Globals.announce_as) -#endif -FN_GLOBAL_INTEGER(lp_lm_announce,&Globals.lm_announce) -FN_GLOBAL_INTEGER(lp_lm_interval,&Globals.lm_interval) -FN_GLOBAL_INTEGER(lp_machine_password_timeout,&Globals.machine_password_timeout) -FN_GLOBAL_INTEGER(lp_change_notify_timeout,&Globals.change_notify_timeout) -FN_GLOBAL_INTEGER(lp_stat_cache_size,&Globals.stat_cache_size) -FN_GLOBAL_INTEGER(lp_map_to_guest,&Globals.map_to_guest) -FN_GLOBAL_INTEGER(lp_min_passwd_length,&Globals.min_passwd_length) -FN_GLOBAL_INTEGER(lp_oplock_break_wait_time,&Globals.oplock_break_wait_time) - -#ifdef WITH_LDAP -FN_GLOBAL_INTEGER(lp_ldap_port,&Globals.ldap_port) -#endif /* WITH_LDAP */ - -FN_LOCAL_STRING(lp_preexec,szPreExec) -FN_LOCAL_STRING(lp_postexec,szPostExec) -FN_LOCAL_STRING(lp_rootpreexec,szRootPreExec) -FN_LOCAL_STRING(lp_rootpostexec,szRootPostExec) -FN_LOCAL_STRING(lp_servicename,szService) -FN_LOCAL_STRING(lp_pathname,szPath) -FN_LOCAL_STRING(lp_dontdescend,szDontdescend) -FN_LOCAL_STRING(lp_username,szUsername) -FN_LOCAL_STRING(lp_guestaccount,szGuestaccount) -FN_LOCAL_STRING(lp_invalid_users,szInvalidUsers) -FN_LOCAL_STRING(lp_valid_users,szValidUsers) -FN_LOCAL_STRING(lp_admin_users,szAdminUsers) -#if 0 -FN_LOCAL_STRING(lp_printcommand,szPrintcommand) -FN_LOCAL_STRING(lp_lpqcommand,szLpqcommand) -FN_LOCAL_STRING(lp_lprmcommand,szLprmcommand) -FN_LOCAL_STRING(lp_lppausecommand,szLppausecommand) -FN_LOCAL_STRING(lp_lpresumecommand,szLpresumecommand) -FN_LOCAL_STRING(lp_queuepausecommand,szQueuepausecommand) -FN_LOCAL_STRING(lp_queueresumecommand,szQueueresumecommand) -FN_LOCAL_STRING(lp_printername,szPrintername) -FN_LOCAL_STRING(lp_printerdriver,szPrinterDriver) -#endif /* 0 */ -FN_LOCAL_STRING(lp_hostsallow,szHostsallow) -FN_LOCAL_STRING(lp_hostsdeny,szHostsdeny) -FN_LOCAL_STRING(lp_magicscript,szMagicScript) -FN_LOCAL_STRING(lp_magicoutput,szMagicOutput) -FN_LOCAL_STRING(lp_comment,comment) -FN_LOCAL_STRING(lp_force_user,force_user) -FN_LOCAL_STRING(lp_force_group,force_group) -FN_LOCAL_STRING(lp_readlist,readlist) -FN_LOCAL_STRING(lp_writelist,writelist) -FN_LOCAL_STRING(lp_fstype,fstype) -#if 0 -static FN_LOCAL_STRING(lp_volume,volume) -#endif -FN_LOCAL_STRING(lp_mangled_map,szMangledMap) -FN_LOCAL_STRING(lp_veto_files,szVetoFiles) -FN_LOCAL_STRING(lp_hide_files,szHideFiles) -FN_LOCAL_STRING(lp_veto_oplocks,szVetoOplockFiles) -FN_LOCAL_BOOL(lp_revalidate,bRevalidate) -FN_LOCAL_BOOL(lp_casesensitive,bCaseSensitive) -FN_LOCAL_BOOL(lp_preservecase,bCasePreserve) -FN_LOCAL_BOOL(lp_shortpreservecase,bShortCasePreserve) -FN_LOCAL_BOOL(lp_casemangle,bCaseMangle) -FN_LOCAL_BOOL(lp_status,status) -FN_LOCAL_BOOL(lp_hide_dot_files,bHideDotFiles) -FN_LOCAL_BOOL(lp_browseable,bBrowseable) -FN_LOCAL_BOOL(lp_readonly,bRead_only) -FN_LOCAL_BOOL(lp_no_set_dir,bNo_set_dir) -FN_LOCAL_BOOL(lp_guest_ok,bGuest_ok) -FN_LOCAL_BOOL(lp_guest_only,bGuest_only) -FN_LOCAL_BOOL(lp_print_ok,bPrint_ok) -FN_LOCAL_BOOL(lp_postscript,bPostscript) -FN_LOCAL_BOOL(lp_map_hidden,bMap_hidden) -FN_LOCAL_BOOL(lp_map_archive,bMap_archive) -FN_LOCAL_BOOL(lp_locking,bLocking) -FN_LOCAL_BOOL(lp_strict_locking,bStrictLocking) -FN_LOCAL_BOOL(lp_share_modes,bShareModes) -FN_LOCAL_BOOL(lp_oplocks,bOpLocks) -FN_LOCAL_BOOL(lp_onlyuser,bOnlyUser) -FN_LOCAL_BOOL(lp_manglednames,bMangledNames) -FN_LOCAL_BOOL(lp_widelinks,bWidelinks) -FN_LOCAL_BOOL(lp_symlinks,bSymlinks) -FN_LOCAL_BOOL(lp_syncalways,bSyncAlways) -FN_LOCAL_BOOL(lp_strict_sync,bStrictSync) -FN_LOCAL_BOOL(lp_map_system,bMap_system) -FN_LOCAL_BOOL(lp_delete_readonly,bDeleteReadonly) -FN_LOCAL_BOOL(lp_fake_oplocks,bFakeOplocks) -FN_LOCAL_BOOL(lp_recursive_veto_delete,bDeleteVetoFiles) -FN_LOCAL_BOOL(lp_dos_filetimes,bDosFiletimes) -FN_LOCAL_BOOL(lp_dos_filetime_resolution,bDosFiletimeResolution) -FN_LOCAL_BOOL(lp_fake_dir_create_times,bFakeDirCreateTimes) -FN_LOCAL_BOOL(lp_blocking_locks,bBlockingLocks) -FN_LOCAL_BOOL(lp_mangle_locks,bMangleLocks) - -FN_LOCAL_INTEGER(lp_create_mode,iCreate_mask) -FN_LOCAL_INTEGER(lp_force_create_mode,iCreate_force_mode) -FN_LOCAL_INTEGER(lp_dir_mode,iDir_mask) -FN_LOCAL_INTEGER(lp_force_dir_mode,iDir_force_mode) -FN_LOCAL_INTEGER(lp_max_connections,iMaxConnections) -FN_LOCAL_INTEGER(lp_defaultcase,iDefaultCase) -FN_LOCAL_INTEGER(lp_minprintspace,iMinPrintSpace) -FN_LOCAL_INTEGER(lp_printing,iPrinting) -FN_LOCAL_INTEGER(lp_oplock_contention_limit,iOplockContentionLimit) - -FN_LOCAL_CHAR(lp_magicchar,magic_char) - - - -/* local prototypes */ -static int strwicmp( const char *psz1, const char *psz2 ); -static int map_parameter( const char *pszParmName); -static BOOL set_boolean( BOOL *pb, const char *pszParmValue ); -static int getservicebyname(const char *pszServiceName, service *pserviceDest); -static void copy_service( service *pserviceDest, - service *pserviceSource, - BOOL *pcopymapDest ); -static BOOL service_ok(int iService); -static BOOL do_parameter(const char *pszParmName, const char *pszParmValue); -static BOOL do_section(const char *pszSectionName); -static void init_copymap(service *pservice); - - -/*************************************************************************** -initialise a service to the defaults -***************************************************************************/ -static void init_service(service *pservice) -{ - memset((char *)pservice,'\0',sizeof(service)); - copy_service(pservice,&sDefault,NULL); -} - - -/*************************************************************************** -free the dynamically allocated parts of a service struct -***************************************************************************/ -static void free_service(service *pservice) -{ - int i; - if (!pservice) - return; - - if(pservice->szService) - DEBUG(5,("free_service: Freeing service %s\n", pservice->szService)); - - string_free(&pservice->szService); - if (pservice->copymap) - { - free(pservice->copymap); - pservice->copymap = NULL; - } - - for (i=0;parm_table[i].label;i++) - if ((parm_table[i].type == P_STRING || - parm_table[i].type == P_USTRING) && - parm_table[i].class == P_LOCAL) - string_free((char **)(((char *)pservice) + PTR_DIFF(parm_table[i].ptr,&sDefault))); -} - -/*************************************************************************** -add a new service to the services array initialising it with the given -service -***************************************************************************/ -static int add_a_service(service *pservice, const char *name) -{ - int i; - service tservice; - int num_to_alloc = iNumServices+1; - - tservice = *pservice; - - /* it might already exist */ - if (name) - { - i = getservicebyname(name,NULL); - if (i >= 0) - return(i); - } - - /* find an invalid one */ - for (i=0;ivalid) - break; - - /* if not, then create one */ - if (i == iNumServices) - { - ServicePtrs = (service **)Realloc(ServicePtrs,sizeof(service *)*num_to_alloc); - if (ServicePtrs) - pSERVICE(iNumServices) = (service *)malloc(sizeof(service)); - - if (!ServicePtrs || !pSERVICE(iNumServices)) - return(-1); - - iNumServices++; - } - else - free_service(pSERVICE(i)); - - pSERVICE(i)->valid = True; - - init_service(pSERVICE(i)); - copy_service(pSERVICE(i),&tservice,NULL); - if (name) - string_set(&iSERVICE(i).szService,name); - - return(i); -} - -/*************************************************************************** -add a new home service, with the specified home directory, defaults coming -from service ifrom -***************************************************************************/ -BOOL lp_add_home(const char *pszHomename, int iDefaultService, const char *pszHomedir) -{ - int i = add_a_service(pSERVICE(iDefaultService),pszHomename); - - if (i < 0) - return(False); - - if (!(*(iSERVICE(i).szPath)) || strequal(iSERVICE(i).szPath,lp_pathname(-1))) - string_set(&iSERVICE(i).szPath,pszHomedir); - if (!(*(iSERVICE(i).comment))) - { - pstring comment; - slprintf(comment,sizeof(comment)-1, - "Home directory of %s",pszHomename); - string_set(&iSERVICE(i).comment,comment); - } - iSERVICE(i).bAvailable = sDefault.bAvailable; - iSERVICE(i).bBrowseable = sDefault.bBrowseable; - - DEBUG(3,("adding home directory %s at %s\n", pszHomename, pszHomedir)); - - return(True); -} - -/*************************************************************************** -add a new service, based on an old one -***************************************************************************/ -int lp_add_service(char *pszService, int iDefaultService) -{ - return(add_a_service(pSERVICE(iDefaultService),pszService)); -} - -#if 0 -/*************************************************************************** -add the IPC service -***************************************************************************/ -static BOOL lp_add_ipc(void) -{ - pstring comment; - int i = add_a_service(&sDefault,"IPC$"); - - if (i < 0) - return(False); - - slprintf(comment,sizeof(comment)-1, - "IPC Service (%s)", Globals.szServerString ); - - string_set(&iSERVICE(i).szPath,tmpdir()); - string_set(&iSERVICE(i).szUsername,""); - string_set(&iSERVICE(i).comment,comment); - string_set(&iSERVICE(i).fstype,"IPC"); - iSERVICE(i).status = False; - iSERVICE(i).iMaxConnections = 0; - iSERVICE(i).bAvailable = True; - iSERVICE(i).bRead_only = True; - iSERVICE(i).bGuest_only = False; - iSERVICE(i).bGuest_ok = True; - iSERVICE(i).bPrint_ok = False; - iSERVICE(i).bBrowseable = sDefault.bBrowseable; - - DEBUG(3,("adding IPC service\n")); - - return(True); -} -#endif /* 0 */ - -/*************************************************************************** -Do a case-insensitive, whitespace-ignoring string compare. -***************************************************************************/ -static int strwicmp(const char *psz1, const char *psz2) -{ - /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */ - /* appropriate value. */ - if (psz1 == psz2) - return (0); - else - if (psz1 == NULL) - return (-1); - else - if (psz2 == NULL) - return (1); - - /* sync the strings on first non-whitespace */ - while (1) - { - while (isspace((unsigned char)*psz1)) - psz1++; - while (isspace((unsigned char)*psz2)) - psz2++; - if (toupper((unsigned char)*psz1) != toupper((unsigned char)*psz2) || *psz1 == '\0' || *psz2 == '\0') - break; - psz1++; - psz2++; - } - return (*psz1 - *psz2); -} - -/*************************************************************************** -Map a parameter's string representation to something we can use. -Returns False if the parameter string is not recognised, else TRUE. -***************************************************************************/ -static int map_parameter(const char *pszParmName) -{ - int iIndex; - - if (*pszParmName == '-') - return(-1); - - for (iIndex = 0; parm_table[iIndex].label; iIndex++) - if (strwicmp(parm_table[iIndex].label, pszParmName) == 0) - return(iIndex); - - DEBUG(0,( "Unknown parameter encountered: \"%s\"\n", pszParmName)); - return(-1); -} - - -/*************************************************************************** -Set a boolean variable from the text value stored in the passed string. -Returns True in success, False if the passed string does not correctly -represent a boolean. -***************************************************************************/ -static BOOL set_boolean(BOOL *pb, const char *pszParmValue) -{ - BOOL bRetval; - - bRetval = True; - if (strwicmp(pszParmValue, "yes") == 0 || - strwicmp(pszParmValue, "true") == 0 || - strwicmp(pszParmValue, "1") == 0) - *pb = True; - else - if (strwicmp(pszParmValue, "no") == 0 || - strwicmp(pszParmValue, "False") == 0 || - strwicmp(pszParmValue, "0") == 0) - *pb = False; - else - { - DEBUG(0,("ERROR: Badly formed boolean in configuration file: \"%s\".\n", - pszParmValue)); - bRetval = False; - } - return (bRetval); -} - -/*************************************************************************** -Find a service by name. Otherwise works like get_service. -***************************************************************************/ -static int getservicebyname(const char *pszServiceName, service *pserviceDest) -{ - int iService; - - for (iService = iNumServices - 1; iService >= 0; iService--) - if (VALID(iService) && - strwicmp(iSERVICE(iService).szService, pszServiceName) == 0) - { - if (pserviceDest != NULL) - copy_service(pserviceDest, pSERVICE(iService), NULL); - break; - } - - return (iService); -} - - - -/*************************************************************************** -Copy a service structure to another - -If pcopymapDest is NULL then copy all fields -***************************************************************************/ -static void copy_service(service *pserviceDest, - service *pserviceSource, - BOOL *pcopymapDest) -{ - int i; - BOOL bcopyall = (pcopymapDest == NULL); - - for (i=0;parm_table[i].label;i++) - if (parm_table[i].ptr && parm_table[i].class == P_LOCAL && - (bcopyall || pcopymapDest[i])) - { - void *def_ptr = parm_table[i].ptr; - void *src_ptr = - ((char *)pserviceSource) + PTR_DIFF(def_ptr,&sDefault); - void *dest_ptr = - ((char *)pserviceDest) + PTR_DIFF(def_ptr,&sDefault); - - switch (parm_table[i].type) - { - case P_BOOL: - case P_BOOLREV: - *(BOOL *)dest_ptr = *(BOOL *)src_ptr; - break; - - case P_INTEGER: - case P_ENUM: - case P_OCTAL: - *(int *)dest_ptr = *(int *)src_ptr; - break; - - case P_CHAR: - *(char *)dest_ptr = *(char *)src_ptr; - break; - - case P_STRING: - string_set(dest_ptr,*(char **)src_ptr); - break; - - case P_USTRING: - string_set(dest_ptr,*(char **)src_ptr); - strupper(*(char **)dest_ptr); - break; - default: - break; - } - } - - if (bcopyall) - { - init_copymap(pserviceDest); - if (pserviceSource->copymap) - memcpy((void *)pserviceDest->copymap, - (void *)pserviceSource->copymap,sizeof(BOOL)*NUMPARAMETERS); - } -} - -/*************************************************************************** -Check a service for consistency. Return False if the service is in any way -incomplete or faulty, else True. -***************************************************************************/ -static BOOL service_ok(int iService) -{ - BOOL bRetval; - - bRetval = True; - if (iSERVICE(iService).szService[0] == '\0') - { - DEBUG(0,( "The following message indicates an internal error:\n")); - DEBUG(0,( "No service name in service entry.\n")); - bRetval = False; - } - - /* The [printers] entry MUST be printable. I'm all for flexibility, but */ - /* I can't see why you'd want a non-printable printer service... */ - if (strwicmp(iSERVICE(iService).szService,PRINTERS_NAME) == 0) - if (!iSERVICE(iService).bPrint_ok) - { - DEBUG(0,( "WARNING: [%s] service MUST be printable!\n", - iSERVICE(iService).szService)); - iSERVICE(iService).bPrint_ok = True; - } - - if (iSERVICE(iService).szPath[0] == '\0' && - strwicmp(iSERVICE(iService).szService,HOMES_NAME) != 0) - { - DEBUG(0,("No path in service %s - using %s\n",iSERVICE(iService).szService,tmpdir())); - string_set(&iSERVICE(iService).szPath,tmpdir()); - } - - /* If a service is flagged unavailable, log the fact at level 0. */ - if (!iSERVICE(iService).bAvailable) - DEBUG(1,( "NOTE: Service %s is flagged unavailable.\n", - iSERVICE(iService).szService)); - - return (bRetval); -} - -#if 0 -static struct file_lists { - struct file_lists *next; - char *name; - time_t modtime; -} *file_lists = NULL; - -/******************************************************************* -keep a linked list of all config files so we know when one has changed -it's date and needs to be reloaded -********************************************************************/ -static void add_to_file_list(const char *fname) -{ - struct file_lists *f=file_lists; - - while (f) { - if (f->name && !strcmp(f->name,fname)) break; - f = f->next; - } - - if (!f) { - f = (struct file_lists *)malloc(sizeof(file_lists[0])); - if (!f) return; - f->next = file_lists; - f->name = strdup(fname); - if (!f->name) { - free(f); - return; - } - file_lists = f; - } - - { - pstring n2; - pstrcpy(n2,fname); - standard_sub_basic(n2); - f->modtime = file_modtime(n2); - } - -} - - -/******************************************************************* -check if a config file has changed date -********************************************************************/ -BOOL lp_file_list_changed(void) -{ - struct file_lists *f = file_lists; - DEBUG(6,("lp_file_list_changed()\n")); - - while (f) - { - pstring n2; - time_t mod_time; - - pstrcpy(n2,f->name); - standard_sub_basic(n2); - - DEBUGADD( 6, ( "file %s -> %s last mod_time: %s\n", - f->name, n2, ctime(&f->modtime) ) ); - - mod_time = file_modtime(n2); - - if (f->modtime != mod_time) { - DEBUGADD(6,("file %s modified: %s\n", n2, ctime(&mod_time))); - f->modtime = mod_time; - return(True); - } - f = f->next; - } - return(False); -} -#else -#define add_to_file_list(x) -#endif /* 0 */ - -/*************************************************************************** - handle the interpretation of the coding system parameter - *************************************************************************/ -static BOOL handle_coding_system(const char *pszParmValue,char **ptr) -{ - string_set(ptr,pszParmValue); - interpret_coding_system(pszParmValue); - return(True); -} - -/*************************************************************************** -handle the interpretation of the character set system parameter -***************************************************************************/ -static BOOL handle_character_set(const char *pszParmValue,char **ptr) -{ - string_set(ptr,pszParmValue); - interpret_character_set(pszParmValue); - return(True); -} - - -/*************************************************************************** -handle the valid chars lines -***************************************************************************/ -static BOOL handle_valid_chars(const char *pszParmValue,char **ptr) -{ - string_set(ptr,pszParmValue); - - /* A dependency here is that the parameter client code page must be - set before this is called - as calling codepage_initialise() - would overwrite the valid char lines. - */ - codepage_initialise(lp_client_code_page()); - - add_char_string(pszParmValue); - return(True); -} - - -/*************************************************************************** -handle the include operation -***************************************************************************/ -static BOOL handle_include(const char *pszParmValue,char **ptr) -{ - pstring fname; - pstrcpy(fname,pszParmValue); - - add_to_file_list(fname); - - standard_sub_basic(fname); - - string_set(ptr,fname); - - if (file_exist(fname,NULL)) - return(pm_process(fname, do_section, do_parameter)); - - DEBUG(2,("Cannot find include file %s\n",fname)); - - return(False); -} - - -/*************************************************************************** -handle the interpretation of the copy parameter -***************************************************************************/ -static BOOL handle_copy(const char *pszParmValue,char **ptr) -{ - BOOL bRetval; - int iTemp; - service serviceTemp; - - string_set(ptr,pszParmValue); - - init_service(&serviceTemp); - - bRetval = False; - - DEBUG(3,("Copying service from service %s\n",pszParmValue)); - - if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) - { - if (iTemp == iServiceIndex) - { - DEBUG(0,("Cannot copy service %s - unable to copy self!\n", - pszParmValue)); - } - else - { - copy_service(pSERVICE(iServiceIndex), - &serviceTemp, - iSERVICE(iServiceIndex).copymap); - bRetval = True; - } - } - else - { - DEBUG(0,( "Unable to copy service - source not found: %s\n", - pszParmValue)); - bRetval = False; - } - - free_service(&serviceTemp); - return (bRetval); -} - - -/*************************************************************************** -initialise a copymap -***************************************************************************/ -static void init_copymap(service *pservice) -{ - size_t i; - if (pservice->copymap) free(pservice->copymap); - pservice->copymap = (BOOL *)malloc(sizeof(BOOL)*NUMPARAMETERS); - if (!pservice->copymap) - DEBUG(0,("Couldn't allocate copymap!! (size %d)\n",(int)NUMPARAMETERS)); - else - for (i=0;icopymap[i] = True; -} - - -/*************************************************************************** - return the local pointer to a parameter given the service number and the - pointer into the default structure -***************************************************************************/ -void *lp_local_ptr(int snum, void *ptr) -{ - return (void *)(((char *)pSERVICE(snum)) + PTR_DIFF(ptr,&sDefault)); -} - -/*************************************************************************** -Process a parameter for a particular service number. If snum < 0 -then assume we are in the globals -***************************************************************************/ -BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue) -{ - int parmnum, i; - void *parm_ptr=NULL; /* where we are going to store the result */ - void *def_ptr=NULL; - - parmnum = map_parameter(pszParmName); - - if (parmnum < 0) - { - DEBUG(0,( "Ignoring unknown parameter \"%s\"\n", pszParmName)); - return(True); - } - - if (parm_table[parmnum].flags & FLAG_DEPRECATED) { - DEBUG(1,("WARNING: The \"%s\"option is deprecated\n", - pszParmName)); - } - - def_ptr = parm_table[parmnum].ptr; - - /* we might point at a service, the default service or a global */ - if (snum < 0) { - parm_ptr = def_ptr; - } else { - if (parm_table[parmnum].class == P_GLOBAL) { - DEBUG(0,( "Global parameter %s found in service section!\n",pszParmName)); - return(True); - } - parm_ptr = ((char *)pSERVICE(snum)) + PTR_DIFF(def_ptr,&sDefault); - } - - if (snum >= 0) { - if (!iSERVICE(snum).copymap) - init_copymap(pSERVICE(snum)); - - /* this handles the aliases - set the copymap for other entries with - the same data pointer */ - for (i=0;parm_table[i].label;i++) - if (parm_table[i].ptr == parm_table[parmnum].ptr) - iSERVICE(snum).copymap[i] = False; - } - - /* if it is a special case then go ahead */ - if (parm_table[parmnum].special) { - parm_table[parmnum].special(pszParmValue,(char **)parm_ptr); - return(True); - } - - /* now switch on the type of variable it is */ - switch (parm_table[parmnum].type) - { - case P_BOOL: - set_boolean(parm_ptr,pszParmValue); - break; - - case P_BOOLREV: - set_boolean(parm_ptr,pszParmValue); - *(BOOL *)parm_ptr = ! *(BOOL *)parm_ptr; - break; - - case P_INTEGER: - *(int *)parm_ptr = atoi(pszParmValue); - break; - - case P_CHAR: - *(char *)parm_ptr = *pszParmValue; - break; - - case P_OCTAL: - sscanf(pszParmValue,"%o",(int *)parm_ptr); - break; - - case P_STRING: - string_set(parm_ptr,pszParmValue); - break; - - case P_USTRING: - string_set(parm_ptr,pszParmValue); - strupper(*(char **)parm_ptr); - break; - - case P_GSTRING: - pstrcpy((char *)parm_ptr,pszParmValue); - break; - - case P_UGSTRING: - pstrcpy((char *)parm_ptr,pszParmValue); - strupper((char *)parm_ptr); - break; - - case P_ENUM: - for (i=0;parm_table[parmnum].enum_list[i].name;i++) { - if (strequal(pszParmValue, parm_table[parmnum].enum_list[i].name)) { - *(int *)parm_ptr = parm_table[parmnum].enum_list[i].value; - break; - } - } - break; - case P_SEP: - break; - } - - return(True); -} - -/*************************************************************************** -Process a parameter. -***************************************************************************/ -static BOOL do_parameter( const char *pszParmName, const char *pszParmValue ) -{ - if( !bInGlobalSection && bGlobalOnly ) - return(True); - - DEBUGADD( 3, ( "doing parameter %s = %s\n", pszParmName, pszParmValue ) ); - - return( lp_do_parameter( bInGlobalSection ? -2 : iServiceIndex, - pszParmName, - pszParmValue ) ); -} - -#if 0 -/*************************************************************************** -check if two parameters are equal -***************************************************************************/ -static BOOL equal_parameter(parm_type type,void *ptr1,void *ptr2) -{ - switch (type) - { - case P_BOOL: - case P_BOOLREV: - return(*((BOOL *)ptr1) == *((BOOL *)ptr2)); - - case P_INTEGER: - case P_ENUM: - case P_OCTAL: - return(*((int *)ptr1) == *((int *)ptr2)); - - case P_CHAR: - return(*((char *)ptr1) == *((char *)ptr2)); - - case P_GSTRING: - case P_UGSTRING: - { - char *p1 = (char *)ptr1, *p2 = (char *)ptr2; - if (p1 && !*p1) p1 = NULL; - if (p2 && !*p2) p2 = NULL; - return(p1==p2 || strequal(p1,p2)); - } - case P_STRING: - case P_USTRING: - { - char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2; - if (p1 && !*p1) p1 = NULL; - if (p2 && !*p2) p2 = NULL; - return(p1==p2 || strequal(p1,p2)); - } - case P_SEP: - break; - } - return(False); -} -#endif /* 0 */ - -/*************************************************************************** -Process a new section (service). At this stage all sections are services. -Later we'll have special sections that permit server parameters to be set. -Returns True on success, False on failure. -***************************************************************************/ -static BOOL do_section(const char *pszSectionName) -{ - BOOL bRetval; - BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) || - (strwicmp(pszSectionName, GLOBAL_NAME2) == 0)); - bRetval = False; - - /* if we were in a global section then do the local inits */ - if (bInGlobalSection && !isglobal) { - init_locals(); - } - - /* if we've just struck a global section, note the fact. */ - bInGlobalSection = isglobal; - - /* check for multiple global sections */ - if (bInGlobalSection) - { - DEBUG( 3, ( "Processing section \"[%s]\"\n", pszSectionName ) ); - return(True); - } - - if (!bInGlobalSection && bGlobalOnly) return(True); - - /* if we have a current service, tidy it up before moving on */ - bRetval = True; - - if (iServiceIndex >= 0) - bRetval = service_ok(iServiceIndex); - - /* if all is still well, move to the next record in the services array */ - if (bRetval) - { - /* We put this here to avoid an odd message order if messages are */ - /* issued by the post-processing of a previous section. */ - DEBUG(2,( "Processing section \"[%s]\"\n", pszSectionName)); - - if ((iServiceIndex=add_a_service(&sDefault,pszSectionName)) < 0) - { - DEBUG(0,("Failed to add a new service\n")); - return(False); - } - } - - return (bRetval); -} - -#if 0 -/*************************************************************************** -return True if a local parameter is currently set to the global default -***************************************************************************/ -BOOL lp_is_default(int snum, struct parm_struct *parm) -{ - int pdiff = PTR_DIFF(parm->ptr,&sDefault); - - return equal_parameter(parm->type, - ((char *)pSERVICE(snum)) + pdiff, - ((char *)&sDefault) + pdiff); -} -#endif /* 0 */ -#if 0 -/*************************************************************************** -return info about the next service in a service. snum==-1 gives the globals - -return NULL when out of parameters -***************************************************************************/ -struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters) -{ - if (snum == -1) { - /* do the globals */ - for (;parm_table[*i].label;(*i)++) { - if (parm_table[*i].class == P_SEPARATOR) - return &parm_table[(*i)++]; - - if (!parm_table[*i].ptr || (*parm_table[*i].label == '-')) - continue; - - if ((*i) > 0 && (parm_table[*i].ptr == parm_table[(*i)-1].ptr)) - continue; - - return &parm_table[(*i)++]; - } - } else { - service *pService = pSERVICE(snum); - - for (;parm_table[*i].label;(*i)++) { - if (parm_table[*i].class == P_SEPARATOR) - return &parm_table[(*i)++]; - - if (parm_table[*i].class == P_LOCAL && - parm_table[*i].ptr && - (*parm_table[*i].label != '-') && - ((*i) == 0 || - (parm_table[*i].ptr != parm_table[(*i)-1].ptr))) { - int pdiff = PTR_DIFF(parm_table[*i].ptr,&sDefault); - - if (allparameters || - !equal_parameter(parm_table[*i].type, - ((char *)pService) + pdiff, - ((char *)&sDefault) + pdiff)) { - return &parm_table[(*i)++]; - } - } - } - } - - return NULL; -} -#endif /* 0 */ -#if 0 -/*************************************************************************** -Return TRUE if the passed service number is within range. -***************************************************************************/ -BOOL lp_snum_ok(int iService) -{ - return (LP_SNUM_OK(iService) && iSERVICE(iService).bAvailable); -} -#endif /* 0 */ - -/*************************************************************************** -auto-load some home services -***************************************************************************/ -static void lp_add_auto_services(char *str) -{ - char *s; - char *p; - int homes; - - if (!str) return; - - s = strdup(str); - if (!s) return; - - homes = lp_servicenumber(HOMES_NAME); - - for (p=strtok(s,LIST_SEP);p;p=strtok(NULL,LIST_SEP)) { - const char *home = get_home_dir(p); - - if (lp_servicenumber(p) >= 0) continue; - - if (home && homes >= 0) { - lp_add_home(p,homes,home); - } - } - free(s); -} - - -/*************************************************************************** -have we loaded a services file yet? -***************************************************************************/ -BOOL lp_loaded(void) -{ - return(bLoaded); -} - -#if 0 -/*************************************************************************** -unload unused services -***************************************************************************/ -void lp_killunused(BOOL (*snumused)(int )) -{ - int i; - for (i=0;i0 && parm_table[i].ptr == parm_table[i-1].ptr) continue; - switch (parm_table[i].type) { - case P_STRING: - case P_USTRING: - parm_table[i].def.svalue = strdup(*(char **)parm_table[i].ptr); - break; - case P_GSTRING: - case P_UGSTRING: - parm_table[i].def.svalue = strdup((char *)parm_table[i].ptr); - break; - case P_BOOL: - case P_BOOLREV: - parm_table[i].def.bvalue = *(BOOL *)parm_table[i].ptr; - break; - case P_CHAR: - parm_table[i].def.cvalue = *(char *)parm_table[i].ptr; - break; - case P_INTEGER: - case P_OCTAL: - case P_ENUM: - parm_table[i].def.ivalue = *(int *)parm_table[i].ptr; - break; - case P_SEP: - break; - } - } - defaults_saved = True; -} -#endif /* 0 */ - -/*************************************************************************** -Load the services array from the services file. Return True on success, -False on failure. -***************************************************************************/ -BOOL lp_load(const char *pszFname,BOOL global_only, BOOL save_defaults, BOOL add_ipc) -{ - pstring n2; - BOOL bRetval; - - add_to_file_list(pszFname); - - bRetval = False; - - bInGlobalSection = True; - bGlobalOnly = global_only; - - init_globals(); -#if 0 - if (save_defaults) { - init_locals(); - lp_save_defaults(); - } -#else - (void) &save_defaults; -#endif /* 0 */ - pstrcpy(n2,pszFname); - standard_sub_basic(n2); - - /* We get sections first, so have to start 'behind' to make up */ - iServiceIndex = -1; - bRetval = pm_process(n2, do_section, do_parameter); - - /* finish up the last section */ - DEBUG(3,("pm_process() returned %s\n", BOOLSTR(bRetval))); - if (bRetval) - if (iServiceIndex >= 0) - bRetval = service_ok(iServiceIndex); - - lp_add_auto_services(lp_auto_services()); -#if 0 - if (add_ipc) - lp_add_ipc(); - set_default_server_announce_type(); -#else - (void) &add_ipc; -#endif /* 0 */ - - bLoaded = True; - - /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */ - /* if bWINSsupport is true and we are in the client */ - - if (in_client && Globals.bWINSsupport) { - - string_set(&Globals.szWINSserver, "127.0.0.1"); - - } - - return (bRetval); -} - - -/*************************************************************************** -reset the max number of services -***************************************************************************/ -void lp_resetnumservices(void) -{ - iNumServices = 0; -} - - -/*************************************************************************** -return the max number of services -***************************************************************************/ -int lp_numservices(void) -{ - return(iNumServices); -} - - -/*************************************************************************** -Return the number of the service with the given name, or -1 if it doesn't -exist. Note that this is a DIFFERENT ANIMAL from the internal function -getservicebyname()! This works ONLY if all services have been loaded, and -does not copy the found service. -***************************************************************************/ -int lp_servicenumber(const char *pszServiceName) -{ - int iService; - - for (iService = iNumServices - 1; iService >= 0; iService--) - if (VALID(iService) && - strequal(lp_servicename(iService), pszServiceName)) - break; - - if (iService < 0) - DEBUG(7,("lp_servicenumber: couldn't find %s\n",pszServiceName)); - - return (iService); -} - -#if 0 -/******************************************************************* - a useful volume label function - ******************************************************************/ -char *volume_label(int snum) -{ - char *ret = lp_volume(snum); - if (!*ret) return(lp_servicename(snum)); - return(ret); -} -#endif /* 0 */ -#if 0 -/******************************************************************* - Set the server type we will announce as via nmbd. -********************************************************************/ -static void set_default_server_announce_type(void) -{ - default_server_announce = (SV_TYPE_WORKSTATION | SV_TYPE_SERVER | - SV_TYPE_SERVER_UNIX | SV_TYPE_PRINTQ_SERVER); - if(lp_announce_as() == ANNOUNCE_AS_NT_SERVER) - default_server_announce |= (SV_TYPE_SERVER_NT | SV_TYPE_NT); - if(lp_announce_as() == ANNOUNCE_AS_NT_WORKSTATION) - default_server_announce |= SV_TYPE_NT; - else if(lp_announce_as() == ANNOUNCE_AS_WIN95) - default_server_announce |= SV_TYPE_WIN95_PLUS; - else if(lp_announce_as() == ANNOUNCE_AS_WFW) - default_server_announce |= SV_TYPE_WFW; - default_server_announce |= (lp_time_server() ? SV_TYPE_TIME_SOURCE : 0); -} - - -/******************************************************************* - Get the default server type we will announce as via nmbd. -********************************************************************/ -int lp_default_server_announce(void) -{ - return default_server_announce; -} - - -/******************************************************************* - Split the announce version into major and minor numbers. -********************************************************************/ -int lp_major_announce_version(void) -{ - static BOOL got_major = False; - static int major_version = DEFAULT_MAJOR_VERSION; - char *vers; - char *p; - - if(got_major) - return major_version; - - got_major = True; - if((vers = lp_announce_version()) == NULL) - return major_version; - - if((p = strchr(vers, '.')) == 0) - return major_version; - - *p = '\0'; - major_version = atoi(vers); - return major_version; -} - - -int lp_minor_announce_version(void) -{ - static BOOL got_minor = False; - static int minor_version = DEFAULT_MINOR_VERSION; - char *vers; - char *p; - - if(got_minor) - return minor_version; - - got_minor = True; - if((vers = lp_announce_version()) == NULL) - return minor_version; - - if((p = strchr(vers, '.')) == 0) - return minor_version; - - p++; - minor_version = atoi(p); - return minor_version; -} -#endif /* 0 */ - -/*********************************************************** - Set the global name resolution order (used in smbclient). -************************************************************/ - -void lp_set_name_resolve_order(char *new_order) -{ - Globals.szNameResolveOrder = new_order; -} +/* + Unix SMB/Netbios implementation. + Version 1.9. + Parameter loading functions + + Copyright (C) Karl Auer 1993-1998 + + Copyright (C) 2011 + The Free Software Foundation, Inc. + + Largely re-written by Andrew Tridgell, September 1994 + + This file is part of the Midnight Commander. + + The Midnight Commander is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + The Midnight Commander is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + */ + +/* + * Load parameters. + * + * This module provides suitable callback functions for the params + * module. It builds the internal table of service details which is + * then used by the rest of the server. + * + * To add a parameter: + * + * 1) add it to the global or service structure definition + * 2) add it to the parm_table + * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING()) + * 4) If it's a global then initialise it in init_globals. If a local + * (ie. service) parameter then initialise it in the sDefault structure + * + * + * Notes: + * The configuration file is processed sequentially for speed. It is NOT + * accessed randomly as happens in 'real' Windows. For this reason, there + * is a fair bit of sequence-dependent code here - ie., code which assumes + * that certain things happen before others. In particular, the code which + * happens at the boundary between sections is delicately poised, so be + * careful! + * + */ + +#include "includes.h" + +/* Set default coding system for KANJI if none specified in Makefile. */ +/* + * We treat KANJI specially due to historical precedent (it was the + * first non-english codepage added to Samba). With the new dynamic + * codepage support this is not needed anymore. + * + * The define 'KANJI' is being overloaded to mean 'use kanji codepage + * by default' and also 'this is the filename-to-disk conversion + * method to use'. This really should be removed and all control + * over this left in the smb.conf parameters 'client codepage' + * and 'coding system'. + */ +#ifndef KANJI +#define KANJI "sbcs" +#endif /* KANJI */ + +BOOL in_client = False; /* Not in the client by default */ +BOOL bLoaded = False; + +extern int DEBUGLEVEL; +extern pstring user_socket_options; +extern pstring global_myname; +pstring global_scope = ""; + +#ifndef GLOBAL_NAME +#define GLOBAL_NAME "global" +#endif + +#ifndef PRINTERS_NAME +#define PRINTERS_NAME "printers" +#endif + +#ifndef HOMES_NAME +#define HOMES_NAME "homes" +#endif + +/* some helpful bits */ +#define pSERVICE(i) ServicePtrs[i] +#define iSERVICE(i) (*pSERVICE(i)) +#define LP_SNUM_OK(iService) (((iService) >= 0) && ((iService) < iNumServices) && iSERVICE(iService).valid) +#define VALID(i) iSERVICE(i).valid + +int keepalive = DEFAULT_KEEPALIVE; +static BOOL use_getwd_cache; + +extern int extra_time_offset; + +/* + * This structure describes global (ie., server-wide) parameters. + */ +typedef struct +{ + char *szPrintcapname; + char *szLockDir; + char *szRootdir; + char *szDefaultService; + char *szDfree; + char *szMsgCommand; + char *szHostsEquiv; + char *szServerString; + char *szAutoServices; + char *szPasswdProgram; + char *szPasswdChat; + char *szLogFile; + char *szConfigFile; + char *szSMBPasswdFile; + char *szPasswordServer; + char *szSocketOptions; + char *szValidChars; + char *szWorkGroup; + char *szDomainAdminGroup; + char *szDomainGuestGroup; + char *szDomainAdminUsers; + char *szDomainGuestUsers; + char *szDomainHostsallow; + char *szDomainHostsdeny; + char *szUsernameMap; +#ifdef USING_GROUPNAME_MAP + char *szGroupnameMap; +#endif /* USING_GROUPNAME_MAP */ + char *szCharacterSet; + char *szLogonScript; + char *szLogonPath; + char *szLogonDrive; + char *szLogonHome; + char *szSmbrun; + char *szWINSserver; + char *szCodingSystem; + char *szInterfaces; + char *szRemoteAnnounce; + char *szRemoteBrowseSync; + char *szSocketAddress; + char *szNISHomeMapName; + char *szAnnounceVersion; /* This is initialised in init_globals */ + char *szNetbiosAliases; + char *szDomainOtherSIDs; + char *szDomainGroups; + char *szDriverFile; + char *szNameResolveOrder; + char *szLdapServer; + char *szLdapSuffix; + char *szLdapFilter; + char *szLdapRoot; + char *szLdapRootPassword; + char *szPanicAction; + char *szAddUserScript; + char *szDelUserScript; + int max_log_size; + int mangled_stack; + int max_xmit; + int max_mux; + int max_open_files; + int max_packet; + int pwordlevel; + int unamelevel; + int deadtime; + int maxprotocol; + int security; + int maxdisksize; + int lpqcachetime; + int syslog; + int os_level; + int max_ttl; + int max_wins_ttl; + int min_wins_ttl; + int ReadSize; + int lm_announce; + int lm_interval; + int shmem_size; + int client_code_page; + int announce_as; /* This is initialised in init_globals */ + int machine_password_timeout; + int change_notify_timeout; + int stat_cache_size; + int map_to_guest; + int min_passwd_length; + int oplock_break_wait_time; +#ifdef WITH_LDAP + int ldap_port; +#endif /* WITH_LDAP */ +#ifdef WITH_SSL + int sslVersion; + char *sslHostsRequire; + char *sslHostsResign; + char *sslCaCertDir; + char *sslCaCertFile; + char *sslCert; + char *sslPrivKey; + char *sslClientCert; + char *sslClientPrivKey; + char *sslCiphers; + BOOL sslEnabled; + BOOL sslReqClientCert; + BOOL sslReqServerCert; + BOOL sslCompatibility; +#endif /* WITH_SSL */ + BOOL bDNSproxy; + BOOL bWINSsupport; + BOOL bWINSproxy; + BOOL bLocalMaster; + BOOL bPreferredMaster; + BOOL bDomainMaster; + BOOL bDomainLogons; + BOOL bEncryptPasswords; + BOOL bUpdateEncrypt; + BOOL bStripDot; + BOOL bNullPasswords; + BOOL bLoadPrinters; + BOOL bUseRhosts; + BOOL bReadRaw; + BOOL bWriteRaw; + BOOL bReadPrediction; + BOOL bReadbmpx; + BOOL bSyslogOnly; + BOOL bBrowseList; + BOOL bUnixRealname; + BOOL bNISHomeMap; + BOOL bTimeServer; + BOOL bBindInterfacesOnly; + BOOL bUnixPasswdSync; + BOOL bPasswdChatDebug; + BOOL bOleLockingCompat; + BOOL bTimestampLogs; + BOOL bNTSmbSupport; + BOOL bNTPipeSupport; + BOOL bNTAclSupport; + BOOL bStatCache; + BOOL bKernelOplocks; + BOOL bAllowTrustedDomains; + BOOL bRestrictAnonymous; +} global; + +static global Globals; + + + +/* + * This structure describes a single service. + */ +typedef struct +{ + BOOL valid; + char *szService; + char *szPath; + char *szUsername; + char *szGuestaccount; + char *szInvalidUsers; + char *szValidUsers; + char *szAdminUsers; + char *szCopy; + char *szInclude; + char *szPreExec; + char *szPostExec; + char *szRootPreExec; + char *szRootPostExec; + char *szPrintcommand; + char *szLpqcommand; + char *szLprmcommand; + char *szLppausecommand; + char *szLpresumecommand; + char *szQueuepausecommand; + char *szQueueresumecommand; + char *szPrintername; + char *szPrinterDriver; + char *szPrinterDriverLocation; + char *szDontdescend; + char *szHostsallow; + char *szHostsdeny; + char *szMagicScript; + char *szMagicOutput; + char *szMangledMap; + char *szVetoFiles; + char *szHideFiles; + char *szVetoOplockFiles; + char *comment; + char *force_user; + char *force_group; + char *readlist; + char *writelist; + char *volume; + char *fstype; + int iMinPrintSpace; + int iCreate_mask; + int iCreate_force_mode; + int iDir_mask; + int iDir_force_mode; + int iMaxConnections; + int iDefaultCase; + int iPrinting; + int iOplockContentionLimit; + BOOL bAlternatePerm; + BOOL bRevalidate; + BOOL bCaseSensitive; + BOOL bCasePreserve; + BOOL bShortCasePreserve; + BOOL bCaseMangle; + BOOL status; + BOOL bHideDotFiles; + BOOL bBrowseable; + BOOL bAvailable; + BOOL bRead_only; + BOOL bNo_set_dir; + BOOL bGuest_only; + BOOL bGuest_ok; + BOOL bPrint_ok; + BOOL bPostscript; + BOOL bMap_system; + BOOL bMap_hidden; + BOOL bMap_archive; + BOOL bLocking; + BOOL bStrictLocking; + BOOL bShareModes; + BOOL bOpLocks; + BOOL bOnlyUser; + BOOL bMangledNames; + BOOL bWidelinks; + BOOL bSymlinks; + BOOL bSyncAlways; + BOOL bStrictSync; + char magic_char; + BOOL *copymap; + BOOL bDeleteReadonly; + BOOL bFakeOplocks; + BOOL bDeleteVetoFiles; + BOOL bDosFiletimes; + BOOL bDosFiletimeResolution; + BOOL bFakeDirCreateTimes; + BOOL bBlockingLocks; + BOOL bMangleLocks; + char dummy[3]; /* for alignment */ +} service; + + +/* This is a default service used to prime a services structure */ +static service sDefault = { + True, /* valid */ + NULL, /* szService */ + NULL, /* szPath */ + NULL, /* szUsername */ + NULL, /* szGuestAccount - this is set in init_globals() */ + NULL, /* szInvalidUsers */ + NULL, /* szValidUsers */ + NULL, /* szAdminUsers */ + NULL, /* szCopy */ + NULL, /* szInclude */ + NULL, /* szPreExec */ + NULL, /* szPostExec */ + NULL, /* szRootPreExec */ + NULL, /* szRootPostExec */ + NULL, /* szPrintcommand */ + NULL, /* szLpqcommand */ + NULL, /* szLprmcommand */ + NULL, /* szLppausecommand */ + NULL, /* szLpresumecommand */ + NULL, /* szQueuepausecommand */ + NULL, /* szQueueresumecommand */ + NULL, /* szPrintername */ + NULL, /* szPrinterDriver - this is set in init_globals() */ + NULL, /* szPrinterDriverLocation */ + NULL, /* szDontdescend */ + NULL, /* szHostsallow */ + NULL, /* szHostsdeny */ + NULL, /* szMagicScript */ + NULL, /* szMagicOutput */ + NULL, /* szMangledMap */ + NULL, /* szVetoFiles */ + NULL, /* szHideFiles */ + NULL, /* szVetoOplockFiles */ + NULL, /* comment */ + NULL, /* force user */ + NULL, /* force group */ + NULL, /* readlist */ + NULL, /* writelist */ + NULL, /* volume */ + NULL, /* fstype */ + 0, /* iMinPrintSpace */ + 0744, /* iCreate_mask */ + 0000, /* iCreate_force_mode */ + 0755, /* iDir_mask */ + 0000, /* iDir_force_mode */ + 0, /* iMaxConnections */ + CASE_LOWER, /* iDefaultCase */ + DEFAULT_PRINTING, /* iPrinting */ + 2, /* iOplockContentionLimit */ + False, /* bAlternatePerm */ + False, /* revalidate */ + False, /* case sensitive */ + True, /* case preserve */ + True, /* short case preserve */ + False, /* case mangle */ + True, /* status */ + True, /* bHideDotFiles */ + True, /* bBrowseable */ + True, /* bAvailable */ + True, /* bRead_only */ + True, /* bNo_set_dir */ + False, /* bGuest_only */ + False, /* bGuest_ok */ + False, /* bPrint_ok */ + False, /* bPostscript */ + False, /* bMap_system */ + False, /* bMap_hidden */ + True, /* bMap_archive */ + True, /* bLocking */ + False, /* bStrictLocking */ + True, /* bShareModes */ + True, /* bOpLocks */ + False, /* bOnlyUser */ + True, /* bMangledNames */ + True, /* bWidelinks */ + True, /* bSymlinks */ + False, /* bSyncAlways */ + False, /* bStrictSync */ + '~', /* magic char */ + NULL, /* copymap */ + False, /* bDeleteReadonly */ + False, /* bFakeOplocks */ + False, /* bDeleteVetoFiles */ + False, /* bDosFiletimes */ + False, /* bDosFiletimeResolution */ + False, /* bFakeDirCreateTimes */ + True, /* bBlockingLocks */ + True, /* bMangleLocks */ + "" /* dummy */ +}; + + + +/* local variables */ +static service **ServicePtrs = NULL; +static int iNumServices = 0; +static int iServiceIndex = 0; +static BOOL bInGlobalSection = True; +static BOOL bGlobalOnly = False; +#if 0 +static int default_server_announce; +#endif /* 0 */ +#define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct)) + +/* prototypes for the special type handlers */ +static BOOL handle_valid_chars (const char *pszParmValue, char **ptr); +static BOOL handle_include (const char *pszParmValue, char **ptr); +static BOOL handle_copy (const char *pszParmValue, char **ptr); +static BOOL handle_character_set (const char *pszParmValue, char **ptr); +static BOOL handle_coding_system (const char *pszParmValue, char **ptr); +#if 0 +static void set_default_server_announce_type (void); +#endif /* 0 */ +static struct enum_list const enum_protocol[] = + { {PROTOCOL_NT1, "NT1"}, {PROTOCOL_LANMAN2, "LANMAN2"}, +{PROTOCOL_LANMAN1, "LANMAN1"}, {PROTOCOL_CORE, "CORE"}, +{PROTOCOL_COREPLUS, "COREPLUS"}, +{PROTOCOL_COREPLUS, "CORE+"}, {-1, NULL} +}; + +static struct enum_list const enum_security[] = { {SEC_SHARE, "SHARE"}, {SEC_USER, "USER"}, +{SEC_SERVER, "SERVER"}, {SEC_DOMAIN, "DOMAIN"}, +{-1, NULL} +}; + +static struct enum_list const enum_printing[] = { {PRINT_SYSV, "sysv"}, {PRINT_AIX, "aix"}, +{PRINT_HPUX, "hpux"}, {PRINT_BSD, "bsd"}, +{PRINT_QNX, "qnx"}, {PRINT_PLP, "plp"}, +{PRINT_LPRNG, "lprng"}, {PRINT_SOFTQ, "softq"}, +{-1, NULL} +}; + +/* Types of machine we can announce as. */ +#define ANNOUNCE_AS_NT_SERVER 1 +#define ANNOUNCE_AS_WIN95 2 +#define ANNOUNCE_AS_WFW 3 +#define ANNOUNCE_AS_NT_WORKSTATION 4 + +static struct enum_list const enum_announce_as[] = + { {ANNOUNCE_AS_NT_SERVER, "NT"}, {ANNOUNCE_AS_NT_SERVER, "NT Server"}, +{ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"}, {ANNOUNCE_AS_WIN95, "win95"}, {ANNOUNCE_AS_WFW, + "WfW"}, {-1, + NULL} +}; + +static struct enum_list const enum_case[] = + { {CASE_LOWER, "lower"}, {CASE_UPPER, "upper"}, {-1, NULL} }; + +static struct enum_list const enum_lm_announce[] = + { {0, "False"}, {1, "True"}, {2, "Auto"}, {-1, NULL} }; + +/* + Do you want session setups at user level security with a invalid + password to be rejected or allowed in as guest? WinNT rejects them + but it can be a pain as it means "net view" needs to use a password + + You have 3 choices in the setting of map_to_guest: + + "Never" means session setups with an invalid password + are rejected. This is the default. + + "Bad User" means session setups with an invalid password + are rejected, unless the username does not exist, in which case it + is treated as a guest login + + "Bad Password" means session setups with an invalid password + are treated as a guest login + + Note that map_to_guest only has an effect in user or server + level security. + */ + +static struct enum_list const enum_map_to_guest[] = + { {NEVER_MAP_TO_GUEST, "Never"}, {MAP_TO_GUEST_ON_BAD_USER, "Bad User"}, +{MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"}, {-1, NULL} +}; + +#ifdef WITH_SSL +static struct enum_list const enum_ssl_version[] = { {SMB_SSL_V2, "ssl2"}, {SMB_SSL_V3, "ssl3"}, +{SMB_SSL_V23, "ssl2or3"}, {SMB_SSL_TLS1, "tls1"}, {-1, NULL} +}; +#endif + +#define PARM_SEPARATOR(label) {label, P_SEP, P_SEPARATOR, NULL, NULL, NULL, 0, {0}} +/* note that we do not initialise the defaults union - it is not allowed in ANSI C */ +static struct parm_struct parm_table[] = { + PARM_SEPARATOR ("Base Options"), + {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, + FLAG_BASIC | FLAG_SHARE | FLAG_PRINT, {0}}, + {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_SHARE | FLAG_PRINT, + {0}}, + {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, 0, {0}}, + {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkGroup, NULL, NULL, FLAG_BASIC, {0}}, + {"netbios name", P_UGSTRING, P_GLOBAL, global_myname, NULL, NULL, FLAG_BASIC, {0}}, + {"netbios aliases", P_STRING, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, 0, {0}}, + {"netbios scope", P_UGSTRING, P_GLOBAL, global_scope, NULL, NULL, 0, {0}}, + {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC, {0}}, + {"interfaces", P_STRING, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC, {0}}, + {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, 0, {0}}, + + PARM_SEPARATOR ("Security Options"), + {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC, {0}}, + {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC, + {0}}, + {"update encrypted", P_BOOL, P_GLOBAL, &Globals.bUpdateEncrypt, NULL, NULL, FLAG_BASIC, {0}}, + {"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, 0, {0}}, + {"alternate permissions", P_BOOL, P_LOCAL, &sDefault.bAlternatePerm, NULL, NULL, + FLAG_GLOBAL | FLAG_DEPRECATED, {0}}, + {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, 0, {0}}, + {"min passwd length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, 0, {0}}, + {"min password length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, 0, {0}}, + {"map to guest", P_ENUM, P_GLOBAL, &Globals.map_to_guest, NULL, enum_map_to_guest, 0, {0}}, + {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, 0, {0}}, + {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, 0, {0}}, + {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, 0, {0}}, + {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0, {0}}, + {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0, {0}}, + {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0, {0}}, + {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, 0, {0}}, + {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, 0, {0}}, + {"passwd chat debug", P_BOOL, P_GLOBAL, &Globals.bPasswdChatDebug, NULL, NULL, 0, {0}}, + {"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL, NULL, 0, {0}}, + {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, 0, {0}}, + {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, 0, {0}}, + {"unix password sync", P_BOOL, P_GLOBAL, &Globals.bUnixPasswdSync, NULL, NULL, 0, {0}}, + {"restrict anonymous", P_BOOL, P_GLOBAL, &Globals.bRestrictAnonymous, NULL, NULL, 0, {0}}, + {"revalidate", P_BOOL, P_LOCAL, &sDefault.bRevalidate, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE, + {0}}, + {"use rhosts", P_BOOL, P_GLOBAL, &Globals.bUseRhosts, NULL, NULL, 0, {0}}, + {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE, + {0}}, + {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, 0, {0}}, + {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, 0, {0}}, + {"guest account", P_STRING, P_LOCAL, &sDefault.szGuestaccount, NULL, NULL, + FLAG_BASIC | FLAG_SHARE | FLAG_PRINT | FLAG_GLOBAL, {0}}, + {"invalid users", P_STRING, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, + FLAG_GLOBAL | FLAG_SHARE, {0}}, + {"valid users", P_STRING, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE, + {0}}, + {"admin users", P_STRING, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE, + {0}}, + {"read list", P_STRING, P_LOCAL, &sDefault.readlist, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE, {0}}, + {"write list", P_STRING, P_LOCAL, &sDefault.writelist, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE, + {0}}, + {"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL, NULL, FLAG_SHARE, {0}}, + {"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_SHARE, {0}}, + {"group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, 0, {0}}, + {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_SHARE, {0}}, + {"write ok", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0, {0}}, + {"writeable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0, {0}}, + {"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0, {0}}, + {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE, + {0}}, + {"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_GLOBAL, {0}}, + {"force create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL, NULL, + FLAG_GLOBAL | FLAG_SHARE, {0}}, + {"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE, + {0}}, + {"directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_GLOBAL, {0}}, + {"force directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_force_mode, NULL, NULL, + FLAG_GLOBAL | FLAG_SHARE, {0}}, + {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_SHARE, {0}}, + {"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, 0, {0}}, + {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, + FLAG_BASIC | FLAG_SHARE | FLAG_PRINT, {0}}, + {"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, 0, {0}}, + {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, FLAG_SHARE, {0}}, + {"hosts allow", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, + FLAG_GLOBAL | FLAG_BASIC | FLAG_SHARE | FLAG_PRINT, {0}}, + {"allow hosts", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, 0, {0}}, + {"hosts deny", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, + FLAG_GLOBAL | FLAG_BASIC | FLAG_SHARE | FLAG_PRINT, {0}}, + {"deny hosts", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, 0, {0}}, + +#ifdef WITH_SSL + PARM_SEPARATOR ("Secure Socket Layer Options"), + {"ssl", P_BOOL, P_GLOBAL, &Globals.sslEnabled, NULL, NULL, 0, {0}}, + {"ssl hosts", P_STRING, P_GLOBAL, &Globals.sslHostsRequire, NULL, NULL, 0, {0}}, + {"ssl hosts resign", P_STRING, P_GLOBAL, &Globals.sslHostsResign, NULL, NULL, 0}, + {"ssl CA certDir", P_STRING, P_GLOBAL, &Globals.sslCaCertDir, NULL, NULL, 0, {0}}, + {"ssl CA certFile", P_STRING, P_GLOBAL, &Globals.sslCaCertFile, NULL, NULL, 0, {0}}, + {"ssl server cert", P_STRING, P_GLOBAL, &Globals.sslCert, NULL, NULL, 0, {0}}, + {"ssl server key", P_STRING, P_GLOBAL, &Globals.sslPrivKey, NULL, NULL, 0, {0}}, + {"ssl client cert", P_STRING, P_GLOBAL, &Globals.sslClientCert, NULL, NULL, 0, {0}}, + {"ssl client key", P_STRING, P_GLOBAL, &Globals.sslClientPrivKey, NULL, NULL, 0, {0}}, + {"ssl require clientcert", P_BOOL, P_GLOBAL, &Globals.sslReqClientCert, NULL, NULL, 0, {0}}, + {"ssl require servercert", P_BOOL, P_GLOBAL, &Globals.sslReqServerCert, NULL, NULL, 0, {0}}, + {"ssl ciphers", P_STRING, P_GLOBAL, &Globals.sslCiphers, NULL, NULL, 0, {0}}, + {"ssl version", P_ENUM, P_GLOBAL, &Globals.sslVersion, NULL, enum_ssl_version, 0, {0}}, + {"ssl compatibility", P_BOOL, P_GLOBAL, &Globals.sslCompatibility, NULL, NULL, 0, {0}}, +#endif /* WITH_SSL */ + + PARM_SEPARATOR ("Logging Options"), + {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_BASIC, {0}}, + {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, 0, {0}}, + {"syslog", P_INTEGER, P_GLOBAL, &Globals.syslog, NULL, NULL, 0, {0}}, + {"syslog only", P_BOOL, P_GLOBAL, &Globals.bSyslogOnly, NULL, NULL, 0, {0}}, + {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, 0, {0}}, + {"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL, NULL, 0, {0}}, + {"timestamp logs", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, 0, {0}}, + {"debug timestamp", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, 0, {0}}, + {"status", P_BOOL, P_LOCAL, &sDefault.status, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE | FLAG_PRINT, + {0}}, + + PARM_SEPARATOR ("Protocol Options"), + {"protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, 0, {0}}, + {"read bmpx", P_BOOL, P_GLOBAL, &Globals.bReadbmpx, NULL, NULL, 0, {0}}, + {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, 0, {0}}, + {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, 0, {0}}, + {"nt smb support", P_BOOL, P_GLOBAL, &Globals.bNTSmbSupport, NULL, NULL, 0, {0}}, + {"nt pipe support", P_BOOL, P_GLOBAL, &Globals.bNTPipeSupport, NULL, NULL, 0, {0}}, + {"nt acl support", P_BOOL, P_GLOBAL, &Globals.bNTAclSupport, NULL, NULL, 0, {0}}, + {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, 0, {0}}, + {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, 0, {0}}, + {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, 0, {0}}, + {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, 0, {0}}, + {"name resolve order", P_STRING, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, 0, {0}}, + {"max packet", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL, NULL, 0, {0}}, + {"packet size", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL, NULL, 0, {0}}, + {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, 0, {0}}, + {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, 0, {0}}, + {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, 0, {0}}, + {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, 0, {0}}, + + PARM_SEPARATOR ("Tuning Options"), + {"change notify timeout", P_INTEGER, P_GLOBAL, &Globals.change_notify_timeout, NULL, NULL, 0, + {0}}, + {"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL, NULL, 0, {0}}, + {"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL, NULL, 0, {0}}, + {"keepalive", P_INTEGER, P_GLOBAL, &keepalive, NULL, NULL, 0, {0}}, + {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, 0, {0}}, + {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_SHARE, {0}}, + {"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL, NULL, 0, {0}}, + {"max open files", P_INTEGER, P_GLOBAL, &Globals.max_open_files, NULL, NULL, 0, {0}}, + {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, FLAG_PRINT, {0}}, + {"read prediction", P_BOOL, P_GLOBAL, &Globals.bReadPrediction, NULL, NULL, 0, {0}}, + {"read size", P_INTEGER, P_GLOBAL, &Globals.ReadSize, NULL, NULL, 0, {0}}, + {"shared mem size", P_INTEGER, P_GLOBAL, &Globals.shmem_size, NULL, NULL, 0, {0}}, + {"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL, NULL, 0, {0}}, + {"stat cache size", P_INTEGER, P_GLOBAL, &Globals.stat_cache_size, NULL, NULL, 0, {0}}, + {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_SHARE, {0}}, + {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL, NULL, FLAG_SHARE, {0}}, + + PARM_SEPARATOR ("Printing Options"), + {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, FLAG_PRINT, {0}}, + {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_PRINT, {0}}, + {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, 0, {0}}, + {"printer driver file", P_STRING, P_GLOBAL, &Globals.szDriverFile, NULL, NULL, FLAG_PRINT, {0}}, + {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_PRINT, {0}}, + {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, 0, {0}}, + {"postscript", P_BOOL, P_LOCAL, &sDefault.bPostscript, NULL, NULL, FLAG_PRINT, {0}}, + {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, NULL, enum_printing, + FLAG_PRINT | FLAG_GLOBAL, {0}}, + {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, + FLAG_PRINT | FLAG_GLOBAL, {0}}, + {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL, + {0}}, + {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, + FLAG_PRINT | FLAG_GLOBAL, {0}}, + {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, + FLAG_PRINT | FLAG_GLOBAL, {0}}, + {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand, NULL, NULL, + FLAG_PRINT | FLAG_GLOBAL, {0}}, + {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, + FLAG_PRINT | FLAG_GLOBAL, {0}}, + {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, + FLAG_PRINT | FLAG_GLOBAL, {0}}, + + {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT, {0}}, + {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, 0, {0}}, + {"printer driver", P_STRING, P_LOCAL, &sDefault.szPrinterDriver, NULL, NULL, FLAG_PRINT, {0}}, + {"printer driver location", P_STRING, P_LOCAL, &sDefault.szPrinterDriverLocation, NULL, NULL, + FLAG_PRINT | FLAG_GLOBAL, {0}}, + + + PARM_SEPARATOR ("Filename Handling"), + {"strip dot", P_BOOL, P_GLOBAL, &Globals.bStripDot, NULL, NULL, 0, {0}}, + {"character set", P_STRING, P_GLOBAL, &Globals.szCharacterSet, handle_character_set, NULL, 0, + {0}}, + {"mangled stack", P_INTEGER, P_GLOBAL, &Globals.mangled_stack, NULL, NULL, 0, {0}}, + {"coding system", P_STRING, P_GLOBAL, &Globals.szCodingSystem, handle_coding_system, NULL, 0, + {0}}, + {"client code page", P_INTEGER, P_GLOBAL, &Globals.client_code_page, NULL, NULL, 0, {0}}, + {"default case", P_ENUM, P_LOCAL, &sDefault.iDefaultCase, NULL, enum_case, FLAG_SHARE, {0}}, + {"case sensitive", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, + FLAG_SHARE | FLAG_GLOBAL, {0}}, + {"casesignames", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, 0, {0}}, + {"preserve case", P_BOOL, P_LOCAL, &sDefault.bCasePreserve, NULL, NULL, + FLAG_SHARE | FLAG_GLOBAL, {0}}, + {"short preserve case", P_BOOL, P_LOCAL, &sDefault.bShortCasePreserve, NULL, NULL, + FLAG_SHARE | FLAG_GLOBAL, {0}}, + {"mangle case", P_BOOL, P_LOCAL, &sDefault.bCaseMangle, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL, + {0}}, + {"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL, + {0}}, + {"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL, NULL, + FLAG_SHARE | FLAG_GLOBAL, {0}}, + {"delete veto files", P_BOOL, P_LOCAL, &sDefault.bDeleteVetoFiles, NULL, NULL, + FLAG_SHARE | FLAG_GLOBAL, {0}}, + {"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL, + {0}}, + {"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL, + {0}}, + {"veto oplock files", P_STRING, P_LOCAL, &sDefault.szVetoOplockFiles, NULL, NULL, + FLAG_SHARE | FLAG_GLOBAL, {0}}, + {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL, + {0}}, + {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL, + {0}}, + {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL, + {0}}, + {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL, NULL, + FLAG_SHARE | FLAG_GLOBAL, {0}}, + {"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL, + {0}}, + {"stat cache", P_BOOL, P_GLOBAL, &Globals.bStatCache, NULL, NULL, 0, {0}}, + + PARM_SEPARATOR ("Domain Options"), + {"domain groups", P_STRING, P_GLOBAL, &Globals.szDomainGroups, NULL, NULL, 0, {0}}, + {"domain admin group", P_STRING, P_GLOBAL, &Globals.szDomainAdminGroup, NULL, NULL, 0, {0}}, + {"domain guest group", P_STRING, P_GLOBAL, &Globals.szDomainGuestGroup, NULL, NULL, 0, {0}}, + {"domain admin users", P_STRING, P_GLOBAL, &Globals.szDomainAdminUsers, NULL, NULL, 0, {0}}, + {"domain guest users", P_STRING, P_GLOBAL, &Globals.szDomainGuestUsers, NULL, NULL, 0, {0}}, +#ifdef USING_GROUPNAME_MAP + {"groupname map", P_STRING, P_GLOBAL, &Globals.szGroupnameMap, NULL, NULL, 0, {0}}, +#endif /* USING_GROUPNAME_MAP */ + {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, + 0, {0}}, + + PARM_SEPARATOR ("Logon Options"), + {"add user script", P_STRING, P_GLOBAL, &Globals.szAddUserScript, NULL, NULL, 0, {0}}, + {"delete user script", P_STRING, P_GLOBAL, &Globals.szDelUserScript, NULL, NULL, 0, {0}}, + {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, 0, {0}}, + {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, 0, {0}}, + {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, 0, {0}}, + {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, 0, {0}}, + {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, 0, {0}}, + + PARM_SEPARATOR ("Browse Options"), + {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC, {0}}, + {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_lm_announce, 0, {0}}, + {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, 0, {0}}, + {"preferred master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL, NULL, FLAG_BASIC, {0}}, + {"prefered master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL, NULL, 0, {0}}, + {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC, {0}}, + {"domain master", P_BOOL, P_GLOBAL, &Globals.bDomainMaster, NULL, NULL, FLAG_BASIC, {0}}, + {"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL, NULL, 0, {0}}, + {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, + FLAG_BASIC | FLAG_SHARE | FLAG_PRINT, {0}}, + {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, 0, {0}}, + + PARM_SEPARATOR ("WINS Options"), + {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, 0, {0}}, + {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, 0, {0}}, + {"wins server", P_STRING, P_GLOBAL, &Globals.szWINSserver, NULL, NULL, FLAG_BASIC, {0}}, + {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC, {0}}, + + PARM_SEPARATOR ("Locking Options"), + {"blocking locks", P_BOOL, P_LOCAL, &sDefault.bBlockingLocks, NULL, NULL, + FLAG_SHARE | FLAG_GLOBAL, {0}}, + {"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL, NULL, FLAG_SHARE, {0}}, + {"kernel oplocks", P_BOOL, P_GLOBAL, &Globals.bKernelOplocks, NULL, NULL, FLAG_GLOBAL, {0}}, + {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL, {0}}, + {"mangle locks", P_BOOL, P_LOCAL, &sDefault.bMangleLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL, + {0}}, + {"ole locking compatibility", P_BOOL, P_GLOBAL, &Globals.bOleLockingCompat, NULL, NULL, + FLAG_GLOBAL, {0}}, + {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL, {0}}, + {"oplock break wait time", P_INTEGER, P_GLOBAL, &Globals.oplock_break_wait_time, NULL, NULL, + FLAG_GLOBAL, {0}}, + {"oplock contention limit", P_INTEGER, P_LOCAL, &sDefault.iOplockContentionLimit, NULL, NULL, + FLAG_SHARE | FLAG_GLOBAL, {0}}, + {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, + FLAG_SHARE | FLAG_GLOBAL, {0}}, + {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL, + {0}}, + +#ifdef WITH_LDAP + PARM_SEPARATOR ("Ldap Options"), + {"ldap server", P_STRING, P_GLOBAL, &Globals.szLdapServer, NULL, NULL, 0, {0}}, + {"ldap port", P_INTEGER, P_GLOBAL, &Globals.ldap_port, NULL, NULL, 0, {0}}, + {"ldap suffix", P_STRING, P_GLOBAL, &Globals.szLdapSuffix, NULL, NULL, 0, {0}}, + {"ldap filter", P_STRING, P_GLOBAL, &Globals.szLdapFilter, NULL, NULL, 0, {0}}, + {"ldap root", P_STRING, P_GLOBAL, &Globals.szLdapRoot, NULL, NULL, 0, {0}}, + {"ldap root passwd", P_STRING, P_GLOBAL, &Globals.szLdapRootPassword, NULL, NULL, 0, {0}}, +#endif /* WITH_LDAP */ + + + PARM_SEPARATOR ("Miscellaneous Options"), + {"smbrun", P_STRING, P_GLOBAL, &Globals.szSmbrun, NULL, NULL, 0, {0}}, + {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE, {0}}, + {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, 0, {0}}, + {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, 0, {0}}, + {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, 0, {0}}, + {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, 0, {0}}, + {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, 0, {0}}, + {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, 0, {0}}, + {"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL, NULL, 0, {0}}, + {"dfree command", P_STRING, P_GLOBAL, &Globals.szDfree, NULL, NULL, 0, {0}}, + {"valid chars", P_STRING, P_GLOBAL, &Globals.szValidChars, handle_valid_chars, NULL, 0, {0}}, + {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, 0, {0}}, + {"remote browse sync", P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync, NULL, NULL, 0, {0}}, + {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, 0, {0}}, + {"homedir map", P_STRING, P_GLOBAL, &Globals.szNISHomeMapName, NULL, NULL, 0, {0}}, + {"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL, NULL, 0, {0}}, + {"unix realname", P_BOOL, P_GLOBAL, &Globals.bUnixRealname, NULL, NULL, 0, {0}}, + {"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL, NULL, 0, {0}}, + {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE, {0}}, + {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE, {0}}, + {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE, {0}}, + {"exec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, FLAG_SHARE | FLAG_PRINT, {0}}, + {"preexec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, 0, {0}}, + {"postexec", P_STRING, P_LOCAL, &sDefault.szPostExec, NULL, NULL, FLAG_SHARE | FLAG_PRINT, {0}}, + {"root preexec", P_STRING, P_LOCAL, &sDefault.szRootPreExec, NULL, NULL, + FLAG_SHARE | FLAG_PRINT, {0}}, + {"root postexec", P_STRING, P_LOCAL, &sDefault.szRootPostExec, NULL, NULL, + FLAG_SHARE | FLAG_PRINT, {0}}, + {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, + FLAG_BASIC | FLAG_SHARE | FLAG_PRINT, {0}}, + {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_SHARE, {0}}, + {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_SHARE, {0}}, + {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL, NULL, FLAG_SHARE, {0}}, + {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL, + {0}}, + {"follow symlinks", P_BOOL, P_LOCAL, &sDefault.bSymlinks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL, + {0}}, + {"dont descend", P_STRING, P_LOCAL, &sDefault.szDontdescend, NULL, NULL, FLAG_SHARE, {0}}, + {"magic script", P_STRING, P_LOCAL, &sDefault.szMagicScript, NULL, NULL, FLAG_SHARE, {0}}, + {"magic output", P_STRING, P_LOCAL, &sDefault.szMagicOutput, NULL, NULL, FLAG_SHARE, {0}}, + {"delete readonly", P_BOOL, P_LOCAL, &sDefault.bDeleteReadonly, NULL, NULL, + FLAG_SHARE | FLAG_GLOBAL, {0}}, + {"dos filetimes", P_BOOL, P_LOCAL, &sDefault.bDosFiletimes, NULL, NULL, + FLAG_SHARE | FLAG_GLOBAL, {0}}, + {"dos filetime resolution", P_BOOL, P_LOCAL, &sDefault.bDosFiletimeResolution, NULL, NULL, + FLAG_SHARE | FLAG_GLOBAL, {0}}, + + {"fake directory create times", P_BOOL, P_LOCAL, &sDefault.bFakeDirCreateTimes, NULL, NULL, + FLAG_SHARE | FLAG_GLOBAL, {0}}, + {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, 0, {0}}, + + {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0, {0}} +}; + + + +/*************************************************************************** +Initialise the global parameter structure. +***************************************************************************/ +static void +init_globals (void) +{ + static BOOL done_init = False; + pstring s; + + if (!done_init) + { + int i; + memset ((void *) &Globals, '\0', sizeof (Globals)); + + for (i = 0; parm_table[i].label; i++) + if ((parm_table[i].type == P_STRING || + parm_table[i].type == P_USTRING) && parm_table[i].ptr) + string_init (parm_table[i].ptr, ""); + + string_set (&sDefault.szGuestaccount, GUEST_ACCOUNT); + string_set (&sDefault.szPrinterDriver, "NULL"); + string_set (&sDefault.fstype, FSTYPE_STRING); + + done_init = True; + } + + + DEBUG (3, ("Initialising global parameters\n")); + + string_set (&Globals.szWorkGroup, WORKGROUP); + string_set (&Globals.szPrintcapname, PRINTCAP_NAME); + string_set (&Globals.szDriverFile, DRIVERFILE); + string_set (&Globals.szRootdir, "/"); + string_set (&Globals.szSocketAddress, "0.0.0.0"); + string_set (&Globals.szServerString, "Samba " VERSION); + slprintf (s, sizeof (s) - 1, "%d.%d", DEFAULT_MAJOR_VERSION, DEFAULT_MINOR_VERSION); + string_set (&Globals.szAnnounceVersion, s); + + pstrcpy (user_socket_options, DEFAULT_SOCKET_OPTIONS); + + string_set (&Globals.szLogonDrive, ""); + /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */ + string_set (&Globals.szLogonHome, "\\\\%N\\%U"); + string_set (&Globals.szLogonPath, "\\\\%N\\%U\\profile"); + + string_set (&Globals.szNameResolveOrder, "lmhosts host wins bcast"); + + Globals.bLoadPrinters = True; + Globals.bUseRhosts = False; + Globals.max_packet = 65535; + Globals.mangled_stack = 50; + Globals.max_xmit = 65535; + Globals.max_mux = 50; /* This is *needed* for profile support. */ + Globals.lpqcachetime = 10; + Globals.pwordlevel = 0; + Globals.unamelevel = 0; + Globals.deadtime = 0; + Globals.max_log_size = 5000; + Globals.max_open_files = MAX_OPEN_FILES; + Globals.maxprotocol = PROTOCOL_NT1; + Globals.security = SEC_USER; + Globals.bEncryptPasswords = False; + Globals.bUpdateEncrypt = False; + Globals.bReadRaw = True; + Globals.bWriteRaw = True; + Globals.bReadPrediction = False; + Globals.bReadbmpx = False; + Globals.bNullPasswords = False; + Globals.bStripDot = False; + Globals.syslog = 1; + Globals.bSyslogOnly = False; + Globals.bTimestampLogs = True; + Globals.os_level = 0; + Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */ + Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */ + Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */ + Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */ + Globals.change_notify_timeout = 60; /* 1 minute default. */ + Globals.ReadSize = 16 * 1024; + Globals.lm_announce = 2; /* = Auto: send only if LM clients found */ + Globals.lm_interval = 60; + Globals.shmem_size = SHMEM_SIZE; + Globals.stat_cache_size = 50; /* Number of stat translations we'll keep */ + Globals.announce_as = ANNOUNCE_AS_NT_SERVER; + Globals.bUnixRealname = False; +#if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT)) + Globals.bNISHomeMap = False; +#ifdef WITH_NISPLUS_HOME + string_set (&Globals.szNISHomeMapName, "auto_home.org_dir"); +#else + string_set (&Globals.szNISHomeMapName, "auto.home"); +#endif +#endif + Globals.client_code_page = DEFAULT_CLIENT_CODE_PAGE; + Globals.bTimeServer = False; + Globals.bBindInterfacesOnly = False; + Globals.bUnixPasswdSync = False; + Globals.bPasswdChatDebug = False; + Globals.bOleLockingCompat = True; + Globals.bNTSmbSupport = True; /* Do NT SMB's by default. */ + Globals.bNTPipeSupport = True; /* Do NT pipes by default. */ + Globals.bNTAclSupport = True; /* Use NT ACLs by default. */ + Globals.bStatCache = True; /* use stat cache by default */ + Globals.bRestrictAnonymous = False; + Globals.map_to_guest = 0; /* By Default, "Never" */ + Globals.min_passwd_length = MINPASSWDLENGTH; /* By Default, 5. */ + Globals.oplock_break_wait_time = 10; /* By Default, 10 msecs. */ + +#ifdef WITH_LDAP + /* default values for ldap */ + string_set (&Globals.szLdapServer, "localhost"); + Globals.ldap_port = 389; +#endif /* WITH_LDAP */ + +#ifdef WITH_SSL + Globals.sslVersion = SMB_SSL_V23; + string_set (&Globals.sslHostsRequire, ""); + string_set (&Globals.sslHostsResign, ""); + string_set (&Globals.sslCaCertDir, ""); + string_set (&Globals.sslCaCertFile, ""); + string_set (&Globals.sslCert, ""); + string_set (&Globals.sslPrivKey, ""); + string_set (&Globals.sslClientCert, ""); + string_set (&Globals.sslClientPrivKey, ""); + string_set (&Globals.sslCiphers, ""); + Globals.sslEnabled = False; + Globals.sslReqClientCert = False; + Globals.sslReqServerCert = False; + Globals.sslCompatibility = False; +#endif /* WITH_SSL */ + + /* these parameters are set to defaults that are more appropriate + for the increasing samba install base: + + as a member of the workgroup, that will possibly become a + _local_ master browser (lm = True). this is opposed to a forced + local master browser startup (pm = True). + + doesn't provide WINS server service by default (wsupp = False), + and doesn't provide domain master browser services by default, either. + + */ + + Globals.bPreferredMaster = False; + Globals.bLocalMaster = True; + Globals.bDomainMaster = False; + Globals.bDomainLogons = False; + Globals.bBrowseList = True; + Globals.bWINSsupport = False; + Globals.bWINSproxy = False; + + Globals.bDNSproxy = True; + + /* + * smbd will check at runtime to see if this value + * will really be used or not. + */ + Globals.bKernelOplocks = True; + + Globals.bAllowTrustedDomains = True; + + /* + * This must be done last as it checks the value in + * client_code_page. + */ + + interpret_coding_system (KANJI); +} + +#if 0 +/*************************************************************************** +check if a string is initialised and if not then initialise it +***************************************************************************/ +static void +string_initial (char **s, char *v) +{ + if (!*s || !**s) + string_init (s, v); +} + +#else +#define init_locals() +#endif /* 0 */ + +static size_t +size_max (size_t a, size_t b) +{ + return (a > b) ? a : b; +} + +/******************************************************************* a +convenience routine to grab string parameters into a rotating buffer, +and run standard_sub_basic on them. The buffers can be written to by +callers without affecting the source string. +********************************************************************/ +static char * +lp_string (const char *s) +{ + static char *bufs[10]; + static int buflen[10]; + static int next = -1; + char *ret; + int i; + int len = s ? strlen (s) : 0; + + if (next == -1) + { + /* initialisation */ + for (i = 0; i < 10; i++) + { + bufs[i] = NULL; + buflen[i] = 0; + } + next = 0; + } + + len = size_max (len + 100, sizeof (pstring)); /* the +100 is for some + substitution room */ + + if (buflen[next] != len) + { + buflen[next] = len; + if (bufs[next]) + free (bufs[next]); + bufs[next] = (char *) malloc (len); + if (!bufs[next]) + { + DEBUG (0, ("out of memory in lp_string()")); + exit (1); + } + } + + ret = &bufs[next][0]; + next = (next + 1) % 10; + + if (!s) + *ret = 0; + else + StrCpy (ret, s); + + trim_string (ret, "\"", "\""); + + standard_sub_basic (ret); + return (ret); +} + + +/* + In this section all the functions that are used to access the + parameters from the rest of the program are defined + */ + +#define FN_GLOBAL_STRING(fn_name,ptr) \ + char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));} +#define FN_GLOBAL_BOOL(fn_name,ptr) \ + BOOL fn_name(void) {return(*(BOOL *)(ptr));} +#define FN_GLOBAL_CHAR(fn_name,ptr) \ + char fn_name(void) {return(*(char *)(ptr));} +#define FN_GLOBAL_INTEGER(fn_name,ptr) \ + int fn_name(void) {return(*(int *)(ptr));} + +#define FN_LOCAL_STRING(fn_name,val) \ + char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i)&&pSERVICE(i)->val)?pSERVICE(i)->val : sDefault.val));} +#define FN_LOCAL_BOOL(fn_name,val) \ + BOOL fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);} +#define FN_LOCAL_CHAR(fn_name,val) \ + char fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);} +#define FN_LOCAL_INTEGER(fn_name,val) \ + int fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);} + +FN_GLOBAL_STRING (lp_logfile, &Globals.szLogFile) +FN_GLOBAL_STRING (lp_configfile, &Globals.szConfigFile) +FN_GLOBAL_STRING (lp_serverstring, &Globals.szServerString) +FN_GLOBAL_STRING (lp_printcapname, &Globals.szPrintcapname) +FN_GLOBAL_STRING (lp_lockdir, &Globals.szLockDir) +FN_GLOBAL_STRING (lp_rootdir, &Globals.szRootdir) +FN_GLOBAL_STRING (lp_defaultservice, &Globals.szDefaultService) +FN_GLOBAL_STRING (lp_msg_command, &Globals.szMsgCommand) +FN_GLOBAL_STRING (lp_hosts_equiv, &Globals.szHostsEquiv) +FN_GLOBAL_STRING (lp_auto_services, &Globals.szAutoServices) +FN_GLOBAL_STRING (lp_passwordserver, &Globals.szPasswordServer) +FN_GLOBAL_STRING (lp_name_resolve_order, &Globals.szNameResolveOrder) +FN_GLOBAL_STRING (lp_workgroup, &Globals.szWorkGroup) +FN_GLOBAL_STRING (lp_username_map, &Globals.szUsernameMap) +#ifdef USING_GROUPNAME_MAP + FN_GLOBAL_STRING (lp_groupname_map, &Globals.szGroupnameMap) +#endif /* USING_GROUPNAME_MAP */ + FN_GLOBAL_STRING (lp_remote_announce, &Globals.szRemoteAnnounce) +FN_GLOBAL_STRING (lp_remote_browse_sync, &Globals.szRemoteBrowseSync) +FN_GLOBAL_STRING (lp_wins_server, &Globals.szWINSserver) +FN_GLOBAL_STRING (lp_interfaces, &Globals.szInterfaces) +FN_GLOBAL_STRING (lp_socket_address, &Globals.szSocketAddress) +FN_GLOBAL_STRING (lp_nis_home_map_name, &Globals.szNISHomeMapName) +#if 0 + static FN_GLOBAL_STRING (lp_announce_version, &Globals.szAnnounceVersion) +#endif /* 0 */ +FN_GLOBAL_STRING (lp_netbios_aliases, &Globals.szNetbiosAliases) +FN_GLOBAL_STRING (lp_driverfile, &Globals.szDriverFile) +FN_GLOBAL_STRING (lp_panic_action, &Globals.szPanicAction) +FN_GLOBAL_STRING (lp_domain_groups, &Globals.szDomainGroups) +FN_GLOBAL_STRING (lp_domain_admin_group, &Globals.szDomainAdminGroup) +FN_GLOBAL_STRING (lp_domain_guest_group, &Globals.szDomainGuestGroup) +FN_GLOBAL_STRING (lp_domain_admin_users, &Globals.szDomainAdminUsers) +FN_GLOBAL_STRING (lp_domain_guest_users, &Globals.szDomainGuestUsers) +#ifdef WITH_LDAP +FN_GLOBAL_STRING (lp_ldap_server, &Globals.szLdapServer); +FN_GLOBAL_STRING (lp_ldap_suffix, &Globals.szLdapSuffix); +FN_GLOBAL_STRING (lp_ldap_filter, &Globals.szLdapFilter); +FN_GLOBAL_STRING (lp_ldap_root, &Globals.szLdapRoot); +FN_GLOBAL_STRING (lp_ldap_rootpasswd, &Globals.szLdapRootPassword); +#endif /* WITH_LDAP */ + +#ifdef WITH_SSL +FN_GLOBAL_INTEGER (lp_ssl_version, &Globals.sslVersion); +FN_GLOBAL_STRING (lp_ssl_hosts, &Globals.sslHostsRequire); +FN_GLOBAL_STRING (lp_ssl_hosts_resign, &Globals.sslHostsResign); +FN_GLOBAL_STRING (lp_ssl_cacertdir, &Globals.sslCaCertDir); +FN_GLOBAL_STRING (lp_ssl_cacertfile, &Globals.sslCaCertFile); +FN_GLOBAL_STRING (lp_ssl_cert, &Globals.sslCert); +FN_GLOBAL_STRING (lp_ssl_privkey, &Globals.sslPrivKey); +FN_GLOBAL_STRING (lp_ssl_client_cert, &Globals.sslClientCert); +FN_GLOBAL_STRING (lp_ssl_client_privkey, &Globals.sslClientPrivKey); +FN_GLOBAL_STRING (lp_ssl_ciphers, &Globals.sslCiphers); +FN_GLOBAL_BOOL (lp_ssl_enabled, &Globals.sslEnabled); +FN_GLOBAL_BOOL (lp_ssl_reqClientCert, &Globals.sslReqClientCert); +FN_GLOBAL_BOOL (lp_ssl_reqServerCert, &Globals.sslReqServerCert); +FN_GLOBAL_BOOL (lp_ssl_compatibility, &Globals.sslCompatibility); +#endif /* WITH_SSL */ + +FN_GLOBAL_BOOL (lp_dns_proxy, &Globals.bDNSproxy) +FN_GLOBAL_BOOL (lp_wins_support, &Globals.bWINSsupport) +FN_GLOBAL_BOOL (lp_we_are_a_wins_server, &Globals.bWINSsupport) +FN_GLOBAL_BOOL (lp_wins_proxy, &Globals.bWINSproxy) +FN_GLOBAL_BOOL (lp_local_master, &Globals.bLocalMaster) +FN_GLOBAL_BOOL (lp_domain_master, &Globals.bDomainMaster) +FN_GLOBAL_BOOL (lp_domain_logons, &Globals.bDomainLogons) +FN_GLOBAL_BOOL (lp_preferred_master, &Globals.bPreferredMaster) +FN_GLOBAL_BOOL (lp_use_rhosts, &Globals.bUseRhosts) +FN_GLOBAL_BOOL (lp_readprediction, &Globals.bReadPrediction) +FN_GLOBAL_BOOL (lp_readbmpx, &Globals.bReadbmpx) +FN_GLOBAL_BOOL (lp_readraw, &Globals.bReadRaw) +FN_GLOBAL_BOOL (lp_writeraw, &Globals.bWriteRaw) +FN_GLOBAL_BOOL (lp_null_passwords, &Globals.bNullPasswords) +FN_GLOBAL_BOOL (lp_strip_dot, &Globals.bStripDot) +FN_GLOBAL_BOOL (lp_encrypted_passwords, &Globals.bEncryptPasswords) +FN_GLOBAL_BOOL (lp_update_encrypted, &Globals.bUpdateEncrypt) +FN_GLOBAL_BOOL (lp_syslog_only, &Globals.bSyslogOnly) +FN_GLOBAL_BOOL (lp_timestamp_logs, &Globals.bTimestampLogs) +FN_GLOBAL_BOOL (lp_browse_list, &Globals.bBrowseList) +FN_GLOBAL_BOOL (lp_unix_realname, &Globals.bUnixRealname) +FN_GLOBAL_BOOL (lp_nis_home_map, &Globals.bNISHomeMap) +#if 0 + static FN_GLOBAL_BOOL (lp_time_server, &Globals.bTimeServer) +#endif /* 0 */ +FN_GLOBAL_BOOL (lp_bind_interfaces_only, &Globals.bBindInterfacesOnly) +FN_GLOBAL_BOOL (lp_passwd_chat_debug, &Globals.bPasswdChatDebug) +FN_GLOBAL_BOOL (lp_ole_locking_compat, &Globals.bOleLockingCompat) +FN_GLOBAL_BOOL (lp_nt_smb_support, &Globals.bNTSmbSupport) +FN_GLOBAL_BOOL (lp_nt_pipe_support, &Globals.bNTPipeSupport) +FN_GLOBAL_BOOL (lp_nt_acl_support, &Globals.bNTAclSupport) +FN_GLOBAL_BOOL (lp_stat_cache, &Globals.bStatCache) +FN_GLOBAL_BOOL (lp_allow_trusted_domains, &Globals.bAllowTrustedDomains) +FN_GLOBAL_BOOL (lp_restrict_anonymous, &Globals.bRestrictAnonymous) +FN_GLOBAL_INTEGER (lp_os_level, &Globals.os_level) +FN_GLOBAL_INTEGER (lp_max_ttl, &Globals.max_ttl) +FN_GLOBAL_INTEGER (lp_max_wins_ttl, &Globals.max_wins_ttl) +FN_GLOBAL_INTEGER (lp_min_wins_ttl, &Globals.min_wins_ttl) +FN_GLOBAL_INTEGER (lp_maxxmit, &Globals.max_xmit) +FN_GLOBAL_INTEGER (lp_maxmux, &Globals.max_mux) +FN_GLOBAL_INTEGER (lp_passwordlevel, &Globals.pwordlevel) +FN_GLOBAL_INTEGER (lp_usernamelevel, &Globals.unamelevel) +FN_GLOBAL_INTEGER (lp_readsize, &Globals.ReadSize) +FN_GLOBAL_INTEGER (lp_deadtime, &Globals.deadtime) +FN_GLOBAL_INTEGER (lp_maxprotocol, &Globals.maxprotocol) +FN_GLOBAL_INTEGER (lp_security, &Globals.security) +FN_GLOBAL_INTEGER (lp_maxdisksize, &Globals.maxdisksize) +FN_GLOBAL_INTEGER (lp_client_code_page, &Globals.client_code_page) +#if 0 + static FN_GLOBAL_INTEGER (lp_announce_as, &Globals.announce_as) +#endif +FN_GLOBAL_INTEGER (lp_lm_announce, &Globals.lm_announce) +FN_GLOBAL_INTEGER (lp_lm_interval, &Globals.lm_interval) +FN_GLOBAL_INTEGER (lp_machine_password_timeout, &Globals.machine_password_timeout) +FN_GLOBAL_INTEGER (lp_change_notify_timeout, &Globals.change_notify_timeout) +FN_GLOBAL_INTEGER (lp_stat_cache_size, &Globals.stat_cache_size) +FN_GLOBAL_INTEGER (lp_map_to_guest, &Globals.map_to_guest) +FN_GLOBAL_INTEGER (lp_min_passwd_length, &Globals.min_passwd_length) +FN_GLOBAL_INTEGER (lp_oplock_break_wait_time, &Globals.oplock_break_wait_time) +#ifdef WITH_LDAP +FN_GLOBAL_INTEGER (lp_ldap_port, &Globals.ldap_port) +#endif /* WITH_LDAP */ +FN_LOCAL_STRING (lp_preexec, szPreExec) +FN_LOCAL_STRING (lp_postexec, szPostExec) +FN_LOCAL_STRING (lp_rootpreexec, szRootPreExec) +FN_LOCAL_STRING (lp_rootpostexec, szRootPostExec) +FN_LOCAL_STRING (lp_servicename, szService) +FN_LOCAL_STRING (lp_pathname, szPath) +FN_LOCAL_STRING (lp_dontdescend, szDontdescend) +FN_LOCAL_STRING (lp_username, szUsername) +FN_LOCAL_STRING (lp_guestaccount, szGuestaccount) +FN_LOCAL_STRING (lp_invalid_users, szInvalidUsers) +FN_LOCAL_STRING (lp_valid_users, szValidUsers) +FN_LOCAL_STRING (lp_admin_users, szAdminUsers) +#if 0 +FN_LOCAL_STRING (lp_printcommand, szPrintcommand) +FN_LOCAL_STRING (lp_lpqcommand, szLpqcommand) +FN_LOCAL_STRING (lp_lprmcommand, szLprmcommand) +FN_LOCAL_STRING (lp_lppausecommand, szLppausecommand) +FN_LOCAL_STRING (lp_lpresumecommand, szLpresumecommand) +FN_LOCAL_STRING (lp_queuepausecommand, szQueuepausecommand) +FN_LOCAL_STRING (lp_queueresumecommand, szQueueresumecommand) +FN_LOCAL_STRING (lp_printername, szPrintername) +FN_LOCAL_STRING (lp_printerdriver, szPrinterDriver) +#endif /* 0 */ +FN_LOCAL_STRING (lp_hostsallow, szHostsallow) +FN_LOCAL_STRING (lp_hostsdeny, szHostsdeny) +FN_LOCAL_STRING (lp_magicscript, szMagicScript) +FN_LOCAL_STRING (lp_magicoutput, szMagicOutput) +FN_LOCAL_STRING (lp_comment, comment) +FN_LOCAL_STRING (lp_force_user, force_user) +FN_LOCAL_STRING (lp_force_group, force_group) +FN_LOCAL_STRING (lp_readlist, readlist) +FN_LOCAL_STRING (lp_writelist, writelist) +FN_LOCAL_STRING (lp_fstype, fstype) +#if 0 + static FN_LOCAL_STRING (lp_volume, volume) +#endif +FN_LOCAL_STRING (lp_mangled_map, szMangledMap) +FN_LOCAL_STRING (lp_veto_files, szVetoFiles) +FN_LOCAL_STRING (lp_hide_files, szHideFiles) +FN_LOCAL_STRING (lp_veto_oplocks, szVetoOplockFiles) +FN_LOCAL_BOOL (lp_revalidate, bRevalidate) +FN_LOCAL_BOOL (lp_casesensitive, bCaseSensitive) +FN_LOCAL_BOOL (lp_preservecase, bCasePreserve) +FN_LOCAL_BOOL (lp_shortpreservecase, bShortCasePreserve) +FN_LOCAL_BOOL (lp_casemangle, bCaseMangle) +FN_LOCAL_BOOL (lp_status, status) +FN_LOCAL_BOOL (lp_hide_dot_files, bHideDotFiles) +FN_LOCAL_BOOL (lp_browseable, bBrowseable) +FN_LOCAL_BOOL (lp_readonly, bRead_only) +FN_LOCAL_BOOL (lp_no_set_dir, bNo_set_dir) +FN_LOCAL_BOOL (lp_guest_ok, bGuest_ok) +FN_LOCAL_BOOL (lp_guest_only, bGuest_only) +FN_LOCAL_BOOL (lp_print_ok, bPrint_ok) +FN_LOCAL_BOOL (lp_postscript, bPostscript) +FN_LOCAL_BOOL (lp_map_hidden, bMap_hidden) +FN_LOCAL_BOOL (lp_map_archive, bMap_archive) +FN_LOCAL_BOOL (lp_locking, bLocking) +FN_LOCAL_BOOL (lp_strict_locking, bStrictLocking) +FN_LOCAL_BOOL (lp_share_modes, bShareModes) +FN_LOCAL_BOOL (lp_oplocks, bOpLocks) +FN_LOCAL_BOOL (lp_onlyuser, bOnlyUser) +FN_LOCAL_BOOL (lp_manglednames, bMangledNames) +FN_LOCAL_BOOL (lp_widelinks, bWidelinks) +FN_LOCAL_BOOL (lp_symlinks, bSymlinks) +FN_LOCAL_BOOL (lp_syncalways, bSyncAlways) +FN_LOCAL_BOOL (lp_strict_sync, bStrictSync) +FN_LOCAL_BOOL (lp_map_system, bMap_system) +FN_LOCAL_BOOL (lp_delete_readonly, bDeleteReadonly) +FN_LOCAL_BOOL (lp_fake_oplocks, bFakeOplocks) +FN_LOCAL_BOOL (lp_recursive_veto_delete, bDeleteVetoFiles) +FN_LOCAL_BOOL (lp_dos_filetimes, bDosFiletimes) +FN_LOCAL_BOOL (lp_dos_filetime_resolution, bDosFiletimeResolution) +FN_LOCAL_BOOL (lp_fake_dir_create_times, bFakeDirCreateTimes) +FN_LOCAL_BOOL (lp_blocking_locks, bBlockingLocks) +FN_LOCAL_BOOL (lp_mangle_locks, bMangleLocks) +FN_LOCAL_INTEGER (lp_create_mode, iCreate_mask) +FN_LOCAL_INTEGER (lp_force_create_mode, iCreate_force_mode) +FN_LOCAL_INTEGER (lp_dir_mode, iDir_mask) +FN_LOCAL_INTEGER (lp_force_dir_mode, iDir_force_mode) +FN_LOCAL_INTEGER (lp_max_connections, iMaxConnections) +FN_LOCAL_INTEGER (lp_defaultcase, iDefaultCase) +FN_LOCAL_INTEGER (lp_minprintspace, iMinPrintSpace) +FN_LOCAL_INTEGER (lp_printing, iPrinting) +FN_LOCAL_INTEGER (lp_oplock_contention_limit, iOplockContentionLimit) +FN_LOCAL_CHAR (lp_magicchar, magic_char) +/* local prototypes */ + static int strwicmp (const char *psz1, const char *psz2); + static int map_parameter (const char *pszParmName); + static BOOL set_boolean (BOOL * pb, const char *pszParmValue); + static int getservicebyname (const char *pszServiceName, service * pserviceDest); + static void copy_service (service * pserviceDest, + service * pserviceSource, BOOL * pcopymapDest); + static BOOL service_ok (int iService); + static BOOL do_parameter (const char *pszParmName, const char *pszParmValue); + static BOOL do_section (const char *pszSectionName); + static void init_copymap (service * pservice); + + +/*************************************************************************** +initialise a service to the defaults +***************************************************************************/ + static void init_service (service * pservice) +{ + memset ((char *) pservice, '\0', sizeof (service)); + copy_service (pservice, &sDefault, NULL); +} + + +/*************************************************************************** +free the dynamically allocated parts of a service struct +***************************************************************************/ +static void +free_service (service * pservice) +{ + int i; + if (!pservice) + return; + + if (pservice->szService) + DEBUG (5, ("free_service: Freeing service %s\n", pservice->szService)); + + string_free (&pservice->szService); + if (pservice->copymap) + { + free (pservice->copymap); + pservice->copymap = NULL; + } + + for (i = 0; parm_table[i].label; i++) + if ((parm_table[i].type == P_STRING || + parm_table[i].type == P_USTRING) && parm_table[i].class == P_LOCAL) + string_free ((char **) (((char *) pservice) + PTR_DIFF (parm_table[i].ptr, &sDefault))); +} + +/*************************************************************************** +add a new service to the services array initialising it with the given +service +***************************************************************************/ +static int +add_a_service (service * pservice, const char *name) +{ + int i; + service tservice; + int num_to_alloc = iNumServices + 1; + + tservice = *pservice; + + /* it might already exist */ + if (name) + { + i = getservicebyname (name, NULL); + if (i >= 0) + return (i); + } + + /* find an invalid one */ + for (i = 0; i < iNumServices; i++) + if (!pSERVICE (i)->valid) + break; + + /* if not, then create one */ + if (i == iNumServices) + { + ServicePtrs = (service **) Realloc (ServicePtrs, sizeof (service *) * num_to_alloc); + if (ServicePtrs) + pSERVICE (iNumServices) = (service *) malloc (sizeof (service)); + + if (!ServicePtrs || !pSERVICE (iNumServices)) + return (-1); + + iNumServices++; + } + else + free_service (pSERVICE (i)); + + pSERVICE (i)->valid = True; + + init_service (pSERVICE (i)); + copy_service (pSERVICE (i), &tservice, NULL); + if (name) + string_set (&iSERVICE (i).szService, name); + + return (i); +} + +/*************************************************************************** +add a new home service, with the specified home directory, defaults coming +from service ifrom +***************************************************************************/ +BOOL +lp_add_home (const char *pszHomename, int iDefaultService, const char *pszHomedir) +{ + int i = add_a_service (pSERVICE (iDefaultService), pszHomename); + + if (i < 0) + return (False); + + if (!(*(iSERVICE (i).szPath)) || strequal (iSERVICE (i).szPath, lp_pathname (-1))) + string_set (&iSERVICE (i).szPath, pszHomedir); + if (!(*(iSERVICE (i).comment))) + { + pstring comment; + slprintf (comment, sizeof (comment) - 1, "Home directory of %s", pszHomename); + string_set (&iSERVICE (i).comment, comment); + } + iSERVICE (i).bAvailable = sDefault.bAvailable; + iSERVICE (i).bBrowseable = sDefault.bBrowseable; + + DEBUG (3, ("adding home directory %s at %s\n", pszHomename, pszHomedir)); + + return (True); +} + +/*************************************************************************** +add a new service, based on an old one +***************************************************************************/ +int +lp_add_service (char *pszService, int iDefaultService) +{ + return (add_a_service (pSERVICE (iDefaultService), pszService)); +} + +#if 0 +/*************************************************************************** +add the IPC service +***************************************************************************/ +static BOOL +lp_add_ipc (void) +{ + pstring comment; + int i = add_a_service (&sDefault, "IPC$"); + + if (i < 0) + return (False); + + slprintf (comment, sizeof (comment) - 1, "IPC Service (%s)", Globals.szServerString); + + string_set (&iSERVICE (i).szPath, tmpdir ()); + string_set (&iSERVICE (i).szUsername, ""); + string_set (&iSERVICE (i).comment, comment); + string_set (&iSERVICE (i).fstype, "IPC"); + iSERVICE (i).status = False; + iSERVICE (i).iMaxConnections = 0; + iSERVICE (i).bAvailable = True; + iSERVICE (i).bRead_only = True; + iSERVICE (i).bGuest_only = False; + iSERVICE (i).bGuest_ok = True; + iSERVICE (i).bPrint_ok = False; + iSERVICE (i).bBrowseable = sDefault.bBrowseable; + + DEBUG (3, ("adding IPC service\n")); + + return (True); +} +#endif /* 0 */ + +/*************************************************************************** +Do a case-insensitive, whitespace-ignoring string compare. +***************************************************************************/ +static int +strwicmp (const char *psz1, const char *psz2) +{ + /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */ + /* appropriate value. */ + if (psz1 == psz2) + return (0); + else if (psz1 == NULL) + return (-1); + else if (psz2 == NULL) + return (1); + + /* sync the strings on first non-whitespace */ + while (1) + { + while (isspace ((unsigned char) *psz1)) + psz1++; + while (isspace ((unsigned char) *psz2)) + psz2++; + if (toupper ((unsigned char) *psz1) != toupper ((unsigned char) *psz2) || *psz1 == '\0' + || *psz2 == '\0') + break; + psz1++; + psz2++; + } + return (*psz1 - *psz2); +} + +/*************************************************************************** +Map a parameter's string representation to something we can use. +Returns False if the parameter string is not recognised, else TRUE. +***************************************************************************/ +static int +map_parameter (const char *pszParmName) +{ + int iIndex; + + if (*pszParmName == '-') + return (-1); + + for (iIndex = 0; parm_table[iIndex].label; iIndex++) + if (strwicmp (parm_table[iIndex].label, pszParmName) == 0) + return (iIndex); + + DEBUG (0, ("Unknown parameter encountered: \"%s\"\n", pszParmName)); + return (-1); +} + + +/*************************************************************************** +Set a boolean variable from the text value stored in the passed string. +Returns True in success, False if the passed string does not correctly +represent a boolean. +***************************************************************************/ +static BOOL +set_boolean (BOOL * pb, const char *pszParmValue) +{ + BOOL bRetval; + + bRetval = True; + if (strwicmp (pszParmValue, "yes") == 0 || + strwicmp (pszParmValue, "true") == 0 || strwicmp (pszParmValue, "1") == 0) + *pb = True; + else if (strwicmp (pszParmValue, "no") == 0 || + strwicmp (pszParmValue, "False") == 0 || strwicmp (pszParmValue, "0") == 0) + *pb = False; + else + { + DEBUG (0, ("ERROR: Badly formed boolean in configuration file: \"%s\".\n", pszParmValue)); + bRetval = False; + } + return (bRetval); +} + +/*************************************************************************** +Find a service by name. Otherwise works like get_service. +***************************************************************************/ +static int +getservicebyname (const char *pszServiceName, service * pserviceDest) +{ + int iService; + + for (iService = iNumServices - 1; iService >= 0; iService--) + if (VALID (iService) && strwicmp (iSERVICE (iService).szService, pszServiceName) == 0) + { + if (pserviceDest != NULL) + copy_service (pserviceDest, pSERVICE (iService), NULL); + break; + } + + return (iService); +} + + + +/*************************************************************************** +Copy a service structure to another + +If pcopymapDest is NULL then copy all fields +***************************************************************************/ +static void +copy_service (service * pserviceDest, service * pserviceSource, BOOL * pcopymapDest) +{ + int i; + BOOL bcopyall = (pcopymapDest == NULL); + + for (i = 0; parm_table[i].label; i++) + if (parm_table[i].ptr && parm_table[i].class == P_LOCAL && (bcopyall || pcopymapDest[i])) + { + void *def_ptr = parm_table[i].ptr; + void *src_ptr = ((char *) pserviceSource) + PTR_DIFF (def_ptr, &sDefault); + void *dest_ptr = ((char *) pserviceDest) + PTR_DIFF (def_ptr, &sDefault); + + switch (parm_table[i].type) + { + case P_BOOL: + case P_BOOLREV: + *(BOOL *) dest_ptr = *(BOOL *) src_ptr; + break; + + case P_INTEGER: + case P_ENUM: + case P_OCTAL: + *(int *) dest_ptr = *(int *) src_ptr; + break; + + case P_CHAR: + *(char *) dest_ptr = *(char *) src_ptr; + break; + + case P_STRING: + string_set (dest_ptr, *(char **) src_ptr); + break; + + case P_USTRING: + string_set (dest_ptr, *(char **) src_ptr); + strupper (*(char **) dest_ptr); + break; + default: + break; + } + } + + if (bcopyall) + { + init_copymap (pserviceDest); + if (pserviceSource->copymap) + memcpy ((void *) pserviceDest->copymap, + (void *) pserviceSource->copymap, sizeof (BOOL) * NUMPARAMETERS); + } +} + +/*************************************************************************** +Check a service for consistency. Return False if the service is in any way +incomplete or faulty, else True. +***************************************************************************/ +static BOOL +service_ok (int iService) +{ + BOOL bRetval; + + bRetval = True; + if (iSERVICE (iService).szService[0] == '\0') + { + DEBUG (0, ("The following message indicates an internal error:\n")); + DEBUG (0, ("No service name in service entry.\n")); + bRetval = False; + } + + /* The [printers] entry MUST be printable. I'm all for flexibility, but */ + /* I can't see why you'd want a non-printable printer service... */ + if (strwicmp (iSERVICE (iService).szService, PRINTERS_NAME) == 0) + if (!iSERVICE (iService).bPrint_ok) + { + DEBUG (0, ("WARNING: [%s] service MUST be printable!\n", + iSERVICE (iService).szService)); + iSERVICE (iService).bPrint_ok = True; + } + + if (iSERVICE (iService).szPath[0] == '\0' && + strwicmp (iSERVICE (iService).szService, HOMES_NAME) != 0) + { + DEBUG (0, ("No path in service %s - using %s\n", iSERVICE (iService).szService, tmpdir ())); + string_set (&iSERVICE (iService).szPath, tmpdir ()); + } + + /* If a service is flagged unavailable, log the fact at level 0. */ + if (!iSERVICE (iService).bAvailable) + DEBUG (1, ("NOTE: Service %s is flagged unavailable.\n", iSERVICE (iService).szService)); + + return (bRetval); +} + +#if 0 +static struct file_lists +{ + struct file_lists *next; + char *name; + time_t modtime; +} *file_lists = NULL; + +/******************************************************************* +keep a linked list of all config files so we know when one has changed +it's date and needs to be reloaded +********************************************************************/ +static void +add_to_file_list (const char *fname) +{ + struct file_lists *f = file_lists; + + while (f) + { + if (f->name && !strcmp (f->name, fname)) + break; + f = f->next; + } + + if (!f) + { + f = (struct file_lists *) malloc (sizeof (file_lists[0])); + if (!f) + return; + f->next = file_lists; + f->name = strdup (fname); + if (!f->name) + { + free (f); + return; + } + file_lists = f; + } + + { + pstring n2; + pstrcpy (n2, fname); + standard_sub_basic (n2); + f->modtime = file_modtime (n2); + } + +} + + +/******************************************************************* +check if a config file has changed date +********************************************************************/ +BOOL +lp_file_list_changed (void) +{ + struct file_lists *f = file_lists; + DEBUG (6, ("lp_file_list_changed()\n")); + + while (f) + { + pstring n2; + time_t mod_time; + + pstrcpy (n2, f->name); + standard_sub_basic (n2); + + DEBUGADD (6, ("file %s -> %s last mod_time: %s\n", f->name, n2, ctime (&f->modtime))); + + mod_time = file_modtime (n2); + + if (f->modtime != mod_time) + { + DEBUGADD (6, ("file %s modified: %s\n", n2, ctime (&mod_time))); + f->modtime = mod_time; + return (True); + } + f = f->next; + } + return (False); +} +#else +#define add_to_file_list(x) +#endif /* 0 */ + +/*************************************************************************** + handle the interpretation of the coding system parameter + *************************************************************************/ +static BOOL +handle_coding_system (const char *pszParmValue, char **ptr) +{ + string_set (ptr, pszParmValue); + interpret_coding_system (pszParmValue); + return (True); +} + +/*************************************************************************** +handle the interpretation of the character set system parameter +***************************************************************************/ +static BOOL +handle_character_set (const char *pszParmValue, char **ptr) +{ + string_set (ptr, pszParmValue); + interpret_character_set (pszParmValue); + return (True); +} + + +/*************************************************************************** +handle the valid chars lines +***************************************************************************/ +static BOOL +handle_valid_chars (const char *pszParmValue, char **ptr) +{ + string_set (ptr, pszParmValue); + + /* A dependency here is that the parameter client code page must be + set before this is called - as calling codepage_initialise() + would overwrite the valid char lines. + */ + codepage_initialise (lp_client_code_page ()); + + add_char_string (pszParmValue); + return (True); +} + + +/*************************************************************************** +handle the include operation +***************************************************************************/ +static BOOL +handle_include (const char *pszParmValue, char **ptr) +{ + pstring fname; + pstrcpy (fname, pszParmValue); + + add_to_file_list (fname); + + standard_sub_basic (fname); + + string_set (ptr, fname); + + if (file_exist (fname, NULL)) + return (pm_process (fname, do_section, do_parameter)); + + DEBUG (2, ("Cannot find include file %s\n", fname)); + + return (False); +} + + +/*************************************************************************** +handle the interpretation of the copy parameter +***************************************************************************/ +static BOOL +handle_copy (const char *pszParmValue, char **ptr) +{ + BOOL bRetval; + int iTemp; + service serviceTemp; + + string_set (ptr, pszParmValue); + + init_service (&serviceTemp); + + bRetval = False; + + DEBUG (3, ("Copying service from service %s\n", pszParmValue)); + + if ((iTemp = getservicebyname (pszParmValue, &serviceTemp)) >= 0) + { + if (iTemp == iServiceIndex) + { + DEBUG (0, ("Cannot copy service %s - unable to copy self!\n", pszParmValue)); + } + else + { + copy_service (pSERVICE (iServiceIndex), &serviceTemp, iSERVICE (iServiceIndex).copymap); + bRetval = True; + } + } + else + { + DEBUG (0, ("Unable to copy service - source not found: %s\n", pszParmValue)); + bRetval = False; + } + + free_service (&serviceTemp); + return (bRetval); +} + + +/*************************************************************************** +initialise a copymap +***************************************************************************/ +static void +init_copymap (service * pservice) +{ + size_t i; + if (pservice->copymap) + free (pservice->copymap); + pservice->copymap = (BOOL *) malloc (sizeof (BOOL) * NUMPARAMETERS); + if (!pservice->copymap) + DEBUG (0, ("Couldn't allocate copymap!! (size %d)\n", (int) NUMPARAMETERS)); + else + for (i = 0; i < NUMPARAMETERS; i++) + pservice->copymap[i] = True; +} + + +/*************************************************************************** + return the local pointer to a parameter given the service number and the + pointer into the default structure +***************************************************************************/ +void * +lp_local_ptr (int snum, void *ptr) +{ + return (void *) (((char *) pSERVICE (snum)) + PTR_DIFF (ptr, &sDefault)); +} + +/*************************************************************************** +Process a parameter for a particular service number. If snum < 0 +then assume we are in the globals +***************************************************************************/ +BOOL +lp_do_parameter (int snum, const char *pszParmName, const char *pszParmValue) +{ + int parmnum, i; + void *parm_ptr = NULL; /* where we are going to store the result */ + void *def_ptr = NULL; + + parmnum = map_parameter (pszParmName); + + if (parmnum < 0) + { + DEBUG (0, ("Ignoring unknown parameter \"%s\"\n", pszParmName)); + return (True); + } + + if (parm_table[parmnum].flags & FLAG_DEPRECATED) + { + DEBUG (1, ("WARNING: The \"%s\"option is deprecated\n", pszParmName)); + } + + def_ptr = parm_table[parmnum].ptr; + + /* we might point at a service, the default service or a global */ + if (snum < 0) + { + parm_ptr = def_ptr; + } + else + { + if (parm_table[parmnum].class == P_GLOBAL) + { + DEBUG (0, ("Global parameter %s found in service section!\n", pszParmName)); + return (True); + } + parm_ptr = ((char *) pSERVICE (snum)) + PTR_DIFF (def_ptr, &sDefault); + } + + if (snum >= 0) + { + if (!iSERVICE (snum).copymap) + init_copymap (pSERVICE (snum)); + + /* this handles the aliases - set the copymap for other entries with + the same data pointer */ + for (i = 0; parm_table[i].label; i++) + if (parm_table[i].ptr == parm_table[parmnum].ptr) + iSERVICE (snum).copymap[i] = False; + } + + /* if it is a special case then go ahead */ + if (parm_table[parmnum].special) + { + parm_table[parmnum].special (pszParmValue, (char **) parm_ptr); + return (True); + } + + /* now switch on the type of variable it is */ + switch (parm_table[parmnum].type) + { + case P_BOOL: + set_boolean (parm_ptr, pszParmValue); + break; + + case P_BOOLREV: + set_boolean (parm_ptr, pszParmValue); + *(BOOL *) parm_ptr = !*(BOOL *) parm_ptr; + break; + + case P_INTEGER: + *(int *) parm_ptr = atoi (pszParmValue); + break; + + case P_CHAR: + *(char *) parm_ptr = *pszParmValue; + break; + + case P_OCTAL: + sscanf (pszParmValue, "%o", (int *) parm_ptr); + break; + + case P_STRING: + string_set (parm_ptr, pszParmValue); + break; + + case P_USTRING: + string_set (parm_ptr, pszParmValue); + strupper (*(char **) parm_ptr); + break; + + case P_GSTRING: + pstrcpy ((char *) parm_ptr, pszParmValue); + break; + + case P_UGSTRING: + pstrcpy ((char *) parm_ptr, pszParmValue); + strupper ((char *) parm_ptr); + break; + + case P_ENUM: + for (i = 0; parm_table[parmnum].enum_list[i].name; i++) + { + if (strequal (pszParmValue, parm_table[parmnum].enum_list[i].name)) + { + *(int *) parm_ptr = parm_table[parmnum].enum_list[i].value; + break; + } + } + break; + case P_SEP: + break; + } + + return (True); +} + +/*************************************************************************** +Process a parameter. +***************************************************************************/ +static BOOL +do_parameter (const char *pszParmName, const char *pszParmValue) +{ + if (!bInGlobalSection && bGlobalOnly) + return (True); + + DEBUGADD (3, ("doing parameter %s = %s\n", pszParmName, pszParmValue)); + + return (lp_do_parameter (bInGlobalSection ? -2 : iServiceIndex, pszParmName, pszParmValue)); +} + +#if 0 +/*************************************************************************** +check if two parameters are equal +***************************************************************************/ +static BOOL +equal_parameter (parm_type type, void *ptr1, void *ptr2) +{ + switch (type) + { + case P_BOOL: + case P_BOOLREV: + return (*((BOOL *) ptr1) == *((BOOL *) ptr2)); + + case P_INTEGER: + case P_ENUM: + case P_OCTAL: + return (*((int *) ptr1) == *((int *) ptr2)); + + case P_CHAR: + return (*((char *) ptr1) == *((char *) ptr2)); + + case P_GSTRING: + case P_UGSTRING: + { + char *p1 = (char *) ptr1, *p2 = (char *) ptr2; + if (p1 && !*p1) + p1 = NULL; + if (p2 && !*p2) + p2 = NULL; + return (p1 == p2 || strequal (p1, p2)); + } + case P_STRING: + case P_USTRING: + { + char *p1 = *(char **) ptr1, *p2 = *(char **) ptr2; + if (p1 && !*p1) + p1 = NULL; + if (p2 && !*p2) + p2 = NULL; + return (p1 == p2 || strequal (p1, p2)); + } + case P_SEP: + break; + } + return (False); +} +#endif /* 0 */ + +/*************************************************************************** +Process a new section (service). At this stage all sections are services. +Later we'll have special sections that permit server parameters to be set. +Returns True on success, False on failure. +***************************************************************************/ +static BOOL +do_section (const char *pszSectionName) +{ + BOOL bRetval; + BOOL isglobal = ((strwicmp (pszSectionName, GLOBAL_NAME) == 0) || + (strwicmp (pszSectionName, GLOBAL_NAME2) == 0)); + bRetval = False; + + /* if we were in a global section then do the local inits */ + if (bInGlobalSection && !isglobal) + { + init_locals (); + } + + /* if we've just struck a global section, note the fact. */ + bInGlobalSection = isglobal; + + /* check for multiple global sections */ + if (bInGlobalSection) + { + DEBUG (3, ("Processing section \"[%s]\"\n", pszSectionName)); + return (True); + } + + if (!bInGlobalSection && bGlobalOnly) + return (True); + + /* if we have a current service, tidy it up before moving on */ + bRetval = True; + + if (iServiceIndex >= 0) + bRetval = service_ok (iServiceIndex); + + /* if all is still well, move to the next record in the services array */ + if (bRetval) + { + /* We put this here to avoid an odd message order if messages are */ + /* issued by the post-processing of a previous section. */ + DEBUG (2, ("Processing section \"[%s]\"\n", pszSectionName)); + + if ((iServiceIndex = add_a_service (&sDefault, pszSectionName)) < 0) + { + DEBUG (0, ("Failed to add a new service\n")); + return (False); + } + } + + return (bRetval); +} + +#if 0 +/*************************************************************************** +return True if a local parameter is currently set to the global default +***************************************************************************/ +BOOL +lp_is_default (int snum, struct parm_struct * parm) +{ + int pdiff = PTR_DIFF (parm->ptr, &sDefault); + + return equal_parameter (parm->type, + ((char *) pSERVICE (snum)) + pdiff, ((char *) &sDefault) + pdiff); +} +#endif /* 0 */ +#if 0 +/*************************************************************************** +return info about the next service in a service. snum==-1 gives the globals + +return NULL when out of parameters +***************************************************************************/ +struct parm_struct * +lp_next_parameter (int snum, int *i, int allparameters) +{ + if (snum == -1) + { + /* do the globals */ + for (; parm_table[*i].label; (*i)++) + { + if (parm_table[*i].class == P_SEPARATOR) + return &parm_table[(*i)++]; + + if (!parm_table[*i].ptr || (*parm_table[*i].label == '-')) + continue; + + if ((*i) > 0 && (parm_table[*i].ptr == parm_table[(*i) - 1].ptr)) + continue; + + return &parm_table[(*i)++]; + } + } + else + { + service *pService = pSERVICE (snum); + + for (; parm_table[*i].label; (*i)++) + { + if (parm_table[*i].class == P_SEPARATOR) + return &parm_table[(*i)++]; + + if (parm_table[*i].class == P_LOCAL && + parm_table[*i].ptr && + (*parm_table[*i].label != '-') && + ((*i) == 0 || (parm_table[*i].ptr != parm_table[(*i) - 1].ptr))) + { + int pdiff = PTR_DIFF (parm_table[*i].ptr, &sDefault); + + if (allparameters || + !equal_parameter (parm_table[*i].type, + ((char *) pService) + pdiff, ((char *) &sDefault) + pdiff)) + { + return &parm_table[(*i)++]; + } + } + } + } + + return NULL; +} +#endif /* 0 */ +#if 0 +/*************************************************************************** +Return TRUE if the passed service number is within range. +***************************************************************************/ +BOOL +lp_snum_ok (int iService) +{ + return (LP_SNUM_OK (iService) && iSERVICE (iService).bAvailable); +} +#endif /* 0 */ + +/*************************************************************************** +auto-load some home services +***************************************************************************/ +static void +lp_add_auto_services (char *str) +{ + char *s; + char *p; + int homes; + + if (!str) + return; + + s = strdup (str); + if (!s) + return; + + homes = lp_servicenumber (HOMES_NAME); + + for (p = strtok (s, LIST_SEP); p; p = strtok (NULL, LIST_SEP)) + { + const char *home = get_home_dir (p); + + if (lp_servicenumber (p) >= 0) + continue; + + if (home && homes >= 0) + { + lp_add_home (p, homes, home); + } + } + free (s); +} + + +/*************************************************************************** +have we loaded a services file yet? +***************************************************************************/ +BOOL +lp_loaded (void) +{ + return (bLoaded); +} + +#if 0 +/*************************************************************************** +unload unused services +***************************************************************************/ +void +lp_killunused (BOOL (*snumused) (int)) +{ + int i; + for (i = 0; i < iNumServices; i++) + if (VALID (i) && (!snumused || !snumused (i))) + { + iSERVICE (i).valid = False; + free_service (pSERVICE (i)); + } +} +#endif /* 0 */ +#if 0 +/*************************************************************************** +save the curent values of all global and sDefault parameters into the +defaults union. This allows swat and testparm to show only the +changed (ie. non-default) parameters. +***************************************************************************/ +static void +lp_save_defaults (void) +{ + static BOOL defaults_saved = False; + int i; + + for (i = 0; parm_table[i].label; i++) + { + if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr) + continue; + switch (parm_table[i].type) + { + case P_STRING: + case P_USTRING: + parm_table[i].def.svalue = strdup (*(char **) parm_table[i].ptr); + break; + case P_GSTRING: + case P_UGSTRING: + parm_table[i].def.svalue = strdup ((char *) parm_table[i].ptr); + break; + case P_BOOL: + case P_BOOLREV: + parm_table[i].def.bvalue = *(BOOL *) parm_table[i].ptr; + break; + case P_CHAR: + parm_table[i].def.cvalue = *(char *) parm_table[i].ptr; + break; + case P_INTEGER: + case P_OCTAL: + case P_ENUM: + parm_table[i].def.ivalue = *(int *) parm_table[i].ptr; + break; + case P_SEP: + break; + } + } + defaults_saved = True; +} +#endif /* 0 */ + +/*************************************************************************** +Load the services array from the services file. Return True on success, +False on failure. +***************************************************************************/ +BOOL +lp_load (const char *pszFname, BOOL global_only, BOOL save_defaults, BOOL add_ipc) +{ + pstring n2; + BOOL bRetval; + + add_to_file_list (pszFname); + + bRetval = False; + + bInGlobalSection = True; + bGlobalOnly = global_only; + + init_globals (); +#if 0 + if (save_defaults) + { + init_locals (); + lp_save_defaults (); + } +#else + (void) &save_defaults; +#endif /* 0 */ + pstrcpy (n2, pszFname); + standard_sub_basic (n2); + + /* We get sections first, so have to start 'behind' to make up */ + iServiceIndex = -1; + bRetval = pm_process (n2, do_section, do_parameter); + + /* finish up the last section */ + DEBUG (3, ("pm_process() returned %s\n", BOOLSTR (bRetval))); + if (bRetval) + if (iServiceIndex >= 0) + bRetval = service_ok (iServiceIndex); + + lp_add_auto_services (lp_auto_services ()); +#if 0 + if (add_ipc) + lp_add_ipc (); + set_default_server_announce_type (); +#else + (void) &add_ipc; +#endif /* 0 */ + + bLoaded = True; + + /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */ + /* if bWINSsupport is true and we are in the client */ + + if (in_client && Globals.bWINSsupport) + { + + string_set (&Globals.szWINSserver, "127.0.0.1"); + + } + + return (bRetval); +} + + +/*************************************************************************** +reset the max number of services +***************************************************************************/ +void +lp_resetnumservices (void) +{ + iNumServices = 0; +} + + +/*************************************************************************** +return the max number of services +***************************************************************************/ +int +lp_numservices (void) +{ + return (iNumServices); +} + + +/*************************************************************************** +Return the number of the service with the given name, or -1 if it doesn't +exist. Note that this is a DIFFERENT ANIMAL from the internal function +getservicebyname()! This works ONLY if all services have been loaded, and +does not copy the found service. +***************************************************************************/ +int +lp_servicenumber (const char *pszServiceName) +{ + int iService; + + for (iService = iNumServices - 1; iService >= 0; iService--) + if (VALID (iService) && strequal (lp_servicename (iService), pszServiceName)) + break; + + if (iService < 0) + DEBUG (7, ("lp_servicenumber: couldn't find %s\n", pszServiceName)); + + return (iService); +} + +#if 0 +/******************************************************************* + a useful volume label function + ******************************************************************/ +char * +volume_label (int snum) +{ + char *ret = lp_volume (snum); + if (!*ret) + return (lp_servicename (snum)); + return (ret); +} +#endif /* 0 */ +#if 0 +/******************************************************************* + Set the server type we will announce as via nmbd. +********************************************************************/ +static void +set_default_server_announce_type (void) +{ + default_server_announce = (SV_TYPE_WORKSTATION | SV_TYPE_SERVER | + SV_TYPE_SERVER_UNIX | SV_TYPE_PRINTQ_SERVER); + if (lp_announce_as () == ANNOUNCE_AS_NT_SERVER) + default_server_announce |= (SV_TYPE_SERVER_NT | SV_TYPE_NT); + if (lp_announce_as () == ANNOUNCE_AS_NT_WORKSTATION) + default_server_announce |= SV_TYPE_NT; + else if (lp_announce_as () == ANNOUNCE_AS_WIN95) + default_server_announce |= SV_TYPE_WIN95_PLUS; + else if (lp_announce_as () == ANNOUNCE_AS_WFW) + default_server_announce |= SV_TYPE_WFW; + default_server_announce |= (lp_time_server ()? SV_TYPE_TIME_SOURCE : 0); +} + + +/******************************************************************* + Get the default server type we will announce as via nmbd. +********************************************************************/ +int +lp_default_server_announce (void) +{ + return default_server_announce; +} + + +/******************************************************************* + Split the announce version into major and minor numbers. +********************************************************************/ +int +lp_major_announce_version (void) +{ + static BOOL got_major = False; + static int major_version = DEFAULT_MAJOR_VERSION; + char *vers; + char *p; + + if (got_major) + return major_version; + + got_major = True; + if ((vers = lp_announce_version ()) == NULL) + return major_version; + + if ((p = strchr (vers, '.')) == 0) + return major_version; + + *p = '\0'; + major_version = atoi (vers); + return major_version; +} + + +int +lp_minor_announce_version (void) +{ + static BOOL got_minor = False; + static int minor_version = DEFAULT_MINOR_VERSION; + char *vers; + char *p; + + if (got_minor) + return minor_version; + + got_minor = True; + if ((vers = lp_announce_version ()) == NULL) + return minor_version; + + if ((p = strchr (vers, '.')) == 0) + return minor_version; + + p++; + minor_version = atoi (p); + return minor_version; +} +#endif /* 0 */ + +/*********************************************************** + Set the global name resolution order (used in smbclient). +************************************************************/ + +void +lp_set_name_resolve_order (char *new_order) +{ + Globals.szNameResolveOrder = new_order; +} diff --git a/src/vfs/smbfs/helpers/param/params.c b/src/vfs/smbfs/helpers/param/params.c index 853db1c79..64c02394e 100644 --- a/src/vfs/smbfs/helpers/param/params.c +++ b/src/vfs/smbfs/helpers/param/params.c @@ -8,22 +8,22 @@ * This module Copyright (C) 1997-1998 by the University of Minnesota * -------------------------------------------------------------------------- ** * - This file is part of the Midnight Commander. + This file is part of the Midnight Commander. - The Midnight Commander is free software: you can redistribute it - and/or modify it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of the License, - or (at your option) any later version. + The Midnight Commander is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. - The Midnight Commander is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + The Midnight Commander is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program. If not, see . + You should have received a copy of the GNU General Public License + along with this program. If not, see . -*/ + */ /* * -------------------------------------------------------------------------- ** @@ -105,14 +105,15 @@ const char *unix_error_string (int error_num); extern int DEBUGLEVEL; -static char *bufr = NULL; -static int bSize = 0; +static char *bufr = NULL; +static int bSize = 0; /* -------------------------------------------------------------------------- ** * Functions... */ -static int EatWhitespace( FILE *InFile ) +static int +EatWhitespace (FILE * InFile) /* ------------------------------------------------------------------------ ** * Scan past whitespace (see ctype(3C)) and return the first non-whitespace * character, or newline, or EOF. @@ -129,15 +130,16 @@ static int EatWhitespace( FILE *InFile ) * * ------------------------------------------------------------------------ ** */ - { - int c; +{ + int c; - for( c = getc( InFile ); isspace( c ) && ('\n' != c); c = getc( InFile ) ) - ; - return( c ); - } /* EatWhitespace */ + for (c = getc (InFile); isspace (c) && ('\n' != c); c = getc (InFile)) + ; + return (c); +} /* EatWhitespace */ -static int EatComment( FILE *InFile ) +static int +EatComment (FILE * InFile) /* ------------------------------------------------------------------------ ** * Scan to the end of a comment. * @@ -154,15 +156,16 @@ static int EatComment( FILE *InFile ) * * ------------------------------------------------------------------------ ** */ - { - int c; +{ + int c; - for( c = getc( InFile ); ('\n'!=c) && (EOF!=c) && (c>0); c = getc( InFile ) ) - ; - return( c ); - } /* EatComment */ + for (c = getc (InFile); ('\n' != c) && (EOF != c) && (c > 0); c = getc (InFile)) + ; + return (c); +} /* EatComment */ -static int Continuation( char *line, int pos ) +static int +Continuation (char *line, int pos) /* ------------------------------------------------------------------------ ** * Scan backards within a string to discover if the last non-whitespace * character is a line-continuation character ('\\'). @@ -177,16 +180,17 @@ static int Continuation( char *line, int pos ) * * ------------------------------------------------------------------------ ** */ - { - pos--; - while( (pos >= 0) && isspace(line[pos]) ) - pos--; +{ + pos--; + while ((pos >= 0) && isspace (line[pos])) + pos--; - return( ((pos >= 0) && ('\\' == line[pos])) ? pos : -1 ); - } /* Continuation */ + return (((pos >= 0) && ('\\' == line[pos])) ? pos : -1); +} /* Continuation */ -static BOOL Section( FILE *InFile, BOOL (*sfunc)(const char *) ) +static BOOL +Section (FILE * InFile, BOOL (*sfunc) (const char *)) /* ------------------------------------------------------------------------ ** * Scan a section name, and pass the name to function sfunc(). * @@ -200,86 +204,86 @@ static BOOL Section( FILE *InFile, BOOL (*sfunc)(const char *) ) * * ------------------------------------------------------------------------ ** */ - { - int c; - int i; - int end; - const char *func = "params.c:Section() -"; - - i = 0; /* is the offset of the next free byte in bufr[] and */ - end = 0; /* is the current "end of string" offset. In most */ - /* cases these will be the same, but if the last */ - /* character written to bufr[] is a space, then */ - /* will be one less than . */ - - c = EatWhitespace( InFile ); /* We've already got the '['. Scan */ - /* past initial white space. */ - - while( (EOF != c) && (c > 0) ) +{ + int c; + int i; + int end; + const char *func = "params.c:Section() -"; + + i = 0; /* is the offset of the next free byte in bufr[] and */ + end = 0; /* is the current "end of string" offset. In most */ + /* cases these will be the same, but if the last */ + /* character written to bufr[] is a space, then */ + /* will be one less than . */ + + c = EatWhitespace (InFile); /* We've already got the '['. Scan */ + /* past initial white space. */ + + while ((EOF != c) && (c > 0)) { - /* Check that the buffer is big enough for the next character. */ - if( i > (bSize - 2) ) - { - bSize += BUFR_INC; - bufr = Realloc( bufr, bSize ); - if( NULL == bufr ) + /* Check that the buffer is big enough for the next character. */ + if (i > (bSize - 2)) + { + bSize += BUFR_INC; + bufr = Realloc (bufr, bSize); + if (NULL == bufr) + { + DEBUG (0, ("%s Memory re-allocation failure.", func)); + return (False); + } + } + + /* Handle a single character. */ + switch (c) { - DEBUG(0, ("%s Memory re-allocation failure.", func) ); - return( False ); + case ']': /* Found the closing bracket. */ + bufr[end] = '\0'; + if (0 == end) /* Don't allow an empty name. */ + { + DEBUG (0, ("%s Empty section name in configuration file.\n", func)); + return (False); + } + if (!sfunc (bufr)) /* Got a valid name. Deal with it. */ + return (False); + (void) EatComment (InFile); /* Finish off the line. */ + return (True); + + case '\n': /* Got newline before closing ']'. */ + i = Continuation (bufr, i); /* Check for line continuation. */ + if (i < 0) + { + bufr[end] = '\0'; + DEBUG (0, ("%s Badly formed line in configuration file: %s\n", func, bufr)); + return (False); + } + end = ((i > 0) && (' ' == bufr[i - 1])) ? (i - 1) : (i); + c = getc (InFile); /* Continue with next line. */ + break; + + default: /* All else are a valid name chars. */ + if (isspace (c)) /* One space per whitespace region. */ + { + bufr[end] = ' '; + i = end + 1; + c = EatWhitespace (InFile); + } + else /* All others copy verbatim. */ + { + bufr[i++] = c; + end = i; + c = getc (InFile); + } } - } - - /* Handle a single character. */ - switch( c ) - { - case ']': /* Found the closing bracket. */ - bufr[end] = '\0'; - if( 0 == end ) /* Don't allow an empty name. */ - { - DEBUG(0, ("%s Empty section name in configuration file.\n", func )); - return( False ); - } - if( !sfunc( bufr ) ) /* Got a valid name. Deal with it. */ - return( False ); - (void)EatComment( InFile ); /* Finish off the line. */ - return( True ); - - case '\n': /* Got newline before closing ']'. */ - i = Continuation( bufr, i ); /* Check for line continuation. */ - if( i < 0 ) - { - bufr[end] = '\0'; - DEBUG(0, ("%s Badly formed line in configuration file: %s\n", - func, bufr )); - return( False ); - } - end = ( (i > 0) && (' ' == bufr[i - 1]) ) ? (i - 1) : (i); - c = getc( InFile ); /* Continue with next line. */ - break; - - default: /* All else are a valid name chars. */ - if( isspace( c ) ) /* One space per whitespace region. */ - { - bufr[end] = ' '; - i = end + 1; - c = EatWhitespace( InFile ); - } - else /* All others copy verbatim. */ - { - bufr[i++] = c; - end = i; - c = getc( InFile ); - } - } } - /* We arrive here if we've met the EOF before the closing bracket. */ - DEBUG(0, ("%s Unexpected EOF in the configuration file: %s\n", func, bufr )); - return( False ); - } /* Section */ + /* We arrive here if we've met the EOF before the closing bracket. */ + DEBUG (0, ("%s Unexpected EOF in the configuration file: %s\n", func, bufr)); + return (False); +} /* Section */ -static BOOL Parameter( FILE *InFile, BOOL (*pfunc)(const char *, const char *), int c ) +static BOOL +Parameter (FILE * InFile, BOOL (*pfunc) (const char *, const char *), int c) /* ------------------------------------------------------------------------ ** * Scan a parameter name and value, and pass these two fields to pfunc(). * @@ -303,126 +307,125 @@ static BOOL Parameter( FILE *InFile, BOOL (*pfunc)(const char *, const char *), * * ------------------------------------------------------------------------ ** */ - { - int i = 0; /* Position within bufr. */ - int end = 0; /* bufr[end] is current end-of-string. */ - int vstart = 0; /* Starting position of the parameter value. */ - const char *func = "params.c:Parameter() -"; - - /* Read the parameter name. */ - while( 0 == vstart ) /* Loop until we've found the start of the value. */ +{ + int i = 0; /* Position within bufr. */ + int end = 0; /* bufr[end] is current end-of-string. */ + int vstart = 0; /* Starting position of the parameter value. */ + const char *func = "params.c:Parameter() -"; + + /* Read the parameter name. */ + while (0 == vstart) /* Loop until we've found the start of the value. */ { - if( i > (bSize - 2) ) /* Ensure there's space for next char. */ - { - bSize += BUFR_INC; - bufr = Realloc( bufr, bSize ); - if( NULL == bufr ) + if (i > (bSize - 2)) /* Ensure there's space for next char. */ + { + bSize += BUFR_INC; + bufr = Realloc (bufr, bSize); + if (NULL == bufr) + { + DEBUG (0, ("%s Memory re-allocation failure.", func)); + return (False); + } + } + + switch (c) { - DEBUG(0, ("%s Memory re-allocation failure.", func) ); - return( False ); + case '=': /* Equal sign marks end of param name. */ + if (0 == end) /* Don't allow an empty name. */ + { + DEBUG (0, ("%s Invalid parameter name in config. file.\n", func)); + return (False); + } + bufr[end++] = '\0'; /* Mark end of string & advance. */ + i = end; /* New string starts here. */ + vstart = end; /* New string is parameter value. */ + bufr[i] = '\0'; /* New string is nul, for now. */ + break; + + case '\n': /* Find continuation char, else error. */ + i = Continuation (bufr, i); + if (i < 0) + { + bufr[end] = '\0'; + DEBUG (1, ("%s Ignoring badly formed line in configuration file: %s\n", + func, bufr)); + return (True); + } + end = ((i > 0) && (' ' == bufr[i - 1])) ? (i - 1) : (i); + c = getc (InFile); /* Read past eoln. */ + break; + + case '\0': /* Shouldn't have EOF within param name. */ + case EOF: + bufr[i] = '\0'; + DEBUG (1, ("%s Unexpected end-of-file at: %s\n", func, bufr)); + return (True); + + default: + if (isspace (c)) /* One ' ' per whitespace region. */ + { + bufr[end] = ' '; + i = end + 1; + c = EatWhitespace (InFile); + } + else /* All others verbatim. */ + { + bufr[i++] = c; + end = i; + c = getc (InFile); + } } - } - - switch( c ) - { - case '=': /* Equal sign marks end of param name. */ - if( 0 == end ) /* Don't allow an empty name. */ - { - DEBUG(0, ("%s Invalid parameter name in config. file.\n", func )); - return( False ); - } - bufr[end++] = '\0'; /* Mark end of string & advance. */ - i = end; /* New string starts here. */ - vstart = end; /* New string is parameter value. */ - bufr[i] = '\0'; /* New string is nul, for now. */ - break; - - case '\n': /* Find continuation char, else error. */ - i = Continuation( bufr, i ); - if( i < 0 ) - { - bufr[end] = '\0'; - DEBUG(1,("%s Ignoring badly formed line in configuration file: %s\n", - func, bufr )); - return( True ); - } - end = ( (i > 0) && (' ' == bufr[i - 1]) ) ? (i - 1) : (i); - c = getc( InFile ); /* Read past eoln. */ - break; - - case '\0': /* Shouldn't have EOF within param name. */ - case EOF: - bufr[i] = '\0'; - DEBUG(1,("%s Unexpected end-of-file at: %s\n", func, bufr )); - return( True ); - - default: - if( isspace( c ) ) /* One ' ' per whitespace region. */ - { - bufr[end] = ' '; - i = end + 1; - c = EatWhitespace( InFile ); - } - else /* All others verbatim. */ - { - bufr[i++] = c; - end = i; - c = getc( InFile ); - } - } } - /* Now parse the value. */ - c = EatWhitespace( InFile ); /* Again, trim leading whitespace. */ - while( (EOF !=c) && (c > 0) ) + /* Now parse the value. */ + c = EatWhitespace (InFile); /* Again, trim leading whitespace. */ + while ((EOF != c) && (c > 0)) { - if( i > (bSize - 2) ) /* Make sure there's enough room. */ - { - bSize += BUFR_INC; - bufr = Realloc( bufr, bSize ); - if( NULL == bufr ) + if (i > (bSize - 2)) /* Make sure there's enough room. */ { - DEBUG(0, ("%s Memory re-allocation failure.", func) ); - return( False ); + bSize += BUFR_INC; + bufr = Realloc (bufr, bSize); + if (NULL == bufr) + { + DEBUG (0, ("%s Memory re-allocation failure.", func)); + return (False); + } + } + + switch (c) + { + case '\r': /* Explicitly remove '\r' because the older */ + c = getc (InFile); /* version called fgets_slash() which also */ + break; /* removes them. */ + + case '\n': /* Marks end of value unless there's a '\'. */ + i = Continuation (bufr, i); + if (i < 0) + c = 0; + else + { + for (end = i; (end >= 0) && isspace (bufr[end]); end--) + ; + c = getc (InFile); + } + break; + + default: /* All others verbatim. Note that spaces do */ + bufr[i++] = c; /* not advance . This allows trimming */ + if (!isspace (c)) /* of whitespace at the end of the line. */ + end = i; + c = getc (InFile); + break; } - } - - switch( c ) - { - case '\r': /* Explicitly remove '\r' because the older */ - c = getc( InFile ); /* version called fgets_slash() which also */ - break; /* removes them. */ - - case '\n': /* Marks end of value unless there's a '\'. */ - i = Continuation( bufr, i ); - if( i < 0 ) - c = 0; - else - { - for( end = i; (end >= 0) && isspace(bufr[end]); end-- ) - ; - c = getc( InFile ); - } - break; - - default: /* All others verbatim. Note that spaces do */ - bufr[i++] = c; /* not advance . This allows trimming */ - if( !isspace( c ) ) /* of whitespace at the end of the line. */ - end = i; - c = getc( InFile ); - break; - } } - bufr[end] = '\0'; /* End of value. */ + bufr[end] = '\0'; /* End of value. */ - return( pfunc( bufr, &bufr[vstart] ) ); /* Pass name & value to pfunc(). */ - } /* Parameter */ + return (pfunc (bufr, &bufr[vstart])); /* Pass name & value to pfunc(). */ +} /* Parameter */ -static BOOL Parse( FILE *InFile, - BOOL (*sfunc)(const char *), - BOOL (*pfunc)(const char *, const char *) ) +static BOOL +Parse (FILE * InFile, BOOL (*sfunc) (const char *), BOOL (*pfunc) (const char *, const char *)) /* ------------------------------------------------------------------------ ** * Scan & parse the input. * @@ -444,44 +447,45 @@ static BOOL Parse( FILE *InFile, * * ------------------------------------------------------------------------ ** */ - { - int c; +{ + int c; - c = EatWhitespace( InFile ); - while( (EOF != c) && (c > 0) ) + c = EatWhitespace (InFile); + while ((EOF != c) && (c > 0)) { - switch( c ) - { - case '\n': /* Blank line. */ - c = EatWhitespace( InFile ); - break; - - case ';': /* Comment line. */ - case '#': - c = EatComment( InFile ); - break; - - case '[': /* Section Header. */ - if( !Section( InFile, sfunc ) ) - return( False ); - c = EatWhitespace( InFile ); - break; - - case '\\': /* Bogus backslash. */ - c = EatWhitespace( InFile ); - break; - - default: /* Parameter line. */ - if( !Parameter( InFile, pfunc, c ) ) - return( False ); - c = EatWhitespace( InFile ); - break; - } + switch (c) + { + case '\n': /* Blank line. */ + c = EatWhitespace (InFile); + break; + + case ';': /* Comment line. */ + case '#': + c = EatComment (InFile); + break; + + case '[': /* Section Header. */ + if (!Section (InFile, sfunc)) + return (False); + c = EatWhitespace (InFile); + break; + + case '\\': /* Bogus backslash. */ + c = EatWhitespace (InFile); + break; + + default: /* Parameter line. */ + if (!Parameter (InFile, pfunc, c)) + return (False); + c = EatWhitespace (InFile); + break; + } } - return( True ); - } /* Parse */ + return (True); +} /* Parse */ -static FILE *OpenConfFile( const char *FileName ) +static FILE * +OpenConfFile (const char *FileName) /* ------------------------------------------------------------------------ ** * Open a configuration file. * @@ -492,32 +496,32 @@ static FILE *OpenConfFile( const char *FileName ) * * ------------------------------------------------------------------------ ** */ - { - FILE *OpenedFile; - const char *func = "params.c:OpenConfFile() -"; - extern BOOL in_client; - int lvl = in_client?1:0; +{ + FILE *OpenedFile; + const char *func = "params.c:OpenConfFile() -"; + extern BOOL in_client; + int lvl = in_client ? 1 : 0; - if( NULL == FileName || 0 == *FileName ) + if (NULL == FileName || 0 == *FileName) { - DEBUG( lvl, ("%s No configuration filename specified.\n", func) ); - return( NULL ); + DEBUG (lvl, ("%s No configuration filename specified.\n", func)); + return (NULL); } - OpenedFile = sys_fopen( FileName, "r" ); - if( NULL == OpenedFile ) + OpenedFile = sys_fopen (FileName, "r"); + if (NULL == OpenedFile) { - DEBUG( lvl, - ("%s Unable to open configuration file \"%s\":\n\t%s\n", - func, FileName, unix_error_string (errno)) ); + DEBUG (lvl, + ("%s Unable to open configuration file \"%s\":\n\t%s\n", + func, FileName, unix_error_string (errno))); } - return( OpenedFile ); - } /* OpenConfFile */ + return (OpenedFile); +} /* OpenConfFile */ -BOOL pm_process( const char *FileName, - BOOL (*sfunc)(const char *), - BOOL (*pfunc)(const char *, const char *) ) +BOOL +pm_process (const char *FileName, + BOOL (*sfunc) (const char *), BOOL (*pfunc) (const char *, const char *)) /* ------------------------------------------------------------------------ ** * Process the named parameter file. * @@ -531,46 +535,46 @@ BOOL pm_process( const char *FileName, * * ------------------------------------------------------------------------ ** */ - { - int result; - FILE *InFile; - const char *func = "params.c:pm_process() -"; - - InFile = OpenConfFile( FileName ); /* Open the config file. */ - if( NULL == InFile ) - return( False ); - - DEBUG( 3, ("%s Processing configuration file \"%s\"\n", func, FileName) ); - - if( NULL != bufr ) /* If we already have a buffer */ - result = Parse( InFile, sfunc, pfunc ); /* (recursive call), then just */ - /* use it. */ - - else /* If we don't have a buffer */ - { /* allocate one, then parse, */ - bSize = BUFR_INC; /* then free. */ - bufr = (char *)malloc( bSize ); - if( NULL == bufr ) - { - DEBUG(0,("%s memory allocation failure.\n", func)); - fclose(InFile); - return( False ); - } - result = Parse( InFile, sfunc, pfunc ); - free( bufr ); - bufr = NULL; - bSize = 0; +{ + int result; + FILE *InFile; + const char *func = "params.c:pm_process() -"; + + InFile = OpenConfFile (FileName); /* Open the config file. */ + if (NULL == InFile) + return (False); + + DEBUG (3, ("%s Processing configuration file \"%s\"\n", func, FileName)); + + if (NULL != bufr) /* If we already have a buffer */ + result = Parse (InFile, sfunc, pfunc); /* (recursive call), then just */ + /* use it. */ + + else /* If we don't have a buffer */ + { /* allocate one, then parse, */ + bSize = BUFR_INC; /* then free. */ + bufr = (char *) malloc (bSize); + if (NULL == bufr) + { + DEBUG (0, ("%s memory allocation failure.\n", func)); + fclose (InFile); + return (False); + } + result = Parse (InFile, sfunc, pfunc); + free (bufr); + bufr = NULL; + bSize = 0; } - fclose(InFile); + fclose (InFile); - if( !result ) /* Generic failure. */ + if (!result) /* Generic failure. */ { - DEBUG(0,("%s Failed. Error returned from params.c:parse().\n", func)); - return( False ); + DEBUG (0, ("%s Failed. Error returned from params.c:parse().\n", func)); + return (False); } - return( True ); /* Generic success. */ - } /* pm_process */ + return (True); /* Generic success. */ +} /* pm_process */ /* -------------------------------------------------------------------------- */ diff --git a/src/vfs/tar/tar.h b/src/vfs/tar/tar.h index b099f2fca..2f7b8dc33 100644 --- a/src/vfs/tar/tar.h +++ b/src/vfs/tar/tar.h @@ -11,7 +11,7 @@ /*** declarations of public functions ************************************************************/ -void init_tarfs(void); +void init_tarfs (void); /*** inline functions ****************************************************************************/ diff --git a/src/vfs/undelfs/undelfs.h b/src/vfs/undelfs/undelfs.h index 06d32095b..c4cd744b8 100644 --- a/src/vfs/undelfs/undelfs.h +++ b/src/vfs/undelfs/undelfs.h @@ -11,7 +11,7 @@ /*** declarations of public functions ************************************************************/ -void init_undelfs(void); +void init_undelfs (void); /*** inline functions ****************************************************************************/ diff --git a/src/viewer/datasource.c b/src/viewer/datasource.c index 5cd31e7ea..e5f55a6fe 100644 --- a/src/viewer/datasource.c +++ b/src/viewer/datasource.c @@ -379,7 +379,7 @@ mcview_close_datasource (mcview_t * view) #ifdef HAVE_ASSERT_H assert (!"Unknown datasource type") #endif - ; + ; } view->datasource = DS_NONE; } diff --git a/src/viewer/display.c b/src/viewer/display.c index 6042edff1..a3fd66245 100644 --- a/src/viewer/display.c +++ b/src/viewer/display.c @@ -59,7 +59,7 @@ /*** file scope macro definitions ****************************************************************/ -#define BUF_TRUNC_LEN 5 /* The length of the line displays the file size */ +#define BUF_TRUNC_LEN 5 /* The length of the line displays the file size */ /*** file scope type declarations ****************************************************************/ -- 2.11.4.GIT