minor delayed clean-ups
[sip-router] / error.c
1 /*
2  * $Id$
3  *
4  */
5
6 #include <stdio.h>
7 #include "error.h"
8 #include "str.h"
9 #include "parser/msg_parser.h"
10 #include "mem/mem.h"
11
12 /* current function's error; */
13 int ser_error=-1;
14 /* previous error */
15 int prev_ser_error=-1;
16
17 int err2reason_phrase( 
18         int ser_error,  /* current itnernal ser error */
19         int *sip_error,  /* the sip error code to which ser     
20                                             ser error will be turned */
21         char *phrase,    /* resulting error text */
22         int etl,                /* error text buffer length */
23         char *signature ) /* extra text to be appended */
24 {
25
26         char *error_txt;
27
28         switch( ser_error ) {
29                 case E_OUT_OF_MEM:
30                         error_txt="Excuse me I ran out of memory";
31                         *sip_error=500;
32                         break;
33                 case E_SEND:
34                         error_txt="Unfortunately error on sending to next hop occured";
35                         *sip_error=-ser_error;
36                         break;
37                 case E_BAD_ADDRESS:
38                         error_txt="Unresolveable destination";
39                         *sip_error=-ser_error;
40                         break;
41                 case E_BAD_REQ:
42                         error_txt="Bad Request";
43                         *sip_error=-ser_error;
44                         break;
45                 case E_BAD_URI:
46                         error_txt="Regretfuly, we were not able to process the URI";
47                         *sip_error=-ser_error;
48                         break;
49                 case E_BAD_TUPEL:
50                         error_txt="Transaction tupel incomplete";
51                         *sip_error=-E_BAD_REQ;
52                         break;
53                 case E_EXEC:
54                         error_txt="Error in external logic";
55                         *sip_error=-E_BAD_SERVER;
56                         break;
57                 case E_TOO_MANY_BRANCHES:
58                         error_txt="Forking capacity exceeded";
59                         *sip_error=-E_BAD_SERVER;
60                         break;
61                 default:
62                         error_txt="I'm terribly sorry, server error occured";
63                         *sip_error=500;
64                         break;
65         }
66         return snprintf( phrase, etl, "%s (%d/%s)", error_txt, 
67                 -ser_error, signature );
68 }
69
70 char *error_text( int code )
71 {
72         switch(code) {
73
74                 case 100: return "Trying";
75                 case 180: return "Ringing";
76                 case 181: return "Call is Being Forwarded";
77                 case 182: return "Queued";
78                 case 183: return "Session Progress";
79
80                 case 200: return "OK";
81
82                 case 300: return "Multiple Choices";
83                 case 301: return "Moved Permanently";
84                 case 302: return "Moved Temporarily";
85                 case 305: return "Use Proxy";
86                 case 380: return "Alternative Service";
87
88                 case 400: return "Bad Request";
89                 case 401: return "Unauthorized";
90                 case 402: return "Payement Required";
91                 case 403: return "Forbidden";
92                 case 404: return "Not Found";
93                 case 405: return "Method not Allowed";
94                 case 406: return "Not Acceptable";
95                 case 407: return "Proxy authentication Required";
96                 case 408: return "Request Timeout";
97                 case 410: return "Gone";
98                 case 413: return "Request Entity Too Large";
99                 case 414: return "Request-URI Too Long";
100                 case 415: return "Unsupported Media Type";
101                 case 416: return "Unsupported URI Scheme";
102                 case 417: return "Bad Extension";
103                 case 421: return "Extension Required";
104                 case 423: return "Interval Too Brief";
105                 case 480: return "Temporarily Unavailable";
106                 case 481: return "Call/Transaction Does not Exist";
107                 case 482: return "Loop Detected";
108                 case 483: return "Too Many Hops";
109                 case 484: return "Address Incomplete";
110                 case 485: return "Ambigous";
111                 case 486: return "Busy Here";
112                 case 487: return "Request Terminated";
113                 case 488: return "Not Acceptable Here";
114                 case 491: return "Request Pending";
115         
116                 case 500: return "Server Internal Error";
117                 case 501: return "Not Implemented";
118                 case 502: return "Bad Gateway";
119                 case 503: return "Service Unavailable";
120                 case 504: return "Server Time-out";
121                 case 505: return "Version not Supported";
122                 case 513: return "Message Too Large";
123
124                 case 600: return "Busy Everywhere";
125                 case 603: return "Decline";
126                 case 604: return "Does not Exist Anywhere";
127                 case 606: return "Not Acceptable";
128
129         }
130
131         if (code>=600) return "Global Failure";
132         else if (code>=500) return "Server Failure";
133         else if (code>=400) return "Request Failure";
134         else if (code>=300) return "Redirection";
135         else if (code>=200) return "Successful";
136         else if (code>=100) return "Provisional";
137         else return "Unspecified";
138 }
139
140 void get_reply_status( str *status, struct sip_msg *reply, int code )
141 {
142         str phrase;
143
144         status->s=0;
145
146         if (reply==0) {
147                 LOG(L_CRIT, "BUG: get_reply_status called with 0 msg\n");
148                 return;
149         }
150
151         if (reply==FAKED_REPLY) {
152                 phrase.s=error_text(code);
153                 phrase.len=strlen(phrase.s);
154         } else {
155                 phrase=reply->first_line.u.reply.reason;
156         }
157         status->len=phrase.len+3/*code*/+1/*space*/+1/*ZT*/;
158         status->s=pkg_malloc(status->len);
159         if (!status->s) {
160                 LOG(L_ERR, "ERROR: get_reply_status: no mem\n");
161                 return;
162         }
163         status->s[3]=' ';
164         status->s[2]='0'+code % 10; code=code/10;
165         status->s[1]='0'+code% 10; code=code/10;
166         status->s[0]='0'+code % 10;
167         memcpy(&status->s[4], phrase.s, phrase.len);
168         status->s[status->len-1]=0;
169 }