more merging voodoo
[samba.git] / source3 / smbd / error.c
1 #define OLD_NTDOMAIN 1
2
3 /* 
4    Unix SMB/Netbios implementation.
5    Version 1.9.
6    error packet handling
7    Copyright (C) Andrew Tridgell 1992-1998
8    
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 2 of the License, or
12    (at your option) any later version.
13    
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18    
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24 #include "includes.h"
25
26 extern int DEBUGLEVEL;
27
28 /* these can be set by some functions to override the error codes */
29 int unix_ERR_class=SMB_SUCCESS;
30 int unix_ERR_code=0;
31
32
33 /****************************************************************************
34   create an error packet from a cached error.
35 ****************************************************************************/
36 int cached_error_packet(char *inbuf,char *outbuf,files_struct *fsp,int line)
37 {
38   write_bmpx_struct *wbmpx = fsp->wbmpx_ptr;
39
40   int32 eclass = wbmpx->wr_errclass;
41   int32 err = wbmpx->wr_error;
42
43   /* We can now delete the auxiliary struct */
44   free((char *)wbmpx);
45   fsp->wbmpx_ptr = NULL;
46   return error_packet(inbuf,outbuf,eclass,err,line);
47 }
48
49
50 struct
51 {
52   int unixerror;
53   int smbclass;
54   int smbcode;
55 } unix_smb_errmap[] =
56 {
57   {EPERM,ERRDOS,ERRnoaccess},
58   {EACCES,ERRDOS,ERRnoaccess},
59   {ENOENT,ERRDOS,ERRbadfile},
60   {ENOTDIR,ERRDOS,ERRbadpath},
61   {EIO,ERRHRD,ERRgeneral},
62   {EBADF,ERRSRV,ERRsrverror},
63   {EINVAL,ERRSRV,ERRsrverror},
64   {EEXIST,ERRDOS,ERRfilexists},
65   {ENFILE,ERRDOS,ERRnofids},
66   {EMFILE,ERRDOS,ERRnofids},
67   {ENOSPC,ERRHRD,ERRdiskfull},
68 #ifdef EDQUOT
69   {EDQUOT,ERRHRD,ERRdiskfull},
70 #endif
71 #ifdef ENOTEMPTY
72   {ENOTEMPTY,ERRDOS,ERRnoaccess},
73 #endif
74 #ifdef EXDEV
75   {EXDEV,ERRDOS,ERRdiffdevice},
76 #endif
77   {EROFS,ERRHRD,ERRnowrite},
78   {0,0,0}
79 };
80
81 /****************************************************************************
82   create an error packet from errno
83 ****************************************************************************/
84 int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int line)
85 {
86   int eclass=def_class;
87   int ecode=def_code;
88   int i=0;
89
90   if (unix_ERR_class != SMB_SUCCESS)
91     {
92       eclass = unix_ERR_class;
93       ecode = unix_ERR_code;
94       unix_ERR_class = SMB_SUCCESS;
95       unix_ERR_code = 0;
96     }
97   else
98     {
99       while (unix_smb_errmap[i].smbclass != 0)
100       {
101             if (unix_smb_errmap[i].unixerror == errno)
102             {
103               eclass = unix_smb_errmap[i].smbclass;
104               ecode = unix_smb_errmap[i].smbcode;
105               break;
106             }
107           i++;
108       }
109     }
110
111   return(error_packet(inbuf,outbuf,eclass,ecode,line));
112 }
113
114
115 /****************************************************************************
116   create an error packet. Normally called using the ERROR() macro
117 ****************************************************************************/
118 int error_packet(char *inbuf,char *outbuf,int error_class,uint32 error_code,int line)
119 {
120   int outsize = set_message(outbuf,0,0,True);
121   int cmd = CVAL(inbuf,smb_com);
122   int flgs2 = SVAL(outbuf,smb_flg2); 
123
124   if ((flgs2 & FLAGS2_32_BIT_ERROR_CODES) == FLAGS2_32_BIT_ERROR_CODES)
125   {
126     SIVAL(outbuf,smb_rcls,error_code);
127     
128     DEBUG( 3, ( "32 bit error packet at line %d cmd=%d (%s) eclass=%08x [%s]\n",
129               line, cmd, smb_fn_name(cmd), error_code, smb_errstr(outbuf) ) );
130   }
131   else
132   {
133     CVAL(outbuf,smb_rcls) = error_class;
134     SSVAL(outbuf,smb_err,error_code);  
135     DEBUG( 3, ( "error packet at line %d cmd=%d (%s) eclass=%d ecode=%d\n",
136               line,
137               (int)CVAL(inbuf,smb_com),
138               smb_fn_name(CVAL(inbuf,smb_com)),
139               error_class,
140               error_code ) );
141
142   }
143   
144   if (errno != 0)
145     DEBUG(3,("error string = %s\n",strerror(errno)));
146   
147   return(outsize);
148 }
149
150 #undef OLD_NTDOMAIN