00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00318
00319
00320 #include "midas.h"
00321 #include "msystem.h"
00322
00323 #ifdef OS_UNIX
00324 #include <sys/mount.h>
00325 #endif
00326
00327 static INT ss_in_async_routine_flag = 0;
00328 #ifdef LOCAL_ROUTINES
00329 #include <signal.h>
00330
00331
00332
00333
00334
00335 BOOL disable_shm_write = FALSE;
00336
00337
00338 INT ss_set_async_flag(INT flag)
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358 {
00359 INT old_flag;
00360
00361 old_flag = ss_in_async_routine_flag;
00362 ss_in_async_routine_flag = flag;
00363 return old_flag;
00364 }
00365
00366
00367 INT ss_shm_open(char *name, INT size, void **adr, HNDLE * handle)
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391 {
00392 INT status;
00393 char mem_name[256], file_name[256], path[256];
00394
00395
00396 sprintf(mem_name, "SM_%s", name);
00397
00398
00399 cm_get_path(path);
00400 if (path[0] == 0) {
00401 getcwd(path, 256);
00402 #if defined(OS_VMS)
00403 #elif defined(OS_UNIX)
00404 strcat(path, "/");
00405 #elif defined(OS_WINNT)
00406 strcat(path, "\\");
00407 #endif
00408 }
00409
00410 strcpy(file_name, path);
00411 #if defined (OS_UNIX)
00412 strcat(file_name, ".");
00413 #endif
00414 strcat(file_name, name);
00415 strcat(file_name, ".SHM");
00416
00417 #ifdef OS_WINNT
00418
00419 status = SS_SUCCESS;
00420
00421 {
00422 HANDLE hFile, hMap;
00423 char str[256], *p;
00424 DWORD file_size;
00425
00426
00427
00428
00429
00430 strcpy(str, path);
00431
00432
00433 while (strpbrk(str, "\\: "))
00434 *strpbrk(str, "\\: ") = '*';
00435 strcat(str, mem_name);
00436
00437
00438 p = str;
00439 while (*p)
00440 *p++ = (char) toupper(*p);
00441
00442 hMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, str);
00443 if (hMap == 0) {
00444 hFile = CreateFile(file_name, GENERIC_READ | GENERIC_WRITE,
00445 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
00446 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
00447 if (!hFile) {
00448 cm_msg(MERROR, "ss_shm_open", "CreateFile() failed");
00449 return SS_FILE_ERROR;
00450 }
00451
00452 file_size = GetFileSize(hFile, NULL);
00453 if (file_size != 0xFFFFFFFF && file_size > 0)
00454 size = file_size;
00455
00456 hMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, size, str);
00457
00458 if (!hMap) {
00459 status = GetLastError();
00460 cm_msg(MERROR, "ss_shm_open", "CreateFileMapping() failed, error %d", status);
00461 return SS_FILE_ERROR;
00462 }
00463
00464 CloseHandle(hFile);
00465 status = SS_CREATED;
00466 }
00467
00468 *adr = MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
00469 *handle = (HNDLE) hMap;
00470
00471 if (adr == NULL) {
00472 cm_msg(MERROR, "ss_shm_open", "MapViewOfFile() failed");
00473 return SS_NO_MEMORY;
00474 }
00475
00476 return status;
00477 }
00478
00479 #endif
00480 #ifdef OS_VMS
00481
00482 status = SS_SUCCESS;
00483
00484 {
00485 int addr[2];
00486 $DESCRIPTOR(memname_dsc, "dummy");
00487 $DESCRIPTOR(filename_dsc, "dummy");
00488 memname_dsc.dsc$w_length = strlen(mem_name);
00489 memname_dsc.dsc$a_pointer = mem_name;
00490 filename_dsc.dsc$w_length = strlen(file_name);
00491 filename_dsc.dsc$a_pointer = file_name;
00492
00493 addr[0] = size;
00494 addr[1] = 0;
00495
00496 status = ppl$create_shared_memory(&memname_dsc, addr, &PPL$M_NOUNI, &filename_dsc);
00497
00498 if (status == PPL$_CREATED)
00499 status = SS_CREATED;
00500 else if (status != PPL$_NORMAL)
00501 status = SS_FILE_ERROR;
00502
00503 *adr = (void *) addr[1];
00504 *handle = 0;
00505
00506 if (adr == NULL)
00507 return SS_NO_MEMORY;
00508
00509 return status;
00510 }
00511
00512 #endif
00513 #ifdef OS_UNIX
00514
00515 status = SS_SUCCESS;
00516
00517 {
00518 int key, shmid, fh, file_size;
00519 struct shmid_ds buf;
00520 char str[256];
00521
00522
00523 key = ftok(file_name, 'M');
00524
00525
00526 if (key == -1) {
00527 fh = open(file_name, O_CREAT | O_TRUNC | O_BINARY, 0644);
00528 close(fh);
00529 key = ftok(file_name, 'M');
00530
00531 if (key == -1) {
00532 cm_msg(MERROR, "ss_shm_open", "ftok() failed");
00533 return SS_FILE_ERROR;
00534 }
00535
00536 status = SS_CREATED;
00537
00538
00539
00540 shmid = shmget(key, 0, 0);
00541 shmctl(shmid, IPC_RMID, &buf);
00542 } else {
00543
00544 file_size = (INT) ss_file_size(file_name);
00545 if (file_size > 0)
00546 size = file_size;
00547 }
00548
00549
00550 shmid = shmget(key, size, 0);
00551 if (shmid == -1) {
00552 shmid = shmget(key, size, IPC_CREAT);
00553 status = SS_CREATED;
00554 }
00555
00556 if (shmid == -1) {
00557 if (errno == EINVAL)
00558 cm_msg(MERROR, "ss_shm_open",
00559 "shmget() failed, shared memory size %d exceeds system limit", size);
00560 else
00561 cm_msg(MERROR, "ss_shm_open", "shmget() failed, errno = %d", errno);
00562
00563 return SS_NO_MEMORY;
00564 }
00565
00566 buf.shm_perm.uid = getuid();
00567 buf.shm_perm.gid = getgid();
00568 buf.shm_perm.mode = 0666;
00569 shmctl(shmid, IPC_SET, &buf);
00570
00571 *adr = shmat(shmid, 0, 0);
00572 *handle = (HNDLE) shmid;
00573
00574 if ((*adr) == (void *) (-1)) {
00575 sprintf(str, "shmat() failed, errno = %d", errno);
00576 cm_msg(MERROR, "ss_shm_open", str);
00577 return SS_NO_MEMORY;
00578 }
00579
00580
00581 if (status == SS_CREATED) {
00582 fh = open(file_name, O_RDONLY, 0644);
00583 if (fh == -1)
00584 fh = open(file_name, O_CREAT | O_RDWR, 0644);
00585 else
00586 read(fh, *adr, size);
00587 close(fh);
00588 }
00589
00590 return status;
00591 }
00592
00593 #endif
00594 }
00595
00596
00597 INT ss_shm_close(char *name, void *adr, HNDLE handle, INT destroy_flag)
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621 {
00622 char mem_name[256], file_name[256], path[256];
00623
00624
00625
00626
00627
00628 sprintf(mem_name, "SM_%s", name);
00629
00630
00631 cm_get_path(path);
00632 if (path[0] == 0) {
00633 getcwd(path, 256);
00634 #if defined(OS_VMS)
00635 #elif defined(OS_UNIX)
00636 strcat(path, "/");
00637 #elif defined(OS_WINNT)
00638 strcat(path, "\\");
00639 #endif
00640 }
00641
00642 strcpy(file_name, path);
00643 #if defined (OS_UNIX)
00644 strcat(file_name, ".");
00645 #endif
00646 strcat(file_name, name);
00647 strcat(file_name, ".SHM");
00648
00649 #ifdef OS_WINNT
00650
00651 if (!UnmapViewOfFile(adr))
00652 return SS_INVALID_ADDRESS;
00653
00654 CloseHandle((HANDLE) handle);
00655
00656 return SS_SUCCESS;
00657
00658 #endif
00659 #ifdef OS_VMS
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683 return SS_INVALID_ADDRESS;
00684
00685 #endif
00686 #ifdef OS_UNIX
00687
00688 {
00689 struct shmid_ds buf;
00690 FILE *fh;
00691
00692
00693 if (shmctl(handle, IPC_STAT, &buf) < 0) {
00694 cm_msg(MERROR, "ss_shm_close", "shmctl() failed");
00695 return SS_INVALID_HANDLE;
00696 }
00697
00698
00699 if (buf.shm_nattch == 1) {
00700 if (!disable_shm_write) {
00701 fh = fopen(file_name, "w");
00702
00703 if (fh == NULL) {
00704 cm_msg(MERROR, "ss_shm_close",
00705 "Cannot write to file %s, please check protection", file_name);
00706 } else {
00707
00708 fwrite(adr, 1, buf.shm_segsz, fh);
00709 fclose(fh);
00710 }
00711 }
00712
00713 if (shmdt(adr) < 0) {
00714 cm_msg(MERROR, "ss_shm_close", "shmdt() failed");
00715 return SS_INVALID_ADDRESS;
00716 }
00717
00718 if (shmctl(handle, IPC_RMID, &buf) < 0) {
00719 cm_msg(MERROR, "ss_shm_close", "shmctl(RMID) failed");
00720 return SS_INVALID_ADDRESS;
00721 }
00722 } else
00723
00724 if (shmdt(adr) < 0) {
00725 cm_msg(MERROR, "ss_shm_close", "shmdt() failed");
00726 return SS_INVALID_ADDRESS;
00727 }
00728
00729 return SS_SUCCESS;
00730 }
00731
00732 #endif
00733 }
00734
00735
00736 INT ss_shm_protect(HNDLE handle, void *adr)
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756 {
00757 #ifdef OS_WINNT
00758
00759 if (!UnmapViewOfFile(adr))
00760 return SS_INVALID_ADDRESS;
00761
00762 #endif
00763 #ifdef OS_UNIX
00764
00765 if (shmdt(adr) < 0) {
00766 cm_msg(MERROR, "ss_shm_protect", "shmdt() failed");
00767 return SS_INVALID_ADDRESS;
00768 }
00769 #endif
00770 return SS_SUCCESS;
00771 }
00772
00773
00774 INT ss_shm_unprotect(HNDLE handle, void **adr)
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794 {
00795 #ifdef OS_WINNT
00796
00797 *adr = MapViewOfFile((HANDLE) handle, FILE_MAP_ALL_ACCESS, 0, 0, 0);
00798
00799 if (*adr == NULL) {
00800 cm_msg(MERROR, "ss_shm_unprotect", "MapViewOfFile() failed");
00801 return SS_NO_MEMORY;
00802 }
00803 #endif
00804 #ifdef OS_UNIX
00805
00806 *adr = shmat(handle, 0, 0);
00807
00808 if ((*adr) == (void *) (-1)) {
00809 cm_msg(MERROR, "ss_shm_unprotect", "shmat() failed, errno = %d", errno);
00810 return SS_NO_MEMORY;
00811 }
00812 #endif
00813
00814 return SS_SUCCESS;
00815 }
00816
00817
00818 INT ss_shm_flush(char *name, void *adr, INT size)
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838 {
00839 char mem_name[256], file_name[256], path[256];
00840
00841
00842
00843
00844
00845 sprintf(mem_name, "SM_%s", name);
00846
00847
00848 cm_get_path(path);
00849 if (path[0] == 0) {
00850 getcwd(path, 256);
00851 #if defined(OS_VMS)
00852 #elif defined(OS_UNIX)
00853 strcat(path, "/");
00854 #elif defined(OS_WINNT)
00855 strcat(path, "\\");
00856 #endif
00857 }
00858
00859 strcpy(file_name, path);
00860 #if defined (OS_UNIX)
00861 strcat(file_name, ".");
00862 #endif
00863 strcat(file_name, name);
00864 strcat(file_name, ".SHM");
00865
00866 #ifdef OS_WINNT
00867
00868 if (!FlushViewOfFile(adr, size))
00869 return SS_INVALID_ADDRESS;
00870
00871 return SS_SUCCESS;
00872
00873 #endif
00874 #ifdef OS_VMS
00875
00876 return SS_SUCCESS;
00877
00878 #endif
00879 #ifdef OS_UNIX
00880
00881 if (!disable_shm_write) {
00882 FILE *fh;
00883
00884 fh = fopen(file_name, "w");
00885
00886 if (fh == NULL) {
00887 cm_msg(MERROR, "ss_shm_flush",
00888 "Cannot write to file %s, please check protection", file_name);
00889 } else {
00890
00891 fwrite(adr, 1, size, fh);
00892 fclose(fh);
00893 }
00894 }
00895 return SS_SUCCESS;
00896
00897 #endif
00898 }
00899
00900
00901 INT ss_getthandle(void)
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918 {
00919 #ifdef OS_WINNT
00920 HANDLE hThread;
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931 DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
00932 GetCurrentProcess(), &hThread, THREAD_ALL_ACCESS, TRUE, 0);
00933
00934 return (INT)hThread;
00935
00936 #endif
00937 #ifdef OS_VMS
00938
00939 return 0;
00940
00941 #endif
00942 #ifdef OS_UNIX
00943
00944 return ss_getpid();
00945
00946 #endif
00947 }
00948
00949 #endif
00950
00951
00952 struct {
00953 char c;
00954 double d;
00955 } test_align;
00956
00957 INT ss_get_struct_align()
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979 {
00980 return (PTYPE) (&test_align.d) - (PTYPE) & test_align.c;
00981 }
00982
00983
00984 INT ss_getpid(void)
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001 {
01002 #ifdef OS_WINNT
01003
01004 return (int) GetCurrentProcessId();
01005
01006 #endif
01007 #ifdef OS_VMS
01008
01009 return getpid();
01010
01011 #endif
01012 #ifdef OS_UNIX
01013
01014 return getpid();
01015
01016 #endif
01017 #ifdef OS_VXWORKS
01018
01019 return 0;
01020
01021 #endif
01022 #ifdef OS_MSDOS
01023
01024 return 0;
01025
01026 #endif
01027 }
01028
01029
01030
01031 static BOOL _single_thread = FALSE;
01032
01033 void ss_force_single_thread()
01034 {
01035 _single_thread = TRUE;
01036 }
01037
01038 INT ss_gettid(void)
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055 {
01056
01057 if (_single_thread)
01058 return 1;
01059
01060 #ifdef OS_MSDOS
01061
01062 return 0;
01063
01064 #endif
01065 #ifdef OS_WINNT
01066
01067 return (int) GetCurrentThreadId();
01068
01069 #endif
01070 #ifdef OS_VMS
01071
01072 return ss_getpid();
01073
01074 #endif
01075 #ifdef OS_UNIX
01076
01077 return ss_getpid();
01078
01079 #endif
01080 #ifdef OS_VXWORKS
01081
01082 return ss_getpid();
01083
01084 #endif
01085 }
01086
01087
01088
01089 #ifdef OS_UNIX
01090 void catch_sigchld(int signo)
01091 {
01092 int status;
01093
01094 wait(&status);
01095 return;
01096 }
01097 #endif
01098
01099 INT ss_spawnv(INT mode, char *cmdname, char *argv[])
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122 {
01123 #ifdef OS_WINNT
01124
01125 if (spawnvp(mode, cmdname, argv) < 0)
01126 return SS_INVALID_NAME;
01127
01128 return SS_SUCCESS;
01129
01130 #endif
01131
01132 #ifdef OS_MSDOS
01133
01134 spawnvp((int) mode, cmdname, argv);
01135
01136 return SS_SUCCESS;
01137
01138 #endif
01139
01140 #ifdef OS_VMS
01141
01142 {
01143 char cmdstring[500], *pc;
01144 INT i, flags, status;
01145 va_list argptr;
01146
01147 $DESCRIPTOR(cmdstring_dsc, "dummy");
01148
01149 if (mode & P_DETACH) {
01150 cmdstring_dsc.dsc$w_length = strlen(cmdstring);
01151 cmdstring_dsc.dsc$a_pointer = cmdstring;
01152
01153 status = sys$creprc(0, &cmdstring_dsc,
01154 0, 0, 0, 0, 0, NULL, 4, 0, 0, PRC$M_DETACH);
01155 } else {
01156 flags = (mode & P_NOWAIT) ? 1 : 0;
01157
01158 for (pc = argv[0] + strlen(argv[0]); *pc != ']' && pc != argv[0]; pc--);
01159 if (*pc == ']')
01160 pc++;
01161
01162 strcpy(cmdstring, pc);
01163
01164 if (strchr(cmdstring, ';'))
01165 *strchr(cmdstring, ';') = 0;
01166
01167 strcat(cmdstring, " ");
01168
01169 for (i = 1; argv[i] != NULL; i++) {
01170 strcat(cmdstring, argv[i]);
01171 strcat(cmdstring, " ");
01172 }
01173
01174 cmdstring_dsc.dsc$w_length = strlen(cmdstring);
01175 cmdstring_dsc.dsc$a_pointer = cmdstring;
01176
01177 status = lib$spawn(&cmdstring_dsc, 0, 0, &flags, NULL, 0, 0, 0, 0, 0, 0, 0, 0);
01178 }
01179
01180 return BM_SUCCESS;
01181 }
01182
01183 #endif
01184 #ifdef OS_UNIX
01185 pid_t child_pid;
01186
01187 #ifdef OS_ULTRIX
01188 union wait *status;
01189 #else
01190 int status;
01191 #endif
01192
01193 if ((child_pid = fork()) < 0)
01194 return (-1);
01195
01196 if (child_pid == 0) {
01197
01198 child_pid = execvp(cmdname, argv);
01199 return SS_SUCCESS;
01200 } else {
01201
01202 if (mode == P_WAIT)
01203 #ifdef OS_ULTRIX
01204 waitpid(child_pid, status, WNOHANG);
01205 #else
01206 waitpid(child_pid, &status, WNOHANG);
01207 #endif
01208
01209 else
01210
01211 signal(SIGCHLD, catch_sigchld);
01212 }
01213
01214 return SS_SUCCESS;
01215
01216 #endif
01217 }
01218
01219
01220 INT ss_shell(int sock)
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237 {
01238 #ifdef OS_WINNT
01239
01240 HANDLE hChildStdinRd, hChildStdinWr, hChildStdinWrDup,
01241 hChildStdoutRd, hChildStdoutWr,
01242 hChildStderrRd, hChildStderrWr, hSaveStdin, hSaveStdout, hSaveStderr;
01243
01244 SECURITY_ATTRIBUTES saAttr;
01245 PROCESS_INFORMATION piProcInfo;
01246 STARTUPINFO siStartInfo;
01247 char buffer[256], cmd[256];
01248 DWORD dwRead, dwWritten, dwAvail, i, i_cmd;
01249 fd_set readfds;
01250 struct timeval timeout;
01251
01252
01253 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
01254 saAttr.bInheritHandle = TRUE;
01255 saAttr.lpSecurityDescriptor = NULL;
01256
01257
01258 hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE);
01259
01260
01261 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
01262 return 0;
01263
01264
01265 if (!SetStdHandle(STD_OUTPUT_HANDLE, hChildStdoutWr))
01266 return 0;
01267
01268
01269
01270 hSaveStderr = GetStdHandle(STD_ERROR_HANDLE);
01271
01272
01273 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
01274 return 0;
01275
01276
01277 if (!SetStdHandle(STD_ERROR_HANDLE, hChildStderrWr))
01278 return 0;
01279
01280
01281
01282 hSaveStdin = GetStdHandle(STD_INPUT_HANDLE);
01283
01284
01285 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
01286 return 0;
01287
01288
01289 if (!SetStdHandle(STD_INPUT_HANDLE, hChildStdinRd))
01290 return 0;
01291
01292
01293 if (!DuplicateHandle(GetCurrentProcess(), hChildStdinWr, GetCurrentProcess(), &hChildStdinWrDup, 0, FALSE,
01294 DUPLICATE_SAME_ACCESS))
01295 return 0;
01296
01297 CloseHandle(hChildStdinWr);
01298
01299
01300 memset(&siStartInfo, 0, sizeof(siStartInfo));
01301 siStartInfo.cb = sizeof(STARTUPINFO);
01302 siStartInfo.lpReserved = NULL;
01303 siStartInfo.lpReserved2 = NULL;
01304 siStartInfo.cbReserved2 = 0;
01305 siStartInfo.lpDesktop = NULL;
01306 siStartInfo.dwFlags = 0;
01307
01308 if (!CreateProcess(NULL, "cmd /Q",
01309 NULL,
01310 NULL,
01311 TRUE,
01312 0,
01313 NULL,
01314 NULL,
01315 &siStartInfo,
01316 &piProcInfo))
01317 return 0;
01318
01319
01320 SetStdHandle(STD_INPUT_HANDLE, hSaveStdin);
01321 SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout);
01322 SetStdHandle(STD_ERROR_HANDLE, hSaveStderr);
01323
01324 i_cmd = 0;
01325
01326 do {
01327
01328 do {
01329 if (!PeekNamedPipe(hChildStderrRd, buffer, 256, &dwRead, &dwAvail, NULL))
01330 break;
01331
01332 if (dwRead > 0) {
01333 ReadFile(hChildStderrRd, buffer, 256, &dwRead, NULL);
01334 send(sock, buffer, dwRead, 0);
01335 }
01336 } while (dwAvail > 0);
01337
01338
01339 do {
01340 if (!PeekNamedPipe(hChildStdoutRd, buffer, 256, &dwRead, &dwAvail, NULL))
01341 break;
01342 if (dwRead > 0) {
01343 ReadFile(hChildStdoutRd, buffer, 256, &dwRead, NULL);
01344 send(sock, buffer, dwRead, 0);
01345 }
01346 } while (dwAvail > 0);
01347
01348
01349
01350 if (!GetExitCodeProcess(piProcInfo.hProcess, &i))
01351 break;
01352 if (i != STILL_ACTIVE)
01353 break;
01354
01355
01356 FD_ZERO(&readfds);
01357 FD_SET(sock, &readfds);
01358 timeout.tv_sec = 0;
01359 timeout.tv_usec = 100;
01360 select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
01361
01362 if (FD_ISSET(sock, &readfds)) {
01363 i = recv(sock, cmd + i_cmd, 1, 0);
01364 if (i <= 0)
01365 break;
01366
01367
01368 if (cmd[i_cmd] == 8) {
01369 if (i_cmd > 0) {
01370 send(sock, "\b \b", 3, 0);
01371 i_cmd -= 1;
01372 }
01373 } else if (cmd[i_cmd] >= ' ' || cmd[i_cmd] == 13 || cmd[i_cmd] == 10) {
01374 send(sock, cmd + i_cmd, 1, 0);
01375 i_cmd += i;
01376 }
01377 }
01378
01379
01380 if (cmd[i_cmd - 1] == 10) {
01381 WriteFile(hChildStdinWrDup, cmd, i_cmd, &dwWritten, NULL);
01382 i_cmd = 0;
01383 }
01384
01385 } while (TRUE);
01386
01387 CloseHandle(hChildStdinWrDup);
01388 CloseHandle(hChildStdinRd);
01389 CloseHandle(hChildStderrRd);
01390 CloseHandle(hChildStdoutRd);
01391
01392 return SS_SUCCESS;
01393
01394 #endif
01395
01396 #ifdef OS_UNIX
01397 #ifndef NO_PTY
01398 pid_t pid;
01399 int i, pipe;
01400 char line[32], buffer[1024], shell[32];
01401 fd_set readfds;
01402
01403 if ((pid = forkpty(&pipe, line, NULL, NULL)) < 0)
01404 return 0;
01405 else if (pid > 0) {
01406
01407
01408 do {
01409 FD_ZERO(&readfds);
01410 FD_SET(sock, &readfds);
01411 FD_SET(pipe, &readfds);
01412
01413 select(FD_SETSIZE, (void *) &readfds, NULL, NULL, NULL);
01414
01415 if (FD_ISSET(sock, &readfds)) {
01416 memset(buffer, 0, sizeof(buffer));
01417 i = recv(sock, buffer, sizeof(buffer), 0);
01418 if (i <= 0)
01419 break;
01420 if (write(pipe, buffer, i) != i)
01421 break;
01422 }
01423
01424 if (FD_ISSET(pipe, &readfds)) {
01425 memset(buffer, 0, sizeof(buffer));
01426 i = read(pipe, buffer, sizeof(buffer));
01427 if (i <= 0)
01428 break;
01429 send(sock, buffer, i, 0);
01430 }
01431
01432 } while (1);
01433 } else {
01434
01435
01436 if (getenv("SHELL"))
01437 strlcpy(shell, getenv("SHELL"), sizeof(shell));
01438 else
01439 strcpy(shell, "/bin/sh");
01440 execl(shell, shell, 0);
01441 }
01442 #else
01443 send(sock, "not implemented\n", 17, 0);
01444 #endif
01445
01446 return SS_SUCCESS;
01447
01448 #endif
01449 }
01450
01451
01452 static BOOL _daemon_flag;
01453
01454 INT ss_daemon_init(BOOL keep_stdout)
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472 {
01473 #ifdef OS_UNIX
01474
01475
01476 int i, fd, pid;
01477
01478 if ((pid = fork()) < 0)
01479 return SS_ABORT;
01480 else if (pid != 0)
01481 exit(0);
01482
01483
01484
01485 _daemon_flag = TRUE;
01486
01487
01488
01489 for (i = 0; i < 3; i++) {
01490 if (keep_stdout && ((i == 1) || (i == 2)))
01491 continue;
01492
01493 close(i);
01494 fd = open("/dev/null", O_RDWR, 0);
01495 if (fd < 0)
01496 fd = open("/dev/null", O_WRONLY, 0);
01497 if (fd < 0) {
01498 cm_msg(MERROR, "ss_system", "Can't open /dev/null");
01499 return SS_ABORT;
01500 }
01501 if (fd != i) {
01502 cm_msg(MERROR, "ss_system", "Did not get file descriptor");
01503 return SS_ABORT;
01504 }
01505 }
01506
01507 setsid();
01508 chdir("/");
01509 umask(0);
01510
01511 #endif
01512
01513 return SS_SUCCESS;
01514 }
01515
01516
01517 BOOL ss_existpid(INT pid)
01518
01519
01520
01521
01522
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534
01535 {
01536 #ifdef OS_UNIX
01537
01538 return (kill(pid, 0) == 0 ? TRUE : FALSE);
01539 #else
01540 cm_msg(MINFO, "ss_existpid", "implemented for UNIX only");
01541 return FALSE;
01542 #endif
01543 }
01544
01545
01546
01547 #endif
01548
01549
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564
01565
01566
01567 INT ss_system(char *command)
01568 {
01569 #ifdef OS_UNIX
01570 INT childpid;
01571
01572 return ss_exec(command, &childpid);
01573
01574 #else
01575
01576 system(command);
01577 return SS_SUCCESS;
01578
01579 #endif
01580 }
01581
01582
01583 #ifndef DOXYGEN_SHOULD_SKIP_THIS
01584
01585
01586 INT ss_exec(char *command, INT * pid)
01587
01588
01589
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604
01605 {
01606 #ifdef OS_UNIX
01607
01608
01609 int i, fd;
01610
01611 if ((*pid = fork()) < 0)
01612 return SS_ABORT;
01613 else if (*pid != 0) {
01614
01615 signal(SIGCHLD, catch_sigchld);
01616 return SS_SUCCESS;
01617 }
01618
01619
01620
01621
01622 for (i = 0; i < 256; i++)
01623 close(i);
01624
01625
01626
01627 for (i = 0; i < 3; i++) {
01628 fd = open("/dev/null", O_RDWR, 0);
01629 if (fd < 0)
01630 fd = open("/dev/null", O_WRONLY, 0);
01631 if (fd < 0) {
01632 cm_msg(MERROR, "ss_exec", "Can't open /dev/null");
01633 return SS_ABORT;
01634 }
01635 if (fd != i) {
01636 cm_msg(MERROR, "ss_exec", "Did not get file descriptor");
01637 return SS_ABORT;
01638 }
01639 }
01640
01641 setsid();
01642
01643 umask(0);
01644
01645
01646 execl("/bin/sh", "sh", "-c", command, NULL);
01647
01648 #else
01649
01650 system(command);
01651
01652 #endif
01653
01654 return SS_SUCCESS;
01655 }
01656
01657
01658 #endif
01659
01660
01661
01662
01663
01664
01665
01666
01667
01668
01669
01670
01671
01672
01673
01674
01675
01676
01677
01678
01679
01680
01681
01682
01683
01684
01685
01686
01687
01688
01689
01690
01691
01692
01693 midas_thread_t ss_thread_create(INT(*thread_func) (void *), void *param)
01694 {
01695 #if defined(OS_WINNT)
01696
01697 HANDLE status;
01698 DWORD thread_id;
01699
01700 if (thread_func == NULL) {
01701 return 0;
01702 }
01703
01704 status = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) thread_func,
01705 (LPVOID) param, 0, &thread_id);
01706
01707 return status == NULL ? 0 : (midas_thread_t)thread_id;
01708
01709 #elif defined(OS_MSDOS)
01710
01711 return 0;
01712
01713 #elif defined(OS_VMS)
01714
01715 return 0;
01716
01717 #elif defined(OS_VXWORKS)
01718
01719
01720
01721
01722
01723
01724
01725
01726 INT status;
01727 VX_TASK_SPAWN *ts;
01728
01729 ts = (VX_TASK_SPAWN *) param;
01730 status =
01731 taskSpawn(ts->name, ts->priority, ts->options, ts->stackSize,
01732 (FUNCPTR) thread_func, ts->arg1, ts->arg2, ts->arg3,
01733 ts->arg4, ts->arg5, ts->arg6, ts->arg7, ts->arg8, ts->arg9, ts->arg10);
01734
01735 return status == ERROR ? 0 : status;
01736
01737 #elif defined(OS_UNIX)
01738
01739 INT status;
01740 pthread_t thread_id;
01741
01742 status = pthread_create(&thread_id, NULL, (void *) thread_func, param);
01743
01744 return status != 0 ? 0 : thread_id;
01745
01746 #endif
01747 }
01748
01749
01750
01751
01752
01753
01754
01755
01756
01757
01758
01759
01760
01761
01762
01763
01764
01765
01766
01767 INT ss_thread_kill(midas_thread_t thread_id)
01768 {
01769 #if defined(OS_WINNT)
01770
01771 DWORD status;
01772
01773 status = TerminateThread(thread_id, 0);
01774
01775 return status != 0 ? SS_SUCCESS : SS_NO_THREAD;
01776
01777 #elif defined(OS_MSDOS)
01778
01779 return 0;
01780
01781 #elif defined(OS_VMS)
01782
01783 return 0;
01784
01785 #elif defined(OS_VXWORKS)
01786
01787 INT status;
01788 status = taskDelete(thread_id);
01789 return status == OK ? 0 : ERROR;
01790
01791 #elif defined(OS_UNIX)
01792
01793 INT status;
01794 status = pthread_kill(thread_id, SIGKILL);
01795 return status == 0 ? SS_SUCCESS : SS_NO_THREAD;
01796
01797 #endif
01798 }
01799
01800
01801 #ifndef DOXYGEN_SHOULD_SKIP_THIS
01802
01803
01804 static INT skip_mutex_handle = -1;
01805
01806 INT ss_mutex_create(char *name, HNDLE * mutex_handle)
01807
01808
01809
01810
01811
01812
01813
01814
01815
01816
01817
01818
01819
01820
01821
01822
01823
01824
01825
01826
01827
01828
01829
01830
01831
01832
01833 {
01834 char mutex_name[256], path[256], file_name[256];
01835
01836
01837 sprintf(mutex_name, "MX_%s", name);
01838
01839 #ifdef OS_VXWORKS
01840
01841
01842
01843 if ((*((SEM_ID *) mutex_handle) = semBCreate(SEM_Q_FIFO, SEM_EMPTY)) == NULL)
01844 return SS_NO_MUTEX;
01845 return SS_CREATED;
01846
01847 #endif
01848
01849
01850 cm_get_path(path);
01851 if (path[0] == 0) {
01852 getcwd(path, 256);
01853 #if defined(OS_VMS)
01854 #elif defined(OS_UNIX)
01855 strcat(path, "/");
01856 #elif defined(OS_WINNT)
01857 strcat(path, "\\");
01858 #endif
01859 }
01860
01861 strcpy(file_name, path);
01862 #if defined (OS_UNIX)
01863 strcat(file_name, ".");
01864 #endif
01865 strcat(file_name, name);
01866 strcat(file_name, ".SHM");
01867
01868 #ifdef OS_WINNT
01869
01870 *mutex_handle = (HNDLE) CreateMutex(NULL, FALSE, mutex_name);
01871
01872 if (*mutex_handle == 0)
01873 return SS_NO_MUTEX;
01874
01875 return SS_CREATED;
01876
01877 #endif
01878 #ifdef OS_VMS
01879
01880
01881
01882 {
01883 INT status;
01884 $DESCRIPTOR(mutexname_dsc, "dummy");
01885 mutexname_dsc.dsc$w_length = strlen(mutex_name);
01886 mutexname_dsc.dsc$a_pointer = mutex_name;
01887
01888 *mutex_handle = (HNDLE) malloc(8);
01889
01890 status = sys$enqw(0, LCK$K_NLMODE, *mutex_handle, 0, &mutexname_dsc,
01891 0, 0, 0, 0, 0, 0);
01892
01893 if (status != SS$_NORMAL) {
01894 free((void *) *mutex_handle);
01895 *mutex_handle = 0;
01896 }
01897
01898 if (*mutex_handle == 0)
01899 return SS_NO_MUTEX;
01900
01901 return SS_CREATED;
01902 }
01903
01904 #endif
01905 #ifdef OS_UNIX
01906
01907 {
01908 INT key, status, fh;
01909 struct semid_ds buf;
01910
01911 #if (defined(OS_LINUX) && !defined(_SEM_SEMUN_UNDEFINED)) || defined(OS_FREEBSD)
01912 union semun arg;
01913 #else
01914 union semun {
01915 INT val;
01916 struct semid_ds *buf;
01917 ushort *array;
01918 } arg;
01919 #endif
01920
01921 status = SS_SUCCESS;
01922
01923
01924 key = ftok(file_name, 'M');
01925 if (key < 0) {
01926 fh = open(file_name, O_CREAT, 0644);
01927 close(fh);
01928 key = ftok(file_name, 'M');
01929 status = SS_CREATED;
01930 }
01931
01932
01933 *mutex_handle = (HNDLE) semget(key, 1, 0);
01934 if (*mutex_handle < 0) {
01935 *mutex_handle = (HNDLE) semget(key, 1, IPC_CREAT);
01936 status = SS_CREATED;
01937 }
01938
01939 if (*mutex_handle < 0) {
01940 cm_msg(MERROR, "ss_mutex_mutex", "semget() failed, errno = %d", errno);
01941 return SS_NO_MUTEX;
01942 }
01943
01944 buf.sem_perm.uid = getuid();
01945 buf.sem_perm.gid = getgid();
01946 buf.sem_perm.mode = 0666;
01947 arg.buf = &buf;
01948
01949 semctl(*mutex_handle, 0, IPC_SET, arg);
01950
01951
01952 if (status == SS_CREATED) {
01953 arg.val = 1;
01954 if (semctl(*mutex_handle, 0, SETVAL, arg) < 0)
01955 return SS_NO_MUTEX;
01956 }
01957
01958 return SS_SUCCESS;
01959 }
01960 #endif
01961
01962 #ifdef OS_MSDOS
01963 return SS_NO_MUTEX;
01964 #endif
01965 }
01966
01967
01968 INT ss_mutex_wait_for(HNDLE mutex_handle, INT timeout)
01969
01970
01971
01972
01973
01974
01975
01976
01977
01978
01979
01980
01981
01982
01983
01984
01985
01986
01987
01988 {
01989 INT status;
01990
01991 #ifdef OS_WINNT
01992
01993 status = WaitForSingleObject((HANDLE) mutex_handle, timeout == 0 ? INFINITE : timeout);
01994 if (status == WAIT_FAILED)
01995 return SS_NO_MUTEX;
01996 if (status == WAIT_TIMEOUT)
01997 return SS_TIMEOUT;
01998
01999 return SS_SUCCESS;
02000 #endif
02001 #ifdef OS_VMS
02002 status = sys$enqw(0, LCK$K_EXMODE, mutex_handle, LCK$M_CONVERT, 0, 0, 0, 0, 0, 0, 0);
02003 if (status != SS$_NORMAL)
02004 return SS_NO_MUTEX;
02005 return SS_SUCCESS;
02006
02007 #endif
02008 #ifdef OS_VXWORKS
02009
02010 status = semTake((SEM_ID) mutex_handle, timeout == 0 ? WAIT_FOREVER : timeout >> 4);
02011 if (status == ERROR)
02012 return SS_NO_MUTEX;
02013 return SS_SUCCESS;
02014
02015 #endif
02016 #ifdef OS_UNIX
02017 {
02018 DWORD start_time;
02019 struct sembuf sb;
02020
02021 #if (defined(OS_LINUX) && !defined(_SEM_SEMUN_UNDEFINED)) || defined(OS_FREEBSD)
02022 union semun arg;
02023 #else
02024 union semun {
02025 INT val;
02026 struct semid_ds *buf;
02027 ushort *array;
02028 } arg;
02029 #endif
02030
02031 sb.sem_num = 0;
02032 sb.sem_op = -1;
02033 sb.sem_flg = SEM_UNDO;
02034
02035 memset(&arg, 0, sizeof(arg));
02036
02037
02038
02039 if (ss_in_async_routine_flag)
02040 if (semctl(mutex_handle, 0, GETPID, arg) == getpid())
02041 if (semctl(mutex_handle, 0, GETVAL, arg) == 0) {
02042 skip_mutex_handle = mutex_handle;
02043 return SS_SUCCESS;
02044 }
02045
02046 skip_mutex_handle = -1;
02047
02048 start_time = ss_millitime();
02049
02050 do {
02051 status = semop(mutex_handle, &sb, 1);
02052
02053
02054 if (status == 0)
02055 break;
02056
02057
02058 if (errno == EINTR) {
02059
02060 if (timeout > 0 && ss_millitime() - start_time > timeout)
02061 return SS_TIMEOUT;
02062
02063 continue;
02064 }
02065
02066 return SS_NO_MUTEX;
02067 } while (1);
02068
02069 return SS_SUCCESS;
02070 }
02071 #endif
02072
02073 #ifdef OS_MSDOS
02074 return SS_NO_MUTEX;
02075 #endif
02076 }
02077
02078
02079 INT ss_mutex_release(HNDLE mutex_handle)
02080
02081
02082
02083
02084
02085
02086
02087
02088
02089
02090
02091
02092
02093
02094
02095
02096
02097 {
02098 INT status;
02099
02100 #ifdef OS_WINNT
02101
02102 status = ReleaseMutex((HANDLE) mutex_handle);
02103
02104 if (status == FALSE)
02105 return SS_NO_MUTEX;
02106
02107 return SS_SUCCESS;
02108
02109 #endif
02110 #ifdef OS_VMS
02111
02112 status = sys$enqw(0, LCK$K_NLMODE, mutex_handle, LCK$M_CONVERT, 0, 0, 0, 0, 0, 0, 0);
02113
02114 if (status != SS$_NORMAL)
02115 return SS_NO_MUTEX;
02116
02117 return SS_SUCCESS;
02118
02119 #endif
02120
02121 #ifdef OS_VXWORKS
02122
02123 if (semGive((SEM_ID) mutex_handle) == ERROR)
02124 return SS_NO_MUTEX;
02125 return SS_SUCCESS;
02126 #endif
02127
02128 #ifdef OS_UNIX
02129 {
02130 struct sembuf sb;
02131
02132 sb.sem_num = 0;
02133 sb.sem_op = 1;
02134 sb.sem_flg = SEM_UNDO;
02135
02136 if (mutex_handle == skip_mutex_handle) {
02137 skip_mutex_handle = -1;
02138 return SS_SUCCESS;
02139 }
02140
02141 do {
02142 status = semop(mutex_handle, &sb, 1);
02143
02144
02145 if (status == 0)
02146 break;
02147
02148
02149 if (errno == EINTR)
02150 continue;
02151
02152 return SS_NO_MUTEX;
02153 } while (1);
02154
02155 return SS_SUCCESS;
02156 }
02157 #endif
02158
02159 #ifdef OS_MSDOS
02160 return SS_NO_MUTEX;
02161 #endif
02162 }
02163
02164
02165 INT ss_mutex_delete(HNDLE mutex_handle, INT destroy_flag)
02166
02167
02168
02169
02170
02171
02172
02173
02174
02175
02176
02177
02178
02179
02180
02181
02182
02183 {
02184 #ifdef OS_WINNT
02185
02186 if (CloseHandle((HANDLE) mutex_handle) == FALSE)
02187 return SS_NO_MUTEX;
02188
02189 return SS_SUCCESS;
02190
02191 #endif
02192 #ifdef OS_VMS
02193
02194 free((void *) mutex_handle);
02195 return SS_SUCCESS;
02196
02197 #endif
02198
02199 #ifdef OS_VXWORKS
02200
02201 if (semDelete((SEM_ID) mutex_handle) == ERROR)
02202 return SS_NO_MUTEX;
02203 return SS_SUCCESS;
02204 #endif
02205
02206 #ifdef OS_UNIX
02207 #if (defined(OS_LINUX) && !defined(_SEM_SEMUN_UNDEFINED)) || defined(OS_FREEBSD)
02208 union semun arg;
02209 #else
02210 union semun {
02211 INT val;
02212 struct semid_ds *buf;
02213 ushort *array;
02214 } arg;
02215 #endif
02216
02217 memset(&arg, 0, sizeof(arg));
02218
02219 if (destroy_flag)
02220 if (semctl(mutex_handle, 0, IPC_RMID, arg) < 0)
02221 return SS_NO_MUTEX;
02222
02223 return SS_SUCCESS;
02224
02225 #endif
02226
02227 #ifdef OS_MSDOS
02228 return SS_NO_MUTEX;
02229 #endif
02230 }
02231
02232
02233 #endif
02234
02235
02236
02237
02238
02239
02240
02241
02242
02243
02244
02245
02246
02247
02248
02249
02250
02251
02252
02253 DWORD ss_millitime()
02254 {
02255 #ifdef OS_WINNT
02256
02257 return (int) GetTickCount();
02258
02259 #endif
02260 #ifdef OS_MSDOS
02261
02262 return clock() * 55;
02263
02264 #endif
02265 #ifdef OS_VMS
02266
02267 {
02268 char time[8];
02269 DWORD lo, hi;
02270
02271 sys$gettim(time);
02272
02273 lo = *((DWORD *) time);
02274 hi = *((DWORD *) (time + 4));
02275
02276
02277
02278 return lo / 10000 + hi * 429496.7296;
02279
02280 }
02281
02282 #endif
02283 #ifdef OS_UNIX
02284 {
02285 struct timeval tv;
02286
02287 gettimeofday(&tv, NULL);
02288
02289 return tv.tv_sec * 1000 + tv.tv_usec / 1000;
02290 }
02291
02292 #endif
02293 #ifdef OS_VXWORKS
02294 {
02295 int count;
02296 static int ticks_per_msec = 0;
02297
02298 if (ticks_per_msec == 0)
02299 ticks_per_msec = 1000 / sysClkRateGet();
02300
02301 return tickGet() * ticks_per_msec;
02302 }
02303 #endif
02304 }
02305
02306
02307
02308
02309
02310
02311
02312
02313
02314
02315
02316
02317
02318
02319
02320 DWORD ss_time()
02321 {
02322 #if !defined(OS_VXWORKS)
02323 #if !defined(OS_VMS)
02324 tzset();
02325 #endif
02326 #endif
02327 return (DWORD) time(NULL);
02328 }
02329
02330
02331 #ifndef DOXYGEN_SHOULD_SKIP_THIS
02332
02333
02334 DWORD ss_settime(DWORD seconds)
02335
02336
02337
02338
02339
02340
02341
02342
02343
02344
02345
02346
02347
02348
02349
02350 {
02351 #if defined(OS_WINNT)
02352 SYSTEMTIME st;
02353 struct tm *ltm;
02354
02355 tzset();
02356 ltm = localtime((time_t *) & seconds);
02357
02358 st.wYear = ltm->tm_year + 1900;
02359 st.wMonth = ltm->tm_mon + 1;
02360 st.wDay = ltm->tm_mday;
02361 st.wHour = ltm->tm_hour;
02362 st.wMinute = ltm->tm_min;
02363 st.wSecond = ltm->tm_sec;
02364 st.wMilliseconds = 0;
02365
02366 SetLocalTime(&st);
02367
02368 #elif defined(OS_DARWIN)
02369
02370 assert(!"ss_settime() is not supported");
02371
02372 return SS_NO_DRIVER;
02373
02374 #elif defined(OS_UNIX)
02375
02376 stime((time_t *) & seconds);
02377
02378 #elif defined(OS_VXWORKS)
02379
02380 struct timespec ltm;
02381
02382 ltm.tv_sec = seconds;
02383 ltm.tv_nsec = 0;
02384 clock_settime(CLOCK_REALTIME, <m);
02385
02386 #endif
02387 return SS_SUCCESS;
02388 }
02389
02390
02391 char *ss_asctime()
02392
02393
02394
02395
02396
02397
02398
02399
02400
02401
02402
02403
02404
02405
02406
02407
02408 {
02409 static char str[32];
02410 time_t seconds;
02411
02412 seconds = (time_t) ss_time();
02413
02414 #if !defined(OS_VXWORKS)
02415 #if !defined(OS_VMS)
02416 tzset();
02417 #endif
02418 #endif
02419 strcpy(str, asctime(localtime(&seconds)));
02420
02421
02422 str[24] = 0;
02423
02424 return str;
02425 }
02426
02427
02428 INT ss_timezone()
02429
02430
02431
02432
02433
02434
02435
02436
02437
02438
02439
02440
02441
02442
02443
02444
02445
02446 {
02447 #if defined(OS_DARWIN) || defined(OS_VXWORKS)
02448 return 0;
02449 #else
02450 return timezone;
02451 #endif
02452 }
02453
02454
02455
02456
02457 #ifdef OS_UNIX
02458
02459 void ss_cont()
02460 {
02461 }
02462 #endif
02463
02464
02465 #endif
02466
02467
02468
02469
02470
02471
02472
02473
02474
02475
02476
02477
02478
02479 INT ss_sleep(INT millisec)
02480 {
02481 fd_set readfds;
02482 struct timeval timeout;
02483 int status;
02484 static int sock = 0;
02485
02486 if (millisec == 0) {
02487 #ifdef OS_WINNT
02488 SuspendThread(GetCurrentThread());
02489 #endif
02490 #ifdef OS_VMS
02491 sys$hiber();
02492 #endif
02493 #ifdef OS_UNIX
02494 signal(SIGCONT, ss_cont);
02495 pause();
02496 #endif
02497 return SS_SUCCESS;
02498 }
02499 #ifdef OS_WINNT
02500 {
02501 WSADATA WSAData;
02502
02503
02504 if (WSAStartup(MAKEWORD(1, 1), &WSAData) != 0)
02505 return SS_SOCKET_ERROR;
02506 }
02507 #endif
02508
02509 timeout.tv_sec = millisec / 1000;
02510 timeout.tv_usec = (millisec % 1000) * 1000;
02511
02512 if (!sock)
02513 sock = socket(AF_INET, SOCK_DGRAM, 0);
02514
02515 FD_ZERO(&readfds);
02516 FD_SET(sock, &readfds);
02517 do {
02518 status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
02519
02520
02521 if (status == -1 && timeout.tv_sec >= WATCHDOG_INTERVAL / 1000)
02522 timeout.tv_sec -= WATCHDOG_INTERVAL / 1000;
02523
02524 } while (status == -1);
02525
02526 return SS_SUCCESS;
02527 }
02528
02529
02530 #ifndef DOXYGEN_SHOULD_SKIP_THIS
02531
02532
02533 BOOL ss_kbhit()
02534
02535
02536
02537
02538
02539
02540
02541
02542
02543
02544
02545
02546
02547
02548
02549
02550
02551 {
02552 #ifdef OS_MSDOS
02553
02554 return kbhit();
02555
02556 #endif
02557 #ifdef OS_WINNT
02558
02559 return kbhit();
02560
02561 #endif
02562 #ifdef OS_VMS
02563
02564 return FALSE;
02565
02566 #endif
02567 #ifdef OS_UNIX
02568
02569 int n;
02570
02571 if (_daemon_flag)
02572 return 0;
02573
02574 ioctl(0, FIONREAD, &n);
02575 return (n > 0);
02576
02577 #endif
02578 #ifdef OS_VXWORKS
02579
02580 int n;
02581 ioctl(0, FIONREAD, (long) &n);
02582 return (n > 0);
02583
02584 #endif
02585 }
02586
02587
02588
02589 #ifdef LOCAL_ROUTINES
02590
02591 INT ss_wake(INT pid, INT tid, INT thandle)
02592
02593
02594
02595
02596
02597
02598
02599
02600
02601
02602
02603
02604
02605
02606
02607
02608
02609
02610
02611
02612
02613 {
02614 #ifdef OS_WINNT
02615 HANDLE process_handle;
02616 HANDLE dup_thread_handle;
02617
02618
02619
02620
02621
02622
02623
02624
02625
02626
02627 process_handle = OpenProcess(PROCESS_ALL_ACCESS, TRUE, pid);
02628
02629 if (process_handle == 0)
02630 return SS_NO_PROCESS;
02631
02632 DuplicateHandle(process_handle, (HANDLE) thandle, GetCurrentProcess(),
02633 &dup_thread_handle, THREAD_ALL_ACCESS, TRUE, 0);
02634
02635
02636 CloseHandle(process_handle);
02637
02638 if (dup_thread_handle == 0)
02639 return SS_NO_PROCESS;
02640
02641 ResumeThread(dup_thread_handle);
02642
02643
02644 CloseHandle(dup_thread_handle);
02645
02646 return SS_SUCCESS;
02647
02648 #endif
02649 #ifdef OS_VMS
02650
02651 if (sys$wake(&pid, 0) == SS$_NONEXPR)
02652 return SS_NO_PROCESS;
02653
02654 return SS_SUCCESS;
02655
02656 #endif
02657 #ifdef OS_UNIX
02658
02659 if (kill(pid, SIGCONT) < 0)
02660 return SS_NO_PROCESS;
02661
02662 return SS_SUCCESS;
02663
02664
02665
02666
02667
02668
02669
02670
02671
02672 #endif
02673 }
02674
02675
02676 #ifdef OS_WINNT
02677
02678 static void (*UserCallback) (int);
02679 static UINT _timer_id = 0;
02680
02681 VOID CALLBACK _timeCallback(UINT idEvent, UINT uReserved, DWORD dwUser,
02682 DWORD dwReserved1, DWORD dwReserved2)
02683 {
02684 _timer_id = 0;
02685 if (UserCallback != NULL)
02686 UserCallback(0);
02687 }
02688
02689 #endif
02690
02691 INT ss_alarm(INT millitime, void (*func) (int))
02692
02693
02694
02695
02696
02697
02698
02699
02700
02701
02702
02703
02704
02705
02706
02707
02708
02709
02710
02711 {
02712 #ifdef OS_WINNT
02713
02714 UserCallback = func;
02715 if (millitime > 0)
02716 _timer_id =
02717 timeSetEvent(millitime, 100, (LPTIMECALLBACK) _timeCallback, 0, TIME_ONESHOT);
02718 else {
02719 if (_timer_id)
02720 timeKillEvent(_timer_id);
02721 _timer_id = 0;
02722 }
02723
02724 return SS_SUCCESS;
02725
02726 #endif
02727 #ifdef OS_VMS
02728
02729 signal(SIGALRM, func);
02730 alarm(millitime / 1000);
02731 return SS_SUCCESS;
02732
02733 #endif
02734 #ifdef OS_UNIX
02735
02736 signal(SIGALRM, func);
02737 alarm(millitime / 1000);
02738 return SS_SUCCESS;
02739
02740 #endif
02741 }
02742
02743
02744 void (*MidasExceptionHandler) ();
02745
02746 #ifdef OS_WINNT
02747
02748 LONG MidasExceptionFilter(LPEXCEPTION_POINTERS pexcep)
02749 {
02750 if (MidasExceptionHandler != NULL)
02751 MidasExceptionHandler();
02752
02753 return EXCEPTION_CONTINUE_SEARCH;
02754 }
02755
02756 INT MidasExceptionSignal(INT sig)
02757 {
02758 if (MidasExceptionHandler != NULL)
02759 MidasExceptionHandler();
02760
02761 raise(sig);
02762
02763 return 0;
02764 }
02765
02766
02767
02768
02769
02770
02771
02772
02773
02774
02775
02776 #endif
02777
02778 #ifdef OS_VMS
02779
02780 INT MidasExceptionFilter(INT * sigargs, INT * mechargs)
02781 {
02782 if (MidasExceptionHandler != NULL)
02783 MidasExceptionHandler();
02784
02785 return (SS$_RESIGNAL);
02786 }
02787
02788 void MidasExceptionSignal(INT sig)
02789 {
02790 if (MidasExceptionHandler != NULL)
02791 MidasExceptionHandler();
02792
02793 kill(getpid(), sig);
02794 }
02795
02796 #endif
02797
02798
02799 INT ss_exception_handler(void (*func) ())
02800
02801
02802
02803
02804
02805
02806
02807
02808
02809
02810
02811
02812
02813
02814
02815
02816
02817
02818 {
02819 #ifdef OS_WINNT
02820
02821 MidasExceptionHandler = func;
02822
02823
02824
02825
02826
02827
02828
02829
02830
02831
02832
02833 #endif
02834 #ifdef OS_VMS
02835
02836 MidasExceptionHandler = func;
02837 lib$establish(MidasExceptionFilter);
02838
02839 signal(SIGINT, MidasExceptionSignal);
02840 signal(SIGILL, MidasExceptionSignal);
02841 signal(SIGQUIT, MidasExceptionSignal);
02842 signal(SIGFPE, MidasExceptionSignal);
02843 signal(SIGSEGV, MidasExceptionSignal);
02844 signal(SIGTERM, MidasExceptionSignal);
02845
02846 #endif
02847
02848 return SS_SUCCESS;
02849 }
02850
02851 #endif
02852
02853
02854 void *ss_ctrlc_handler(void (*func) (int))
02855
02856
02857
02858
02859
02860
02861
02862
02863
02864
02865
02866
02867
02868
02869
02870
02871
02872
02873
02874 {
02875 #ifdef OS_WINNT
02876
02877 if (func == NULL) {
02878 signal(SIGBREAK, SIG_DFL);
02879 return signal(SIGINT, SIG_DFL);
02880 } else {
02881 signal(SIGBREAK, func);
02882 return signal(SIGINT, func);
02883 }
02884 return NULL;
02885
02886 #endif
02887 #ifdef OS_VMS
02888
02889 return signal(SIGINT, func);
02890
02891 #endif
02892
02893 #ifdef OS_UNIX
02894
02895 if (func == NULL) {
02896 signal(SIGTERM, SIG_DFL);
02897 return (void *) signal(SIGINT, SIG_DFL);
02898 } else {
02899 signal(SIGTERM, func);
02900 return (void *) signal(SIGINT, func);
02901 }
02902
02903 #endif
02904 }
02905
02906
02907
02908
02909
02910
02911
02912
02913
02914
02915
02916
02917
02918
02919
02920
02921
02922
02923
02924 typedef struct {
02925 BOOL in_use;
02926 INT thread_id;
02927 INT ipc_port;
02928 INT ipc_recv_socket;
02929 INT ipc_send_socket;
02930 INT(*ipc_dispatch) (char *, INT);
02931 INT listen_socket;
02932 INT(*listen_dispatch) (INT);
02933 RPC_SERVER_CONNECTION *server_connection;
02934 INT(*client_dispatch) (INT);
02935 RPC_SERVER_ACCEPTION *server_acception;
02936 INT(*server_dispatch) (INT, int, BOOL);
02937 struct sockaddr_in bind_addr;
02938 } SUSPEND_STRUCT;
02939
02940 SUSPEND_STRUCT *_suspend_struct = NULL;
02941 INT _suspend_entries;
02942
02943
02944 INT ss_suspend_init_ipc(INT index)
02945
02946
02947
02948
02949
02950
02951
02952
02953
02954
02955
02956
02957
02958
02959
02960
02961
02962
02963 {
02964 INT status, sock;
02965 int i;
02966 struct sockaddr_in bind_addr;
02967 char local_host_name[HOST_NAME_LENGTH];
02968 struct hostent *phe;
02969
02970 #ifdef OS_WINNT
02971 {
02972 WSADATA WSAData;
02973
02974
02975 if (WSAStartup(MAKEWORD(1, 1), &WSAData) != 0)
02976 return SS_SOCKET_ERROR;
02977 }
02978 #endif
02979
02980
02981 sock = socket(AF_INET, SOCK_DGRAM, 0);
02982 if (sock == -1)
02983 return SS_SOCKET_ERROR;
02984
02985
02986 memset(&bind_addr, 0, sizeof(bind_addr));
02987 bind_addr.sin_family = AF_INET;
02988 bind_addr.sin_addr.s_addr = 0;
02989 bind_addr.sin_port = 0;
02990
02991 gethostname(local_host_name, sizeof(local_host_name));
02992
02993 #ifdef OS_VXWORKS
02994 {
02995 INT host_addr;
02996
02997 host_addr = hostGetByName(local_host_name);
02998 memcpy((char *) &(bind_addr.sin_addr), &host_addr, 4);
02999 }
03000 #else
03001 phe = gethostbyname(local_host_name);
03002 if (phe == NULL) {
03003 cm_msg(MERROR, "ss_suspend_init_ipc", "cannot get host name");
03004 return SS_SOCKET_ERROR;
03005 }
03006 memcpy((char *) &(bind_addr.sin_addr), phe->h_addr, phe->h_length);
03007 #endif
03008
03009 status = bind(sock, (struct sockaddr *) &bind_addr, sizeof(bind_addr));
03010 if (status < 0)
03011 return SS_SOCKET_ERROR;
03012
03013
03014 i = sizeof(bind_addr);
03015 getsockname(sock, (struct sockaddr *) &bind_addr, (int *) &i);
03016
03017 _suspend_struct[index].ipc_recv_socket = sock;
03018 _suspend_struct[index].ipc_port = ntohs(bind_addr.sin_port);
03019
03020
03021 sock = socket(AF_INET, SOCK_DGRAM, 0);
03022
03023 if (sock == -1)
03024 return SS_SOCKET_ERROR;
03025
03026
03027 memset(&bind_addr, 0, sizeof(bind_addr));
03028 bind_addr.sin_family = AF_INET;
03029 bind_addr.sin_addr.s_addr = 0;
03030
03031 #ifdef OS_VXWORKS
03032 {
03033 INT host_addr;
03034
03035 host_addr = hostGetByName(local_host_name);
03036 memcpy((char *) &(bind_addr.sin_addr), &host_addr, 4);
03037 }
03038 #else
03039 memcpy((char *) &(bind_addr.sin_addr), phe->h_addr, phe->h_length);
03040 #endif
03041
03042 memcpy(&_suspend_struct[index].bind_addr, &bind_addr, sizeof(bind_addr));
03043 _suspend_struct[index].ipc_send_socket = sock;
03044
03045 return SS_SUCCESS;
03046 }
03047
03048
03049 INT ss_suspend_get_index(INT * pindex)
03050
03051
03052
03053
03054
03055
03056
03057
03058
03059
03060
03061
03062
03063
03064
03065
03066
03067
03068
03069 {
03070 INT index;
03071
03072 if (_suspend_struct == NULL) {
03073
03074 _suspend_struct = (SUSPEND_STRUCT *) malloc(sizeof(SUSPEND_STRUCT));
03075 memset(_suspend_struct, 0, sizeof(SUSPEND_STRUCT));
03076 if (_suspend_struct == NULL)
03077 return SS_NO_MEMORY;
03078
03079 _suspend_entries = 1;
03080 *pindex = 0;
03081 _suspend_struct[0].thread_id = ss_gettid();
03082 _suspend_struct[0].in_use = TRUE;
03083 } else {
03084
03085 for (index = 0; index < _suspend_entries; index++)
03086 if (_suspend_struct[index].thread_id == ss_gettid()) {
03087 if (pindex != NULL)
03088 *pindex = index;
03089
03090 return SS_SUCCESS;
03091 }
03092
03093
03094 for (index = 0; index < _suspend_entries; index++)
03095 if (!_suspend_struct[index].in_use)
03096 break;
03097
03098 if (index == _suspend_entries) {
03099
03100 _suspend_struct = (SUSPEND_STRUCT *) realloc(_suspend_struct,
03101 sizeof
03102 (SUSPEND_STRUCT) *
03103 (_suspend_entries + 1));
03104 memset(&_suspend_struct[_suspend_entries], 0, sizeof(SUSPEND_STRUCT));
03105
03106 _suspend_entries++;
03107 if (_suspend_struct == NULL) {
03108 _suspend_entries--;
03109 return SS_NO_MEMORY;
03110 }
03111 }
03112 *pindex = index;
03113 _suspend_struct[index].thread_id = ss_gettid();
03114 _suspend_struct[index].in_use = TRUE;
03115 }
03116
03117 return SS_SUCCESS;
03118 }
03119
03120
03121 INT ss_suspend_exit()
03122
03123
03124
03125
03126
03127
03128
03129
03130
03131
03132
03133
03134
03135
03136
03137
03138
03139 {
03140 INT i, status;
03141
03142 status = ss_suspend_get_index(&i);
03143
03144 if (status != SS_SUCCESS)
03145 return status;
03146
03147 if (_suspend_struct[i].ipc_recv_socket) {
03148 closesocket(_suspend_struct[i].ipc_recv_socket);
03149 closesocket(_suspend_struct[i].ipc_send_socket);
03150 }
03151
03152 memset(&_suspend_struct[i], 0, sizeof(SUSPEND_STRUCT));
03153
03154
03155 for (i = _suspend_entries - 1; i >= 0; i--)
03156 if (_suspend_struct[i].in_use)
03157 break;
03158
03159 _suspend_entries = i + 1;
03160
03161 if (_suspend_entries == 0) {
03162 free(_suspend_struct);
03163 _suspend_struct = NULL;
03164 }
03165
03166 return SS_SUCCESS;
03167 }
03168
03169
03170 INT ss_suspend_set_dispatch(INT channel, void *connection, INT(*dispatch) ())
03171
03172
03173
03174
03175
03176
03177
03178
03179
03180
03181
03182
03183
03184
03185
03186
03187
03188
03189
03190
03191
03192
03193
03194
03195
03196
03197
03198
03199 {
03200 INT i, status;
03201
03202 status = ss_suspend_get_index(&i);
03203
03204 if (status != SS_SUCCESS)
03205 return status;
03206
03207 if (channel == CH_IPC) {
03208 _suspend_struct[i].ipc_dispatch = (INT(*)(char *, INT)) dispatch;
03209
03210 if (!_suspend_struct[i].ipc_recv_socket)
03211 ss_suspend_init_ipc(i);
03212 }
03213
03214 if (channel == CH_LISTEN) {
03215 _suspend_struct[i].listen_socket = *((INT *) connection);
03216 _suspend_struct[i].listen_dispatch = (INT(*)(INT)) dispatch;
03217 }
03218
03219 if (channel == CH_CLIENT) {
03220 _suspend_struct[i].server_connection = (RPC_SERVER_CONNECTION *) connection;
03221 _suspend_struct[i].client_dispatch = (INT(*)(INT)) dispatch;
03222 }
03223
03224 if (channel == CH_SERVER) {
03225 _suspend_struct[i].server_acception = (RPC_SERVER_ACCEPTION *) connection;
03226 _suspend_struct[i].server_dispatch = (INT(*)(INT, int, BOOL)) dispatch;
03227 }
03228
03229 return SS_SUCCESS;
03230 }
03231
03232
03233 INT ss_suspend_get_port(INT * port)
03234
03235
03236
03237
03238
03239
03240
03241
03242
03243
03244
03245
03246
03247
03248
03249
03250
03251
03252
03253
03254 {
03255 INT index, status;
03256
03257 status = ss_suspend_get_index(&index);
03258
03259 if (status != SS_SUCCESS)
03260 return status;
03261
03262 if (!_suspend_struct[index].ipc_port)
03263 ss_suspend_init_ipc(index);
03264
03265 *port = _suspend_struct[index].ipc_port;
03266
03267 return SS_SUCCESS;
03268 }
03269
03270
03271 INT ss_suspend(INT millisec, INT msg)
03272
03273
03274
03275
03276
03277
03278
03279
03280
03281
03282
03283
03284
03285
03286
03287
03288
03289
03290
03291
03292
03293
03294
03295
03296
03297
03298
03299
03300
03301
03302 {
03303 fd_set readfds;
03304 struct timeval timeout;
03305 INT sock, server_socket;
03306 INT index, status, i, return_status;
03307 int size;
03308 struct sockaddr from_addr;
03309 char str[100], buffer[80], buffer_tmp[80];
03310
03311
03312 status = ss_suspend_get_index(&index);
03313
03314 if (status != SS_SUCCESS)
03315 return status;
03316
03317 return_status = SS_TIMEOUT;
03318
03319 do {
03320 FD_ZERO(&readfds);
03321
03322
03323 if (_suspend_struct[index].listen_socket)
03324 FD_SET(_suspend_struct[index].listen_socket, &readfds);
03325
03326
03327 if (_suspend_struct[index].server_acception)
03328 for (i = 0; i < MAX_RPC_CONNECTION; i++) {
03329
03330 sock = _suspend_struct[index].server_acception[i].recv_sock;
03331
03332
03333 if (!sock || _suspend_struct[index].server_acception[i].tid != ss_gettid())
03334 continue;
03335
03336
03337 if (recv_tcp_check(sock) == 0)
03338 FD_SET(sock, &readfds);
03339
03340
03341 else if (msg == 0)
03342 millisec = 0;
03343
03344
03345 sock = _suspend_struct[index].server_acception[i].event_sock;
03346
03347 if (!sock)
03348 continue;
03349
03350
03351 if (recv_event_check(sock) == 0)
03352 FD_SET(sock, &readfds);
03353
03354
03355 else if (msg == 0)
03356 millisec = 0;
03357 }
03358
03359
03360 if (_suspend_struct[index].server_connection) {
03361 sock = _suspend_struct[index].server_connection->recv_sock;
03362 if (sock)
03363 FD_SET(sock, &readfds);
03364 }
03365
03366
03367 if (_suspend_struct[index].ipc_recv_socket)
03368 FD_SET(_suspend_struct[index].ipc_recv_socket, &readfds);
03369
03370 timeout.tv_sec = millisec / 1000;
03371 timeout.tv_usec = (millisec % 1000) * 1000;
03372
03373 do {
03374 if (millisec < 0)
03375 status = select(FD_SETSIZE, &readfds, NULL, NULL, NULL);
03376 else
03377 status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
03378
03379
03380 if (status == -1 && timeout.tv_sec >= WATCHDOG_INTERVAL / 1000)
03381 timeout.tv_sec -= WATCHDOG_INTERVAL / 1000;
03382
03383 } while (status == -1);
03384
03385
03386 if (_suspend_struct[index].listen_socket &&
03387 FD_ISSET(_suspend_struct[index].listen_socket, &readfds)) {
03388 sock = _suspend_struct[index].listen_socket;
03389
03390 if (_suspend_struct[index].listen_dispatch) {
03391 status = _suspend_struct[index].listen_dispatch(sock);
03392 if (status == RPC_SHUTDOWN)
03393 return status;
03394 }
03395 }
03396
03397
03398 if (_suspend_struct[index].server_acception)
03399 for (i = 0; i < MAX_RPC_CONNECTION; i++) {
03400
03401 sock = _suspend_struct[index].server_acception[i].recv_sock;
03402
03403
03404 if (!sock || _suspend_struct[index].server_acception[i].tid != ss_gettid())
03405 continue;
03406
03407 if (recv_tcp_check(sock) || FD_ISSET(sock, &readfds)) {
03408 if (_suspend_struct[index].server_dispatch) {
03409 status = _suspend_struct[index].server_dispatch(i, sock, msg != 0);
03410 _suspend_struct[index].server_acception[i].
03411 last_activity = ss_millitime();
03412
03413 if (status == SS_ABORT || status == SS_EXIT || status == RPC_SHUTDOWN)
03414 return status;
03415
03416 return_status = SS_SERVER_RECV;
03417 }
03418 }
03419
03420
03421 sock = _suspend_struct[index].server_acception[i].event_sock;
03422 if (!sock)
03423 continue;
03424
03425 if (recv_event_check(sock) || FD_ISSET(sock, &readfds)) {
03426 if (_suspend_struct[index].server_dispatch) {
03427 status = _suspend_struct[index].server_dispatch(i, sock, msg != 0);
03428 _suspend_struct[index].server_acception[i].
03429 last_activity = ss_millitime();
03430
03431 if (status == SS_ABORT || status == SS_EXIT || status == RPC_SHUTDOWN)
03432 return status;
03433
03434 return_status = SS_SERVER_RECV;
03435 }
03436 }
03437 }
03438
03439
03440 if (_suspend_struct[index].server_connection) {
03441 sock = _suspend_struct[index].server_connection->recv_sock;
03442
03443 if (sock && FD_ISSET(sock, &readfds)) {
03444 if (_suspend_struct[index].client_dispatch)
03445 status = _suspend_struct[index].client_dispatch(sock);
03446 else {
03447 status = SS_SUCCESS;
03448 size = recv_tcp(sock, buffer, sizeof(buffer), 0);
03449
03450 if (size <= 0)
03451 status = SS_ABORT;
03452 }
03453
03454 if (status == SS_ABORT) {
03455 sprintf(str, "Server connection broken to %s",
03456 _suspend_struct[index].server_connection->host_name);
03457 cm_msg(MINFO, "ss_suspend", str);
03458
03459
03460 closesocket(_suspend_struct[index].server_connection->send_sock);
03461 closesocket(_suspend_struct[index].server_connection->recv_sock);
03462 closesocket(_suspend_struct[index].server_connection->event_sock);
03463
03464 memset(_suspend_struct[index].server_connection,
03465 0, sizeof(RPC_CLIENT_CONNECTION));
03466
03467
03468 return SS_ABORT;
03469 }
03470
03471 return_status = SS_CLIENT_RECV;
03472 }
03473 }
03474
03475
03476 if (_suspend_struct[index].ipc_recv_socket &&
03477 FD_ISSET(_suspend_struct[index].ipc_recv_socket, &readfds)) {
03478
03479 size = sizeof(struct sockaddr);
03480 size = recvfrom(_suspend_struct[index].ipc_recv_socket,
03481 buffer, sizeof(buffer), 0, &from_addr, (int *) &size);
03482
03483
03484 server_socket = 0;
03485 if (_suspend_struct[index].server_acception &&
03486 rpc_get_server_option(RPC_OSERVER_TYPE) != ST_REMOTE)
03487 for (i = 0; i < MAX_RPC_CONNECTION; i++) {
03488 sock = _suspend_struct[index].server_acception[i].send_sock;
03489 if (sock && _suspend_struct[index].server_acception[i].tid == ss_gettid())
03490 server_socket = sock;
03491 }
03492
03493
03494 do {
03495 FD_ZERO(&readfds);
03496 FD_SET(_suspend_struct[index].ipc_recv_socket, &readfds);
03497
03498 timeout.tv_sec = 0;
03499 timeout.tv_usec = 0;
03500
03501 status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
03502
03503 if (status != -1
03504 && FD_ISSET(_suspend_struct[index].ipc_recv_socket, &readfds)) {
03505 size = sizeof(struct sockaddr);
03506 size =
03507 recvfrom(_suspend_struct[index].ipc_recv_socket,
03508 buffer_tmp, sizeof(buffer_tmp), 0, &from_addr, &size);
03509
03510
03511 if (buffer_tmp[0] != 'B' || strcmp(buffer_tmp, buffer) != 0)
03512 if (_suspend_struct[index].ipc_dispatch)
03513 _suspend_struct[index].ipc_dispatch(buffer_tmp, server_socket);
03514 }
03515
03516 } while (FD_ISSET(_suspend_struct[index].ipc_recv_socket, &readfds));
03517
03518
03519 if (msg == MSG_BM && buffer[0] == 'B')
03520 return SS_SUCCESS;
03521 if (msg == MSG_ODB && buffer[0] == 'O')
03522 return SS_SUCCESS;
03523
03524
03525 if (_suspend_struct[index].ipc_dispatch)
03526 _suspend_struct[index].ipc_dispatch(buffer, server_socket);
03527
03528 return_status = SS_SUCCESS;
03529 }
03530
03531 } while (millisec < 0);
03532
03533 return return_status;
03534 }
03535
03536
03537 INT ss_resume(INT port, char *message)
03538
03539
03540
03541
03542
03543
03544
03545
03546
03547
03548
03549
03550
03551
03552
03553
03554
03555
03556
03557
03558
03559
03560 {
03561 INT status, index;
03562
03563 if (ss_in_async_routine_flag) {
03564
03565 index = 0;
03566 } else {
03567 status = ss_suspend_get_index(&index);
03568
03569 if (status != SS_SUCCESS)
03570 return status;
03571 }
03572
03573 _suspend_struct[index].bind_addr.sin_port = htons((short) port);
03574
03575 status = sendto(_suspend_struct[index].ipc_send_socket, message,
03576 strlen(message) + 1, 0,
03577 (struct sockaddr *) &_suspend_struct[index].bind_addr,
03578 sizeof(struct sockaddr_in));
03579
03580 if (status != (INT) strlen(message) + 1)
03581 return SS_SOCKET_ERROR;
03582
03583 return SS_SUCCESS;
03584 }
03585
03586
03587
03588
03589
03590
03591
03592
03593
03594 INT send_tcp(int sock, char *buffer, DWORD buffer_size, INT flags)
03595
03596
03597
03598
03599
03600
03601
03602
03603
03604
03605
03606
03607
03608
03609
03610
03611
03612
03613
03614 {
03615 DWORD count;
03616 INT status;
03617
03618
03619
03620 for (count = 0; (INT) count < (INT) buffer_size - NET_TCP_SIZE;) {
03621 status = send(sock, buffer + count, NET_TCP_SIZE, flags);
03622 if (status != -1)
03623 count += status;
03624 else {
03625 cm_msg(MERROR, "send_tcp",
03626 "send(socket=%d,size=%d) returned %d, errno: %d (%s)",
03627 sock, NET_TCP_SIZE, status, errno, strerror(errno));
03628 return status;
03629 }
03630 }
03631
03632 while (count < buffer_size) {
03633 status = send(sock, buffer + count, buffer_size - count, flags);
03634 if (status != -1)
03635 count += status;
03636 else {
03637 cm_msg(MERROR, "send_tcp",
03638 "send(socket=%d,size=%d) returned %d, errno: %d (%s)",
03639 sock, (int) (buffer_size - count), status, errno, strerror(errno));
03640 return status;
03641 }
03642 }
03643
03644 return count;
03645 }
03646
03647
03648 INT recv_string(int sock, char *buffer, DWORD buffer_size, INT millisec)
03649
03650
03651
03652
03653
03654
03655
03656
03657
03658
03659
03660
03661
03662
03663
03664
03665
03666
03667
03668
03669
03670
03671
03672
03673 {
03674 INT i, status;
03675 DWORD n;
03676 fd_set readfds;
03677 struct timeval timeout;
03678
03679 n = 0;
03680 memset(buffer, 0, buffer_size);
03681
03682 do {
03683 if (millisec > 0) {
03684 FD_ZERO(&readfds);
03685 FD_SET(sock, &readfds);
03686
03687 timeout.tv_sec = millisec / 1000;
03688 timeout.tv_usec = (millisec % 1000) * 1000;
03689
03690 do {
03691 status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
03692
03693
03694 if (status == -1 && timeout.tv_sec >= WATCHDOG_INTERVAL / 1000)
03695 timeout.tv_sec -= WATCHDOG_INTERVAL / 1000;
03696
03697 } while (status == -1);
03698
03699 if (!FD_ISSET(sock, &readfds))
03700 break;
03701 }
03702
03703 i = recv(sock, buffer + n, 1, 0);
03704
03705 if (i <= 0)
03706 break;
03707
03708 n++;
03709
03710 if (n >= buffer_size)
03711 break;
03712
03713 } while (buffer[n - 1] && buffer[n - 1] != 10);
03714
03715 return n - 1;
03716 }
03717
03718
03719 INT recv_tcp(int sock, char *net_buffer, DWORD buffer_size, INT flags)
03720
03721
03722
03723
03724
03725
03726
03727
03728
03729
03730
03731
03732
03733
03734
03735
03736
03737
03738
03739
03740
03741
03742
03743
03744
03745
03746
03747
03748
03749 {
03750 INT param_size, n_received, n;
03751 NET_COMMAND *nc;
03752
03753 if (buffer_size < sizeof(NET_COMMAND_HEADER)) {
03754 cm_msg(MERROR, "recv_tcp", "parameters too large for network buffer");
03755 return -1;
03756 }
03757
03758
03759 n_received = 0;
03760 do {
03761 #ifdef OS_UNIX
03762 do {
03763 n = recv(sock, net_buffer + n_received, sizeof(NET_COMMAND_HEADER), flags);
03764
03765
03766 } while (n == -1 && errno == EINTR);
03767 #else
03768 n = recv(sock, net_buffer + n_received, sizeof(NET_COMMAND_HEADER), flags);
03769 #endif
03770
03771 if (n <= 0) {
03772 cm_msg(MERROR, "recv_tcp",
03773 "header: recv returned %d, n_received = %d, errno: %d (%s)",
03774 n, n_received, errno, strerror(errno));
03775 return n;
03776 }
03777
03778 n_received += n;
03779
03780 } while (n_received < sizeof(NET_COMMAND_HEADER));
03781
03782
03783
03784 nc = (NET_COMMAND *) net_buffer;
03785 param_size = nc->header.param_size;
03786 n_received = 0;
03787
03788 if (param_size == 0)
03789 return sizeof(NET_COMMAND_HEADER);
03790
03791 do {
03792 #ifdef OS_UNIX
03793 do {
03794 n = recv(sock,
03795 net_buffer + sizeof(NET_COMMAND_HEADER) + n_received,
03796 param_size - n_received, flags);
03797
03798
03799 } while (n == -1 && errno == EINTR);
03800 #else
03801 n = recv(sock, net_buffer + sizeof(NET_COMMAND_HEADER) + n_received,
03802 param_size - n_received, flags);
03803 #endif
03804
03805 if (n <= 0) {
03806 cm_msg(MERROR, "recv_tcp",
03807 "param: recv returned %d, n_received = %d, errno: %d (%s)",
03808 n, n_received, errno, strerror(errno));
03809 return n;
03810 }
03811
03812 n_received += n;
03813 } while (n_received < param_size);
03814
03815 return sizeof(NET_COMMAND_HEADER) + param_size;
03816 }
03817
03818
03819 INT send_udp(int sock, char *buffer, DWORD buffer_size, INT flags)
03820
03821
03822
03823
03824
03825
03826
03827
03828
03829
03830
03831
03832
03833
03834
03835
03836
03837
03838
03839
03840
03841
03842 {
03843 INT status;
03844 UDP_HEADER *udp_header;
03845 static char udp_buffer[NET_UDP_SIZE];
03846 static INT serial_number = 0, n_received = 0;
03847 DWORD i, data_size;
03848
03849 udp_header = (UDP_HEADER *) udp_buffer;
03850 data_size = NET_UDP_SIZE - sizeof(UDP_HEADER);
03851
03852
03853
03854
03855
03856 if (buffer_size >= NET_UDP_SIZE / 2 && buffer_size <= data_size) {
03857
03858
03859
03860 if (n_received) {
03861 udp_header->serial_number = UDP_FIRST | n_received;
03862 udp_header->sequence_number = ++serial_number;
03863
03864 send(sock, udp_buffer, n_received + sizeof(UDP_HEADER), flags);
03865 n_received = 0;
03866 }
03867
03868 udp_header->serial_number = UDP_FIRST | buffer_size;
03869 udp_header->sequence_number = ++serial_number;
03870
03871 memcpy(udp_header + 1, buffer, buffer_size);
03872 status = send(sock, udp_buffer, buffer_size + sizeof(UDP_HEADER), flags);
03873 if (status == (INT) buffer_size + (int) sizeof(UDP_HEADER))
03874 status -= sizeof(UDP_HEADER);
03875
03876 return status;
03877 }
03878
03879
03880
03881
03882
03883 if (buffer_size <= data_size) {
03884
03885 if (buffer_size + n_received < data_size) {
03886 memcpy(udp_buffer + sizeof(UDP_HEADER) + n_received, buffer, buffer_size);
03887
03888 n_received += buffer_size;
03889 return buffer_size;
03890 }
03891
03892
03893 udp_header->serial_number = UDP_FIRST | n_received;
03894 udp_header->sequence_number = ++serial_number;
03895
03896 status = send(sock, udp_buffer, n_received + sizeof(UDP_HEADER), flags);
03897
03898 n_received = 0;
03899
03900 memcpy(udp_header + 1, buffer, buffer_size);
03901 n_received = buffer_size;
03902
03903 return buffer_size;
03904 }
03905
03906
03907
03908
03909
03910
03911
03912 if (n_received) {
03913 udp_header->serial_number = UDP_FIRST | n_received;
03914 udp_header->sequence_number = ++serial_number;
03915
03916 send(sock, udp_buffer, n_received + sizeof(UDP_HEADER), flags);
03917 n_received = 0;
03918 }
03919
03920 for (i = 0; i < ((buffer_size - 1) / data_size); i++) {
03921 if (i == 0) {
03922 udp_header->serial_number = UDP_FIRST | buffer_size;
03923 udp_header->sequence_number = ++serial_number;
03924 } else {
03925 udp_header->serial_number = serial_number;
03926 udp_header->sequence_number = i;
03927 }
03928
03929 memcpy(udp_header + 1, buffer + i * data_size, data_size);
03930 send(sock, udp_buffer, NET_UDP_SIZE, flags);
03931 }
03932
03933
03934 udp_header->serial_number = serial_number;
03935 udp_header->sequence_number = i;
03936 memcpy(udp_header + 1, buffer + i * data_size, buffer_size - i * data_size);
03937 status =
03938 send(sock, udp_buffer, sizeof(UDP_HEADER) + buffer_size - i * data_size, flags);
03939 if ((DWORD) status == sizeof(UDP_HEADER) + buffer_size - i * data_size)
03940 return buffer_size;
03941
03942 return status;
03943 }
03944
03945
03946 INT recv_udp(int sock, char *buffer, DWORD buffer_size, INT flags)
03947
03948
03949
03950
03951
03952
03953
03954
03955
03956
03957
03958
03959
03960
03961
03962
03963
03964
03965
03966
03967
03968 {
03969 INT i, status;
03970 UDP_HEADER *udp_header;
03971 char udp_buffer[NET_UDP_SIZE];
03972 DWORD serial_number, sequence_number, total_buffer_size;
03973 DWORD data_size, n_received;
03974 fd_set readfds;
03975 struct timeval timeout;
03976
03977 udp_header = (UDP_HEADER *) udp_buffer;
03978 data_size = NET_UDP_SIZE - sizeof(UDP_HEADER);
03979
03980
03981 #ifdef OS_UNIX
03982 do {
03983 i = recv(sock, udp_buffer, NET_UDP_SIZE, flags);
03984
03985
03986 } while (i == -1 && errno == EINTR);
03987 #else
03988 i = recv(sock, udp_buffer, NET_UDP_SIZE, flags);
03989 #endif
03990
03991 start:
03992
03993
03994 while (!(udp_header->serial_number & UDP_FIRST)) {
03995
03996 FD_ZERO(&readfds);
03997 FD_SET(sock, &readfds);
03998
03999 timeout.tv_sec = 0;
04000 timeout.tv_usec = 100000;
04001
04002 do {
04003 status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
04004 } while (status == -1);
04005
04006
04007
04008
04009
04010 if (!FD_ISSET(sock, &readfds))
04011 return 0;
04012
04013 #ifdef OS_UNIX
04014 do {
04015 i = recv(sock, udp_buffer, NET_UDP_SIZE, flags);
04016
04017
04018 } while (i == -1 && errno == EINTR);
04019 #else
04020 i = recv(sock, udp_buffer, NET_UDP_SIZE, flags);
04021 #endif
04022 }
04023
04024
04025 total_buffer_size = udp_header->serial_number & ~UDP_FIRST;
04026 serial_number = udp_header->sequence_number;
04027 sequence_number = 0;
04028
04029 if (total_buffer_size <= data_size) {
04030 if (buffer_size < total_buffer_size) {
04031 memcpy(buffer, udp_header + 1, buffer_size);
04032 return buffer_size;
04033 } else {
04034 memcpy(buffer, udp_header + 1, total_buffer_size);
04035 return total_buffer_size;
04036 }
04037 }
04038
04039
04040 n_received = data_size;
04041
04042 if (buffer_size < data_size) {
04043 memcpy(buffer, udp_header + 1, buffer_size);
04044 return buffer_size;
04045 }
04046
04047 memcpy(buffer, udp_header + 1, data_size);
04048
04049
04050 do {
04051
04052 FD_ZERO(&readfds);
04053 FD_SET(sock, &readfds);
04054
04055 timeout.tv_sec = 0;
04056 timeout.tv_usec = 100000;
04057
04058 do {
04059 status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
04060 } while (status == -1);
04061
04062
04063
04064
04065
04066 if (!FD_ISSET(sock, &readfds))
04067 return 0;
04068
04069 #ifdef OS_UNIX
04070 do {
04071 i = recv(sock, udp_buffer, NET_UDP_SIZE, flags);
04072
04073
04074 } while (i == -1 && errno == EINTR);
04075 #else
04076 i = recv(sock, udp_buffer, NET_UDP_SIZE, flags);
04077 #endif
04078
04079 sequence_number++;
04080
04081
04082 if (udp_header->serial_number != serial_number ||
04083 udp_header->sequence_number != sequence_number)
04084
04085 goto start;
04086
04087
04088 memcpy(buffer + n_received, udp_header + 1, i - sizeof(UDP_HEADER));
04089
04090 n_received += (i - sizeof(UDP_HEADER));
04091
04092 } while (n_received < total_buffer_size);
04093
04094 return n_received;
04095 }
04096
04097
04098
04099 #ifdef OS_MSDOS
04100 #ifdef sopen
04101
04102
04103
04104
04105
04106
04107 #undef sopen
04108
04109 int sopen(const char *path, int access, int shflag, int mode)
04110 {
04111 return open(path, (access) | (shflag), mode);
04112 }
04113
04114 #endif
04115 #endif
04116
04117
04118
04119
04120
04121
04122
04123
04124
04125 INT ss_tape_open(char *path, INT oflag, INT * channel)
04126
04127
04128
04129
04130
04131
04132
04133
04134
04135
04136
04137
04138
04139
04140
04141
04142
04143
04144
04145
04146
04147 {
04148 #ifdef OS_UNIX
04149 struct mtop arg;
04150
04151 cm_enable_watchdog(FALSE);
04152
04153 *channel = open(path, oflag, 0644);
04154
04155 cm_enable_watchdog(TRUE);
04156
04157 if (*channel < 0)
04158 cm_msg(MERROR, "ss_tape_open", strerror(errno));
04159
04160 if (*channel < 0) {
04161 if (errno == EIO)
04162 return SS_NO_TAPE;
04163 if (errno == EBUSY)
04164 return SS_DEV_BUSY;
04165 return errno;
04166 }
04167 #ifdef MTSETBLK
04168
04169 arg.mt_op = MTSETBLK;
04170 arg.mt_count = 0;
04171
04172 ioctl(*channel, MTIOCTOP, &arg);
04173 #endif
04174
04175 #endif
04176
04177 #ifdef OS_WINNT
04178 INT status;
04179 TAPE_GET_MEDIA_PARAMETERS m;
04180
04181 *channel = (INT) CreateFile(path, GENERIC_READ | GENERIC_WRITE, 0,
04182 0, OPEN_EXISTING, 0, NULL);
04183
04184 if (*channel == (INT) INVALID_HANDLE_VALUE) {
04185 status = GetLastError();
04186 if (status == ERROR_SHARING_VIOLATION) {
04187 cm_msg(MERROR, "ss_tape_open", "tape is used by other process");
04188 return SS_DEV_BUSY;
04189 }
04190 if (status == ERROR_FILE_NOT_FOUND) {
04191 cm_msg(MERROR, "ss_tape_open", "tape device \"%s\" doesn't exist", path);
04192 return SS_NO_TAPE;
04193 }
04194
04195 cm_msg(MERROR, "ss_tape_open", "unknown error %d", status);
04196 return status;
04197 }
04198
04199 status = GetTapeStatus((HANDLE) (*channel));
04200 if (status == ERROR_NO_MEDIA_IN_DRIVE || status == ERROR_BUS_RESET) {
04201 cm_msg(MERROR, "ss_tape_open", "no media in drive");
04202 return SS_NO_TAPE;
04203 }
04204
04205
04206 memset(&m, 0, sizeof(m));
04207 m.BlockSize = TAPE_BUFFER_SIZE;
04208 SetTapeParameters((HANDLE) (*channel), SET_TAPE_MEDIA_INFORMATION, &m);
04209
04210 #endif
04211
04212 return SS_SUCCESS;
04213 }
04214
04215
04216 INT ss_tape_close(INT channel)
04217
04218
04219
04220
04221
04222
04223
04224
04225
04226
04227
04228
04229
04230
04231
04232
04233
04234 {
04235 INT status;
04236
04237 #ifdef OS_UNIX
04238
04239 status = close(channel);
04240
04241 if (status < 0) {
04242 cm_msg(MERROR, "ss_tape_close", strerror(errno));
04243 return errno;
04244 }
04245 #endif
04246
04247 #ifdef OS_WINNT
04248
04249 if (!CloseHandle((HANDLE) channel)) {
04250 status = GetLastError();
04251 cm_msg(MERROR, "ss_tape_close", "unknown error %d", status);
04252 return status;
04253 }
04254 #endif
04255
04256 return SS_SUCCESS;
04257 }
04258
04259
04260 INT ss_tape_status(char *path)
04261
04262
04263
04264
04265
04266
04267
04268
04269
04270
04271
04272
04273
04274
04275
04276
04277 {
04278 #ifdef OS_UNIX
04279 char str[256];
04280
04281 sprintf(str, "mt -f %s status", path);
04282 system(str);
04283 #endif
04284
04285 #ifdef OS_WINNT
04286 INT status, channel;
04287 DWORD size;
04288 TAPE_GET_MEDIA_PARAMETERS m;
04289 TAPE_GET_DRIVE_PARAMETERS d;
04290 double x;
04291
04292 channel = (INT) CreateFile(path, GENERIC_READ | GENERIC_WRITE, 0,
04293 0, OPEN_EXISTING, 0, NULL);
04294
04295 if (channel == (INT) INVALID_HANDLE_VALUE) {
04296 status = GetLastError();
04297 if (status == ERROR_SHARING_VIOLATION) {
04298 cm_msg(MINFO, "ss_tape_status", "tape is used by other process");
04299 return SS_SUCCESS;
04300 }
04301 if (status == ERROR_FILE_NOT_FOUND) {
04302 cm_msg(MINFO, "ss_tape_status", "tape device \"%s\" doesn't exist", path);
04303 return SS_SUCCESS;
04304 }
04305
04306 cm_msg(MINFO, "ss_tape_status", "unknown error %d", status);
04307 return status;
04308 }
04309
04310
04311 GetTapeParameters((HANDLE) channel, GET_TAPE_DRIVE_INFORMATION, &size, &d);
04312 GetTapeParameters((HANDLE) channel, GET_TAPE_DRIVE_INFORMATION, &size, &d);
04313
04314 status = GetTapeStatus((HANDLE) channel);
04315 if (status == ERROR_NO_MEDIA_IN_DRIVE || status == ERROR_BUS_RESET) {
04316 cm_msg(MINFO, "ss_tape_status", "no media in drive");
04317 CloseHandle((HANDLE) channel);
04318 return SS_SUCCESS;
04319 }
04320
04321 GetTapeParameters((HANDLE) channel, GET_TAPE_DRIVE_INFORMATION, &size, &d);
04322 GetTapeParameters((HANDLE) channel, GET_TAPE_MEDIA_INFORMATION, &size, &m);
04323
04324 printf("Hardware error correction is %s\n", d.ECC ? "on" : "off");
04325 printf("Hardware compression is %s\n", d.Compression ? "on" : "off");
04326 printf("Tape %s write protected\n", m.WriteProtected ? "is" : "is not");
04327
04328 if (d.FeaturesLow & TAPE_DRIVE_TAPE_REMAINING) {
04329 x = ((double) m.Remaining.LowPart + (double) m.Remaining.HighPart * 4.294967295E9)
04330 / 1024.0 / 1000.0;
04331 printf("Tape capacity remaining is %d MB\n", (int) x);
04332 } else
04333 printf("Tape capacity is not reported by tape\n");
04334
04335 CloseHandle((HANDLE) channel);
04336
04337 #endif
04338
04339 return SS_SUCCESS;
04340 }
04341
04342
04343 INT ss_tape_write(INT channel, void *pdata, INT count)
04344
04345
04346
04347
04348
04349
04350
04351
04352
04353
04354
04355
04356
04357
04358
04359
04360
04361
04362
04363
04364 {
04365 #ifdef OS_UNIX
04366 INT status;
04367
04368 do {
04369 status = write(channel, pdata, count);
04370
04371
04372
04373
04374 } while (status == -1 && errno == EINTR);
04375
04376 if (status != count) {
04377 cm_msg(MERROR, "ss_tape_write", strerror(errno));
04378
04379 if (errno == EIO)
04380 return SS_IO_ERROR;
04381 else
04382 return SS_TAPE_ERROR;
04383 }
04384 #endif
04385
04386 #ifdef OS_WINNT
04387 INT status;
04388 DWORD written;
04389
04390 WriteFile((HANDLE) channel, pdata, count, &written, NULL);
04391 if (written != (DWORD) count) {
04392 status = GetLastError();
04393 cm_msg(MERROR, "ss_tape_write", "error %d", status);
04394
04395 return SS_IO_ERROR;
04396 }
04397 #endif
04398
04399 return SS_SUCCESS;
04400 }
04401
04402
04403 INT ss_tape_read(INT channel, void *pdata, INT * count)
04404
04405
04406
04407
04408
04409
04410
04411
04412
04413
04414
04415
04416
04417
04418
04419
04420
04421
04422
04423 {
04424 #ifdef OS_UNIX
04425 INT n, status;
04426
04427 do {
04428 n = read(channel, pdata, *count);
04429 } while (n == -1 && errno == EINTR);
04430
04431 if (n == -1) {
04432 if (errno == ENOSPC || errno == EIO)
04433 status = SS_END_OF_TAPE;
04434 else {
04435 if (n == 0 && errno == 0)
04436 status = SS_END_OF_FILE;
04437 else {
04438 cm_msg(MERROR, "ss_tape_read",
04439 "unexpected tape error: n=%d, errno=%d\n", n, errno);
04440 status = errno;
04441 }
04442 }
04443 } else
04444 status = SS_SUCCESS;
04445 *count = n;
04446
04447 return status;
04448
04449 #elif defined(OS_WINNT)
04450
04451 INT status;
04452 DWORD read;
04453
04454 if (!ReadFile((HANDLE) channel, pdata, *count, &read, NULL)) {
04455 status = GetLastError();
04456 if (status == ERROR_NO_DATA_DETECTED)
04457 status = SS_END_OF_TAPE;
04458 else if (status == ERROR_FILEMARK_DETECTED)
04459 status = SS_END_OF_FILE;
04460 else if (status == ERROR_MORE_DATA)
04461 status = SS_SUCCESS;
04462 else
04463 cm_msg(MERROR, "ss_tape_read",
04464 "unexpected tape error: n=%d, errno=%d\n", read, status);
04465 } else
04466 status = SS_SUCCESS;
04467
04468 *count = read;
04469 return status;
04470
04471 #else
04472
04473 return SS_SUCCESS;
04474
04475 #endif
04476 }
04477
04478
04479 INT ss_tape_write_eof(INT channel)
04480
04481
04482
04483
04484
04485
04486
04487
04488
04489
04490
04491
04492
04493
04494
04495
04496
04497 {
04498 INT status;
04499
04500 #ifdef OS_UNIX
04501 struct mtop arg;
04502
04503 arg.mt_op = MTWEOF;
04504 arg.mt_count = 1;
04505
04506 cm_enable_watchdog(FALSE);
04507
04508 status = ioctl(channel, MTIOCTOP, &arg);
04509
04510 cm_enable_watchdog(TRUE);
04511
04512 if (status < 0) {
04513 cm_msg(MERROR, "ss_tape_write_eof", strerror(errno));
04514 return errno;
04515 }
04516 #endif
04517
04518 #ifdef OS_WINNT
04519
04520 TAPE_GET_DRIVE_PARAMETERS d;
04521 DWORD size;
04522
04523 size = sizeof(TAPE_GET_DRIVE_PARAMETERS);
04524 GetTapeParameters((HANDLE) channel, GET_TAPE_DRIVE_INFORMATION, &size, &d);
04525
04526 if (d.FeaturesHigh & TAPE_DRIVE_WRITE_FILEMARKS)
04527 status = WriteTapemark((HANDLE) channel, TAPE_FILEMARKS, 1, FALSE);
04528 else if (d.FeaturesHigh & TAPE_DRIVE_WRITE_LONG_FMKS)
04529 status = WriteTapemark((HANDLE) channel, TAPE_LONG_FILEMARKS, 1, FALSE);
04530 else if (d.FeaturesHigh & TAPE_DRIVE_WRITE_SHORT_FMKS)
04531 status = WriteTapemark((HANDLE) channel, TAPE_SHORT_FILEMARKS, 1, FALSE);
04532 else
04533 cm_msg(MERROR, "ss_tape_write_eof", "tape doesn't support writing of filemarks");
04534
04535 if (status != NO_ERROR) {
04536 cm_msg(MERROR, "ss_tape_write_eof", "unknown error %d", status);
04537 return status;
04538 }
04539 #endif
04540
04541 return SS_SUCCESS;
04542 }
04543
04544
04545 INT ss_tape_fskip(INT channel, INT count)
04546
04547
04548
04549
04550
04551
04552
04553
04554
04555
04556
04557
04558
04559
04560
04561
04562
04563
04564 {
04565 INT status;
04566
04567 #ifdef OS_UNIX
04568 struct mtop arg;
04569
04570 if (count > 0)
04571 arg.mt_op = MTFSF;
04572 else
04573 arg.mt_op = MTBSF;
04574 arg.mt_count = abs(count);
04575
04576 cm_enable_watchdog(FALSE);
04577
04578 status = ioctl(channel, MTIOCTOP, &arg);
04579
04580 cm_enable_watchdog(TRUE);
04581
04582 if (status < 0) {
04583 cm_msg(MERROR, "ss_tape_fskip", strerror(errno));
04584 return errno;
04585 }
04586 #endif
04587
04588 #ifdef OS_WINNT
04589
04590 status = SetTapePosition((HANDLE) channel, TAPE_SPACE_FILEMARKS, 0,
04591 (DWORD) count, 0, FALSE);
04592
04593 if (status == ERROR_END_OF_MEDIA)
04594 return SS_END_OF_TAPE;
04595
04596 if (status != NO_ERROR) {
04597 cm_msg(MERROR, "ss_tape_fskip", "error %d", status);
04598 return status;
04599 }
04600 #endif
04601
04602 return SS_SUCCESS;
04603 }
04604
04605
04606 INT ss_tape_rskip(INT channel, INT count)
04607
04608
04609
04610
04611
04612
04613
04614
04615
04616
04617
04618
04619
04620
04621
04622
04623
04624
04625 {
04626 INT status;
04627
04628 #ifdef OS_UNIX
04629 struct mtop arg;
04630
04631 if (count > 0)
04632 arg.mt_op = MTFSR;
04633 else
04634 arg.mt_op = MTBSR;
04635 arg.mt_count = abs(count);
04636
04637 cm_enable_watchdog(FALSE);
04638
04639 status = ioctl(channel, MTIOCTOP, &arg);
04640
04641 cm_enable_watchdog(TRUE);
04642
04643 if (status < 0) {
04644 cm_msg(MERROR, "ss_tape_rskip", strerror(errno));
04645 return errno;
04646 }
04647 #endif
04648
04649 #ifdef OS_WINNT
04650
04651 status =
04652 SetTapePosition((HANDLE) channel, TAPE_SPACE_RELATIVE_BLOCKS, 0,
04653 (DWORD) count, 0, FALSE);
04654 if (status != NO_ERROR) {
04655 cm_msg(MERROR, "ss_tape_rskip", "error %d", status);
04656 return status;
04657 }
04658 #endif
04659
04660 return CM_SUCCESS;
04661 }
04662
04663
04664 INT ss_tape_rewind(INT channel)
04665
04666
04667
04668
04669
04670
04671
04672
04673
04674
04675
04676
04677
04678
04679
04680
04681
04682 {
04683 INT status;
04684
04685 #ifdef OS_UNIX
04686 struct mtop arg;
04687
04688 arg.mt_op = MTREW;
04689 arg.mt_count = 0;
04690
04691 cm_enable_watchdog(FALSE);
04692
04693 status = ioctl(channel, MTIOCTOP, &arg);
04694
04695 cm_enable_watchdog(TRUE);
04696
04697 if (status < 0) {
04698 cm_msg(MERROR, "ss_tape_rewind", strerror(errno));
04699 return errno;
04700 }
04701 #endif
04702
04703 #ifdef OS_WINNT
04704
04705 status = SetTapePosition((HANDLE) channel, TAPE_REWIND, 0, 0, 0, FALSE);
04706 if (status != NO_ERROR) {
04707 cm_msg(MERROR, "ss_tape_rewind", "error %d", status);
04708 return status;
04709 }
04710 #endif
04711
04712 return CM_SUCCESS;
04713 }
04714
04715
04716 INT ss_tape_spool(INT channel)
04717
04718
04719
04720
04721
04722
04723
04724
04725
04726
04727
04728
04729
04730
04731
04732
04733
04734 {
04735 INT status;
04736
04737 #ifdef OS_UNIX
04738 struct mtop arg;
04739
04740 #ifdef MTEOM
04741 arg.mt_op = MTEOM;
04742 #else
04743 arg.mt_op = MTSEOD;
04744 #endif
04745 arg.mt_count = 0;
04746
04747 cm_enable_watchdog(FALSE);
04748
04749 status = ioctl(channel, MTIOCTOP, &arg);
04750
04751 cm_enable_watchdog(TRUE);
04752
04753 if (status < 0) {
04754 cm_msg(MERROR, "ss_tape_rewind", strerror(errno));
04755 return errno;
04756 }
04757 #endif
04758
04759 #ifdef OS_WINNT
04760
04761 status = SetTapePosition((HANDLE) channel, TAPE_SPACE_END_OF_DATA, 0, 0, 0, FALSE);
04762 if (status != NO_ERROR) {
04763 cm_msg(MERROR, "ss_tape_spool", "error %d", status);
04764 return status;
04765 }
04766 #endif
04767
04768 return CM_SUCCESS;
04769 }
04770
04771
04772 INT ss_tape_mount(INT channel)
04773
04774
04775
04776
04777
04778
04779
04780
04781
04782
04783
04784
04785
04786
04787
04788
04789
04790 {
04791 INT status;
04792
04793 #ifdef OS_UNIX
04794 struct mtop arg;
04795
04796 #ifdef MTLOAD
04797 arg.mt_op = MTLOAD;
04798 #else
04799 arg.mt_op = MTNOP;
04800 #endif
04801 arg.mt_count = 0;
04802
04803 cm_enable_watchdog(FALSE);
04804
04805 status = ioctl(channel, MTIOCTOP, &arg);
04806
04807 cm_enable_watchdog(TRUE);
04808
04809 if (status < 0) {
04810 cm_msg(MERROR, "ss_tape_mount", strerror(errno));
04811 return errno;
04812 }
04813 #endif
04814
04815 #ifdef OS_WINNT
04816
04817 status = PrepareTape((HANDLE) channel, TAPE_LOAD, FALSE);
04818 if (status != NO_ERROR) {
04819 cm_msg(MERROR, "ss_tape_mount", "error %d", status);
04820 return status;
04821 }
04822 #endif
04823
04824 return CM_SUCCESS;
04825 }
04826
04827
04828 INT ss_tape_unmount(INT channel)
04829
04830
04831
04832
04833
04834
04835
04836
04837
04838
04839
04840
04841
04842
04843
04844
04845
04846 {
04847 INT status;
04848
04849 #ifdef OS_UNIX
04850 struct mtop arg;
04851
04852 #ifdef MTOFFL
04853 arg.mt_op = MTOFFL;
04854 #else
04855 arg.mt_op = MTUNLOAD;
04856 #endif
04857 arg.mt_count = 0;
04858
04859 cm_enable_watchdog(FALSE);
04860
04861 status = ioctl(channel, MTIOCTOP, &arg);
04862
04863 cm_enable_watchdog(TRUE);
04864
04865 if (status < 0) {
04866 cm_msg(MERROR, "ss_tape_unmount", strerror(errno));
04867 return errno;
04868 }
04869 #endif
04870
04871 #ifdef OS_WINNT
04872
04873 status = PrepareTape((HANDLE) channel, TAPE_UNLOAD, FALSE);
04874 if (status != NO_ERROR) {
04875 cm_msg(MERROR, "ss_tape_unmount", "error %d", status);
04876 return status;
04877 }
04878 #endif
04879
04880 return CM_SUCCESS;
04881 }
04882
04883
04884 INT ss_tape_get_blockn(INT channel)
04885
04886
04887
04888
04889
04890
04891
04892
04893 {
04894 #if defined(OS_DARWIN)
04895
04896 return 0;
04897
04898 #elif defined(OS_UNIX)
04899
04900 INT status;
04901 struct mtpos arg;
04902
04903 cm_enable_watchdog(FALSE);
04904 status = ioctl(channel, MTIOCPOS, &arg);
04905 cm_enable_watchdog(TRUE);
04906 if (status < 0) {
04907 if (errno == EIO)
04908 return 0;
04909 else {
04910 cm_msg(MERROR, "ss_tape_get_blockn", strerror(errno));
04911 return -errno;
04912 }
04913 }
04914 return (arg.mt_blkno);
04915
04916 #elif defined(OS_WINNT)
04917
04918 INT status;
04919 TAPE_GET_MEDIA_PARAMETERS media;
04920 unsigned long size;
04921
04922 status =
04923 GetTapeParameters((HANDLE) channel, GET_TAPE_MEDIA_INFORMATION, &size, &media);
04924 return (media.PartitionCount);
04925
04926 #endif
04927 }
04928
04929
04930
04931
04932
04933
04934
04935
04936
04937
04938 double ss_disk_free(char *path)
04939
04940
04941
04942
04943
04944
04945
04946
04947
04948
04949
04950
04951
04952
04953
04954 {
04955 #ifdef OS_UNIX
04956 #if defined(OS_OSF1)
04957 struct statfs st;
04958 statfs(path, &st, sizeof(st));
04959 return (double) st.f_bavail * st.f_bsize;
04960 #elif defined(OS_LINUX)
04961 struct statfs st;
04962 statfs(path, &st);
04963 return (double) st.f_bavail * st.f_bsize;
04964 #elif defined(OS_SOLARIS)
04965 struct statvfs st;
04966 statvfs(path, &st);
04967 return (double) st.f_bavail * st.f_bsize;
04968 #elif defined(OS_IRIX)
04969 struct statfs st;
04970 statfs(path, &st, sizeof(struct statfs), 0);
04971 return (double) st.f_bfree * st.f_bsize;
04972 #else
04973 struct fs_data st;
04974 statfs(path, &st);
04975 return (double) st.fd_otsize * st.fd_bfree;
04976 #endif
04977
04978 #elif defined(OS_WINNT)
04979 DWORD SectorsPerCluster;
04980 DWORD BytesPerSector;
04981 DWORD NumberOfFreeClusters;
04982 DWORD TotalNumberOfClusters;
04983 char str[80];
04984
04985 strcpy(str, path);
04986 if (strchr(str, ':') != NULL) {
04987 *(strchr(str, ':') + 1) = 0;
04988 strcat(str, DIR_SEPARATOR_STR);
04989 GetDiskFreeSpace(str, &SectorsPerCluster, &BytesPerSector,
04990 &NumberOfFreeClusters, &TotalNumberOfClusters);
04991 } else
04992 GetDiskFreeSpace(NULL, &SectorsPerCluster, &BytesPerSector,
04993 &NumberOfFreeClusters, &TotalNumberOfClusters);
04994
04995 return (double) NumberOfFreeClusters *SectorsPerCluster * BytesPerSector;
04996 #else
04997
04998 return 1e9;
04999
05000 #endif
05001 }
05002
05003 #if defined(OS_ULTRIX) || defined(OS_WINNT)
05004 int fnmatch(const char *pat, const char *str, const int flag)
05005 {
05006 while (*str != '\0') {
05007 if (*pat == '*') {
05008 pat++;
05009 if ((str = strchr(str, *pat)) == NULL)
05010 return -1;
05011 }
05012 if (*pat == *str) {
05013 pat++;
05014 str++;
05015 } else
05016 return -1;
05017 }
05018 if (*pat == '\0')
05019 return 0;
05020 else
05021 return -1;
05022 }
05023 #endif
05024
05025 #ifdef OS_WINNT
05026 HANDLE pffile;
05027 LPWIN32_FIND_DATA lpfdata;
05028 #endif
05029 INT ss_file_find(char *path, char *pattern, char **plist)
05030
05031
05032
05033
05034
05035
05036
05037
05038
05039
05040
05041
05042
05043
05044
05045
05046
05047 {
05048 int i;
05049 #ifdef OS_UNIX
05050 DIR *dir_pointer;
05051 struct dirent *dp;
05052
05053 if ((dir_pointer = opendir(path)) == NULL)
05054 return 0;
05055 *plist = (char *) malloc(MAX_STRING_LENGTH);
05056 i = 0;
05057 for (dp = readdir(dir_pointer); dp != NULL; dp = readdir(dir_pointer)) {
05058 if (fnmatch(pattern, dp->d_name, 0) == 0) {
05059 *plist = (char *) realloc(*plist, (i + 1) * MAX_STRING_LENGTH);
05060 strncpy(*plist + (i * MAX_STRING_LENGTH), dp->d_name, strlen(dp->d_name));
05061 *(*plist + (i * MAX_STRING_LENGTH) + strlen(dp->d_name)) = '\0';
05062 i++;
05063 seekdir(dir_pointer, telldir(dir_pointer));
05064 }
05065 }
05066 closedir(dir_pointer);
05067 #endif
05068 #ifdef OS_WINNT
05069 char str[255];
05070 int first;
05071
05072 strcpy(str, path);
05073 strcat(str, "\\");
05074 strcat(str, pattern);
05075 first = 1;
05076 i = 0;
05077 lpfdata = (WIN32_FIND_DATA *) malloc(sizeof(WIN32_FIND_DATA));
05078 *plist = (char *) malloc(MAX_STRING_LENGTH);
05079 pffile = FindFirstFile(str, lpfdata);
05080 if (pffile == INVALID_HANDLE_VALUE)
05081 return 0;
05082 first = 0;
05083 *plist = (char *) realloc(*plist, (i + 1) * MAX_STRING_LENGTH);
05084 strncpy(*plist + (i * MAX_STRING_LENGTH), lpfdata->cFileName,
05085 strlen(lpfdata->cFileName));
05086 *(*plist + (i * MAX_STRING_LENGTH) + strlen(lpfdata->cFileName)) = '\0';
05087 i++;
05088 while (FindNextFile(pffile, lpfdata)) {
05089 *plist = (char *) realloc(*plist, (i + 1) * MAX_STRING_LENGTH);
05090 strncpy(*plist + (i * MAX_STRING_LENGTH), lpfdata->cFileName,
05091 strlen(lpfdata->cFileName));
05092 *(*plist + (i * MAX_STRING_LENGTH) + strlen(lpfdata->cFileName)) = '\0';
05093 i++;
05094 }
05095 free(lpfdata);
05096 #endif
05097 return i;
05098 }
05099
05100 INT ss_file_remove(char *path)
05101
05102
05103
05104
05105
05106
05107
05108
05109
05110
05111
05112
05113
05114
05115
05116 {
05117 return remove(path);
05118 }
05119
05120 double ss_file_size(char *path)
05121
05122
05123
05124
05125
05126
05127
05128
05129
05130
05131
05132
05133
05134
05135
05136 {
05137 struct stat stat_buf;
05138
05139
05140 stat(path, &stat_buf);
05141 return (double) stat_buf.st_size;
05142 }
05143
05144 double ss_disk_size(char *path)
05145
05146
05147
05148
05149
05150
05151
05152
05153
05154
05155
05156
05157
05158
05159
05160 {
05161 #ifdef OS_UNIX
05162 #if defined(OS_OSF1)
05163 struct statfs st;
05164 statfs(path, &st, sizeof(st));
05165 return (double) st.f_blocks * st.f_fsize;
05166 #elif defined(OS_LINUX)
05167 struct statfs st;
05168 statfs(path, &st);
05169 return (double) st.f_blocks * st.f_bsize;
05170 #elif defined(OS_SOLARIS)
05171 struct statvfs st;
05172 statvfs(path, &st);
05173 if (st.f_frsize > 0)
05174 return (double) st.f_blocks * st.f_frsize;
05175 else
05176 return (double) st.f_blocks * st.f_bsize;
05177 #elif defined(OS_ULTRIX)
05178 struct fs_data st;
05179 statfs(path, &st);
05180 return (double) st.fd_btot * 1024;
05181 #elif defined(OS_IRIX)
05182 struct statfs st;
05183 statfs(path, &st, sizeof(struct statfs), 0);
05184 return (double) st.f_blocks * st.f_bsize;
05185 #else
05186 #error ss_disk_size not defined for this OS
05187 #endif
05188 #endif
05189
05190 #ifdef OS_WINNT
05191 DWORD SectorsPerCluster;
05192 DWORD BytesPerSector;
05193 DWORD NumberOfFreeClusters;
05194 DWORD TotalNumberOfClusters;
05195 char str[80];
05196
05197 strcpy(str, path);
05198 if (strchr(str, ':') != NULL) {
05199 *(strchr(str, ':') + 1) = 0;
05200 strcat(str, DIR_SEPARATOR_STR);
05201 GetDiskFreeSpace(str, &SectorsPerCluster, &BytesPerSector,
05202 &NumberOfFreeClusters, &TotalNumberOfClusters);
05203 } else
05204 GetDiskFreeSpace(NULL, &SectorsPerCluster, &BytesPerSector,
05205 &NumberOfFreeClusters, &TotalNumberOfClusters);
05206
05207 return (double) TotalNumberOfClusters *SectorsPerCluster * BytesPerSector;
05208 #endif
05209
05210 return 1e9;
05211 }
05212
05213
05214
05215
05216
05217
05218
05219
05220
05221 void ss_clear_screen()
05222
05223
05224
05225
05226
05227
05228
05229
05230
05231
05232
05233
05234
05235
05236
05237
05238 {
05239 #ifdef OS_WINNT
05240
05241 HANDLE hConsole;
05242 COORD coordScreen = { 0, 0 };
05243 BOOL bSuccess;
05244 DWORD cCharsWritten;
05245 CONSOLE_SCREEN_BUFFER_INFO csbi;
05246 DWORD dwConSize;
05247
05248 hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
05249
05250
05251 bSuccess = GetConsoleScreenBufferInfo(hConsole, &csbi);
05252 dwConSize = csbi.dwSize.X * csbi.dwSize.Y;
05253
05254
05255 bSuccess = FillConsoleOutputCharacter(hConsole, (TCHAR) ' ',
05256 dwConSize, coordScreen, &cCharsWritten);
05257
05258
05259 bSuccess = SetConsoleCursorPosition(hConsole, coordScreen);
05260 return;
05261
05262 #endif
05263 #if defined(OS_UNIX) || defined(OS_VXWORKS) || defined(OS_VMS)
05264 printf("\033[2J");
05265 #endif
05266 #ifdef OS_MSDOS
05267 clrscr();
05268 #endif
05269 }
05270
05271
05272 void ss_set_screen_size(int x, int y)
05273
05274
05275
05276
05277
05278
05279
05280
05281
05282
05283
05284
05285
05286
05287
05288
05289 {
05290 #ifdef OS_WINNT
05291
05292 HANDLE hConsole;
05293 COORD coordSize;
05294
05295 coordSize.X = (short) x;
05296 coordSize.Y = (short) y;
05297 hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
05298 SetConsoleScreenBufferSize(hConsole, coordSize);
05299
05300 #endif
05301 }
05302
05303
05304 void ss_printf(INT x, INT y, const char *format, ...)
05305
05306
05307
05308
05309
05310
05311
05312
05313
05314
05315
05316
05317
05318
05319
05320
05321
05322
05323
05324
05325 {
05326 char str[256];
05327 va_list argptr;
05328
05329 va_start(argptr, format);
05330 vsprintf(str, (char *) format, argptr);
05331 va_end(argptr);
05332
05333 #ifdef OS_WINNT
05334 {
05335 HANDLE hConsole;
05336 COORD dwWriteCoord;
05337 DWORD cCharsWritten;
05338
05339 hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
05340
05341 dwWriteCoord.X = (short) x;
05342 dwWriteCoord.Y = (short) y;
05343
05344 WriteConsoleOutputCharacter(hConsole, str, strlen(str),
05345 dwWriteCoord, &cCharsWritten);
05346 }
05347
05348 #endif
05349
05350 #if defined(OS_UNIX) || defined(OS_VXWORKS) || defined(OS_VMS)
05351 printf("\033[%1d;%1d;H", y + 1, x + 1);
05352 printf(str);
05353 fflush(stdout);
05354 #endif
05355
05356 #ifdef OS_MSDOS
05357 gotoxy(x + 1, y + 1);
05358 cputs(str);
05359 #endif
05360 }
05361
05362
05363 char *ss_getpass(char *prompt)
05364
05365
05366
05367
05368
05369
05370
05371
05372
05373
05374
05375
05376
05377
05378
05379
05380 {
05381 static char password[32];
05382
05383 printf(prompt);
05384 memset(password, 0, sizeof(password));
05385
05386 #ifdef OS_UNIX
05387 return (char *) getpass("");
05388 #elif defined(OS_WINNT)
05389 {
05390 HANDLE hConsole;
05391 DWORD nCharsRead;
05392
05393 hConsole = GetStdHandle(STD_INPUT_HANDLE);
05394 SetConsoleMode(hConsole, ENABLE_LINE_INPUT);
05395 ReadConsole(hConsole, password, sizeof(password), &nCharsRead, NULL);
05396 SetConsoleMode(hConsole, ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT |
05397 ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT);
05398 printf("\n");
05399
05400 if (password[strlen(password) - 1] == '\r')
05401 password[strlen(password) - 1] = 0;
05402
05403 return password;
05404 }
05405 #elif defined(OS_MSDOS)
05406 {
05407 char c, *ptr;
05408
05409 ptr = password;
05410 while ((c = getchar()) != EOF && c != '\n')
05411 *ptr++ = c;
05412 *ptr = 0;
05413
05414 printf("\n");
05415 return password;
05416 }
05417 #else
05418 {
05419 ss_gets(password, 32);
05420 return password;
05421 }
05422 #endif
05423 }
05424
05425
05426 INT ss_getchar(BOOL reset)
05427
05428
05429
05430
05431
05432
05433
05434
05435
05436
05437
05438
05439
05440
05441
05442
05443
05444
05445
05446 {
05447 #ifdef OS_UNIX
05448
05449 static BOOL init = FALSE;
05450 static struct termios save_termios;
05451 struct termios buf;
05452 int i, fd;
05453 char c[3];
05454
05455 if (_daemon_flag)
05456 return 0;
05457
05458 fd = fileno(stdin);
05459
05460 if (reset) {
05461 if (init)
05462 tcsetattr(fd, TCSAFLUSH, &save_termios);
05463 init = FALSE;
05464 return 0;
05465 }
05466
05467 if (!init) {
05468 tcgetattr(fd, &save_termios);
05469 memcpy(&buf, &save_termios, sizeof(buf));
05470
05471 buf.c_lflag &= ~(ECHO | ICANON | IEXTEN);
05472
05473 buf.c_iflag &= ~(ICRNL | INPCK | ISTRIP | IXON);
05474
05475 buf.c_cflag &= ~(CSIZE | PARENB);
05476 buf.c_cflag |= CS8;
05477
05478 buf.c_cc[VMIN] = 0;
05479 buf.c_cc[VTIME] = 0;
05480
05481 tcsetattr(fd, TCSAFLUSH, &buf);
05482 init = TRUE;
05483 }
05484
05485 memset(c, 0, 3);
05486 i = read(fd, c, 1);
05487
05488 if (i == 0)
05489 return 0;
05490
05491
05492 if (c[0] == 27) {
05493 i = read(fd, c, 2);
05494 if (i == 0)
05495 return 27;
05496
05497
05498 if (c[1] < 65)
05499 read(fd, c, 1);
05500
05501
05502 switch (c[1]) {
05503 case 49:
05504 return CH_HOME;
05505 case 50:
05506 return CH_INSERT;
05507 case 51:
05508 return CH_DELETE;
05509 case 52:
05510 return CH_END;
05511 case 53:
05512 return CH_PUP;
05513 case 54:
05514 return CH_PDOWN;
05515 case 65:
05516 return CH_UP;
05517 case 66:
05518 return CH_DOWN;
05519 case 67:
05520 return CH_RIGHT;
05521 case 68:
05522 return CH_LEFT;
05523 }
05524 }
05525
05526
05527 if (c[0] == 127)
05528 return CH_BS;
05529
05530 return c[0];
05531
05532 #elif defined(OS_WINNT)
05533
05534 static BOOL init = FALSE;
05535 static INT repeat_count = 0;
05536 static INT repeat_char;
05537 HANDLE hConsole;
05538 DWORD nCharsRead;
05539 INPUT_RECORD ir;
05540 OSVERSIONINFO vi;
05541
05542
05543 vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
05544 GetVersionEx(&vi);
05545
05546 if (vi.dwPlatformId != VER_PLATFORM_WIN32_NT) {
05547
05548 int c;
05549
05550 if (!kbhit())
05551 return 0;
05552
05553 c = getch();
05554 if (c == 224) {
05555 c = getch();
05556 switch (c) {
05557 case 71:
05558 return CH_HOME;
05559 case 72:
05560 return CH_UP;
05561 case 73:
05562 return CH_PUP;
05563 case 75:
05564 return CH_LEFT;
05565 case 77:
05566 return CH_RIGHT;
05567 case 79:
05568 return CH_END;
05569 case 80:
05570 return CH_DOWN;
05571 case 81:
05572 return CH_PDOWN;
05573 case 82:
05574 return CH_INSERT;
05575 case 83:
05576 return CH_DELETE;
05577 }
05578 }
05579 return c;
05580 }
05581
05582 hConsole = GetStdHandle(STD_INPUT_HANDLE);
05583
05584 if (reset) {
05585 SetConsoleMode(hConsole, ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT |
05586 ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT);
05587 init = FALSE;
05588 return 0;
05589 }
05590
05591 if (!init) {
05592 SetConsoleMode(hConsole, ENABLE_PROCESSED_INPUT);
05593 init = TRUE;
05594 }
05595
05596 if (repeat_count) {
05597 repeat_count--;
05598 return repeat_char;
05599 }
05600
05601 PeekConsoleInput(hConsole, &ir, 1, &nCharsRead);
05602
05603 if (nCharsRead == 0)
05604 return 0;
05605
05606 ReadConsoleInput(hConsole, &ir, 1, &nCharsRead);
05607
05608 if (ir.EventType != KEY_EVENT)
05609 return ss_getchar(0);
05610
05611 if (!ir.Event.KeyEvent.bKeyDown)
05612 return ss_getchar(0);
05613
05614 if (ir.Event.KeyEvent.wRepeatCount > 1) {
05615 repeat_count = ir.Event.KeyEvent.wRepeatCount - 1;
05616 repeat_char = ir.Event.KeyEvent.uChar.AsciiChar;
05617 return repeat_char;
05618 }
05619
05620 if (ir.Event.KeyEvent.uChar.AsciiChar)
05621 return ir.Event.KeyEvent.uChar.AsciiChar;
05622
05623 if (ir.Event.KeyEvent.dwControlKeyState & (ENHANCED_KEY)) {
05624 switch (ir.Event.KeyEvent.wVirtualKeyCode) {
05625 case 33:
05626 return CH_PUP;
05627 case 34:
05628 return CH_PDOWN;
05629 case 35:
05630 return CH_END;
05631 case 36:
05632 return CH_HOME;
05633 case 37:
05634 return CH_LEFT;
05635 case 38:
05636 return CH_UP;
05637 case 39:
05638 return CH_RIGHT;
05639 case 40:
05640 return CH_DOWN;
05641 case 45:
05642 return CH_INSERT;
05643 case 46:
05644 return CH_DELETE;
05645 }
05646
05647 return ir.Event.KeyEvent.wVirtualKeyCode;
05648 }
05649
05650 return ss_getchar(0);
05651
05652 #elif defined(OS_MSDOS)
05653
05654 int c;
05655
05656 if (!kbhit())
05657 return 0;
05658
05659 c = getch();
05660 if (!c) {
05661 c = getch();
05662 switch (c) {
05663 case 71:
05664 return CH_HOME;
05665 case 72:
05666 return CH_UP;
05667 case 73:
05668 return CH_PUP;
05669 case 75:
05670 return CH_LEFT;
05671 case 77:
05672 return CH_RIGHT;
05673 case 79:
05674 return CH_END;
05675 case 80:
05676 return CH_DOWN;
05677 case 81:
05678 return CH_PDOWN;
05679 case 82:
05680 return CH_INSERT;
05681 case 83:
05682 return CH_DELETE;
05683 }
05684 }
05685 return c;
05686
05687 #else
05688 return -1;
05689 #endif
05690 }
05691
05692
05693 char *ss_gets(char *string, int size)
05694
05695
05696
05697
05698
05699
05700
05701
05702
05703
05704
05705
05706
05707
05708
05709
05710
05711
05712 {
05713 char *p;
05714
05715 do {
05716 p = fgets(string, size, stdin);
05717 } while (p == NULL);
05718
05719
05720 if (strlen(p) > 0 && p[strlen(p) - 1] == '\n')
05721 p[strlen(p) - 1] = 0;
05722
05723 return p;
05724 }
05725
05726
05727
05728
05729
05730
05731
05732
05733
05734 INT ss_directio_give_port(INT start, INT end)
05735 {
05736 #ifdef OS_WINNT
05737
05738
05739
05740 OSVERSIONINFO vi;
05741 HANDLE hdio = 0;
05742 DWORD buffer[] = { 6, 0, 0, 0 };
05743 DWORD size;
05744
05745 vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
05746 GetVersionEx(&vi);
05747
05748
05749 if (vi.dwPlatformId == VER_PLATFORM_WIN32_NT) {
05750 hdio =
05751 CreateFile("\\\\.\\directio", GENERIC_READ, FILE_SHARE_READ,
05752 NULL, OPEN_EXISTING, 0, NULL);
05753 if (hdio == INVALID_HANDLE_VALUE) {
05754 printf("hyt1331.c: Cannot access IO ports (No DirectIO driver installed)\n");
05755 return -1;
05756 }
05757
05758
05759 buffer[1] = start;
05760 buffer[2] = end;
05761 if (!DeviceIoControl
05762 (hdio, (DWORD) 0x9c406000, &buffer, sizeof(buffer), NULL, 0, &size, NULL))
05763 return -1;
05764 }
05765
05766 return SS_SUCCESS;
05767 #else
05768 return SS_SUCCESS;
05769 #endif
05770 }
05771
05772
05773 INT ss_directio_lock_port(INT start, INT end)
05774 {
05775 #ifdef OS_WINNT
05776
05777
05778
05779 OSVERSIONINFO vi;
05780 HANDLE hdio;
05781 DWORD buffer[] = { 7, 0, 0, 0 };
05782 DWORD size;
05783
05784 vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
05785 GetVersionEx(&vi);
05786
05787
05788 if (vi.dwPlatformId == VER_PLATFORM_WIN32_NT) {
05789 hdio =
05790 CreateFile("\\\\.\\directio", GENERIC_READ, FILE_SHARE_READ,
05791 NULL, OPEN_EXISTING, 0, NULL);
05792 if (hdio == INVALID_HANDLE_VALUE) {
05793 printf("hyt1331.c: Cannot access IO ports (No DirectIO driver installed)\n");
05794 return -1;
05795 }
05796
05797
05798 buffer[1] = start;
05799 buffer[2] = end;
05800 if (!DeviceIoControl
05801 (hdio, (DWORD) 0x9c406000, &buffer, sizeof(buffer), NULL, 0, &size, NULL))
05802 return -1;
05803 }
05804
05805 return SS_SUCCESS;
05806 #else
05807 return SS_SUCCESS;
05808 #endif
05809 }
05810
05811
05812
05813
05814
05815
05816
05817
05818
05819 INT ss_syslog(const char *message)
05820
05821
05822
05823
05824
05825
05826
05827
05828
05829
05830
05831
05832
05833
05834
05835
05836 {
05837 #ifdef OS_UNIX
05838 static BOOL init = FALSE;
05839
05840 if (!init) {
05841 #ifdef OS_ULTRIX
05842 openlog("MIDAS", LOG_PID);
05843 #else
05844 openlog("MIDAS", LOG_PID, LOG_USER);
05845 #endif
05846 init = TRUE;
05847 }
05848
05849 syslog(LOG_DEBUG, message);
05850 return SS_SUCCESS;
05851 #elif defined(OS_WINNT)
05852
05853
05854
05855
05856
05857
05858
05859
05860
05861
05862
05863
05864
05865
05866
05867
05868
05869
05870
05871
05872
05873
05874
05875
05876
05877
05878
05879
05880
05881
05882 return SS_SUCCESS;
05883
05884 #else
05885
05886 return SS_SUCCESS;
05887
05888 #endif
05889 }
05890
05891
05892
05893
05894
05895
05896
05897
05898 #define bin_to_ascii(c) ((c)>=38?((c)-38+'a'):(c)>=12?((c)-12+'A'):(c)+'.')
05899
05900 char *ss_crypt(char *buf, char *salt)
05901
05902
05903
05904
05905
05906
05907
05908
05909
05910
05911
05912
05913
05914
05915
05916
05917
05918
05919
05920 {
05921 int i, seed;
05922 static char enc_pw[13];
05923
05924 memset(enc_pw, 0, sizeof(enc_pw));
05925 enc_pw[0] = salt[0];
05926 enc_pw[1] = salt[1];
05927
05928 for (i = 0; i < 8 && buf[i]; i++)
05929 enc_pw[i + 2] = buf[i];
05930 for (; i < 8; i++)
05931 enc_pw[i + 2] = 0;
05932
05933 seed = 123;
05934 for (i = 2; i < 13; i++) {
05935 seed = 5 * seed + 27 + enc_pw[i];
05936 enc_pw[i] = (char) bin_to_ascii(seed & 0x3F);
05937 }
05938
05939 return enc_pw;
05940 }
05941
05942
05943 #endif
05944
05945
05946
05947